39#include <QButtonGroup>
43#include "moc_qgslabelinggui.cpp"
45using namespace Qt::StringLiterals;
51 QgsExpressionContext expContext;
54 expContext = mMapCanvas->createExpressionContext();
83void QgsLabelingGui::updateCalloutWidget(
QgsCallout *callout )
87 mCalloutStackedWidget->setCurrentWidget( pageDummy );
91 QgsVectorLayer *vLayer = qobject_cast<QgsVectorLayer *>( mLayer );
94 mCalloutStackedWidget->setCurrentWidget( pageDummy );
98 if ( mCalloutStackedWidget->currentWidget() != pageDummy )
101 if ( QgsCalloutWidget *pew = qobject_cast<QgsCalloutWidget *>( mCalloutStackedWidget->currentWidget() ) )
108 if ( QgsCalloutWidget *w = am->createCalloutWidget( vLayer ) )
111 if ( mGeometryGeneratorGroupBox->isChecked() )
115 w->setGeometryType( geometryType );
116 w->setCallout( callout );
118 w->setContext( context() );
119 mCalloutStackedWidget->addWidget( w );
120 mCalloutStackedWidget->setCurrentWidget( w );
127 mCalloutStackedWidget->setCurrentWidget( pageDummy );
130void QgsLabelingGui::showObstacleSettings()
132 QgsVectorLayer *vLayer = qobject_cast<QgsVectorLayer *>( mLayer );
138 QgsExpressionContext context = createExpressionContext();
140 QgsSymbolWidgetContext symbolContext;
144 QgsLabelObstacleSettingsWidget *widget =
new QgsLabelObstacleSettingsWidget(
nullptr, vLayer );
150 auto applySettings = [
this, widget] {
151 mObstacleSettings = widget->
settings();
154 emit widgetChanged();
167 QgsLabelSettingsWidgetDialog dialog( widget,
this );
169 dialog.buttonBox()->addButton( QDialogButtonBox::Help );
170 connect( dialog.buttonBox(), &QDialogButtonBox::helpRequested,
this, [] {
171 QgsHelp::openHelp( u
"style_library/label_settings.html#obstacles"_s );
183void QgsLabelingGui::showLineAnchorSettings()
185 QgsVectorLayer *vLayer = qobject_cast<QgsVectorLayer *>( mLayer );
191 QgsExpressionContext context = createExpressionContext();
193 QgsSymbolWidgetContext symbolContext;
197 QgsLabelLineAnchorWidget *widget =
new QgsLabelLineAnchorWidget(
nullptr, vLayer );
203 auto applySettings = [
this, widget] {
204 const QgsLabelLineSettings widgetSettings = widget->
settings();
206 mLineSettings.setAnchorType( widgetSettings.
anchorType() );
207 mLineSettings.setAnchorClipping( widgetSettings.
anchorClipping() );
211 emit widgetChanged();
224 QgsLabelSettingsWidgetDialog dialog( widget,
this );
226 dialog.buttonBox()->addButton( QDialogButtonBox::Help );
227 connect( dialog.buttonBox(), &QDialogButtonBox::helpRequested,
this, [] {
228 QgsHelp::openHelp( u
"style_library/label_settings.html#placement-for-line-layers"_s );
240void QgsLabelingGui::showDuplicateSettings()
242 QgsExpressionContext context = createExpressionContext();
244 QgsSymbolWidgetContext symbolContext;
248 QgsLabelRemoveDuplicatesSettingsWidget *widget =
new QgsLabelRemoveDuplicatesSettingsWidget(
nullptr, mLayer );
251 auto vectorLayer = qobject_cast< QgsVectorLayer * >( mLayer );
255 auto applySettings = [
this, widget] {
256 mThinningSettings = widget->
settings();
259 emit widgetChanged();
272 QgsLabelSettingsWidgetDialog dialog( widget,
this );
285 , mSettings( layerSettings )
287 mGeomType = geomType;
297 , mSettings( settings )
299 mGeomType = geomType;
309 , mSettings( settings )
311 mGeomType = geomType;
329 , mSettings( settings )
336void QgsLabelingGui::init()
357 connect( mBufferDrawChkBx, &QAbstractButton::toggled,
this, &QgsLabelingGui::updateUi );
359 connect( mEnableMaskChkBx, &QAbstractButton::toggled,
this, &QgsLabelingGui::updateUi );
360 connect( mShapeDrawChkBx, &QAbstractButton::toggled,
this, &QgsLabelingGui::updateUi );
361 connect( mCalloutsDrawCheckBox, &QAbstractButton::toggled,
this, &QgsLabelingGui::updateUi );
362 connect( mShadowDrawChkBx, &QAbstractButton::toggled,
this, &QgsLabelingGui::updateUi );
363 connect( mDirectSymbChkBx, &QAbstractButton::toggled,
this, &QgsLabelingGui::updateUi );
364 connect( mFormatNumChkBx, &QAbstractButton::toggled,
this, &QgsLabelingGui::updateUi );
365 connect( mScaleBasedVisibilityChkBx, &QAbstractButton::toggled,
this, &QgsLabelingGui::updateUi );
366 connect( mFontLimitPixelChkBox, &QAbstractButton::toggled,
this, &QgsLabelingGui::updateUi );
367 connect( mGeometryGeneratorGroupBox, &QGroupBox::toggled,
this, &QgsLabelingGui::updateGeometryTypeBasedWidgets );
368 connect( mGeometryGeneratorType, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsLabelingGui::updateGeometryTypeBasedWidgets );
369 connect( mGeometryGeneratorExpressionButton, &QToolButton::clicked,
this, &QgsLabelingGui::showGeometryGeneratorExpressionBuilder );
370 connect( mGeometryGeneratorGroupBox, &QGroupBox::toggled,
this, &QgsLabelingGui::validateGeometryGeneratorExpression );
371 connect( mGeometryGenerator, &QgsCodeEditorExpression::textChanged,
this, &QgsLabelingGui::validateGeometryGeneratorExpression );
372 connect( mGeometryGeneratorType, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsLabelingGui::validateGeometryGeneratorExpression );
373 connect( mObstacleSettingsButton, &QAbstractButton::clicked,
this, &QgsLabelingGui::showObstacleSettings );
374 connect( mLineAnchorSettingsButton, &QAbstractButton::clicked,
this, &QgsLabelingGui::showLineAnchorSettings );
375 connect( mDuplicateSettingsButton, &QAbstractButton::clicked,
this, &QgsLabelingGui::showDuplicateSettings );
377 mFieldExpressionWidget->registerExpressionContextGenerator(
this );
379 mMinScaleWidget->setMapCanvas( mMapCanvas );
380 mMinScaleWidget->setShowCurrentScaleButton(
true );
381 mMaxScaleWidget->setMapCanvas( mMapCanvas );
382 mMaxScaleWidget->setShowCurrentScaleButton(
true );
384 mGeometryGeneratorExpressionButton->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
388 for (
const QString &type : calloutTypes )
393 mGeometryGeneratorWarningLabel->setStyleSheet( u
"color: #FFC107;"_s );
394 mGeometryGeneratorWarningLabel->setTextInteractionFlags( Qt::TextBrowserInteraction );
395 connect( mGeometryGeneratorWarningLabel, &QLabel::linkActivated,
this, [
this](
const QString &link ) {
396 if ( link ==
"#determineGeometryGeneratorType"_L1 )
397 determineGeometryGeneratorType();
400 connect( mCalloutStyleComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsLabelingGui::calloutTypeChanged );
402 mLblNoObstacle1->installEventFilter(
this );
405void QgsLabelingGui::setLayer(
QgsMapLayer *mapLayer )
407 mPreviewFeature = QgsFeature();
418 QgsVectorLayer *vLayer = qobject_cast<QgsVectorLayer *>( mapLayer );
420 mTextFormatsListWidget->setLayerType( vLayer ? vLayer->
geometryType() : mGeomType );
421 mBackgroundMarkerSymbolButton->setLayer( vLayer );
422 mBackgroundFillSymbolButton->setLayer( vLayer );
425 updateGeometryTypeBasedWidgets();
427 mFieldExpressionWidget->setLayer( mapLayer );
432 mFieldExpressionWidget->setGeomCalculator( da );
434 mFieldExpressionWidget->setEnabled( mMode == Labels || !mLayer );
435 mLabelingFrame->setEnabled( mMode == Labels || !mLayer );
437 blockInitSignals(
true );
439 mGeometryGenerator->setText( mSettings.geometryGenerator );
440 mGeometryGeneratorGroupBox->setChecked( mSettings.geometryGeneratorEnabled );
441 if ( !mSettings.geometryGeneratorEnabled )
442 mGeometryGeneratorGroupBox->setCollapsed(
true );
443 mGeometryGeneratorType->setCurrentIndex( mGeometryGeneratorType->findData( QVariant::fromValue( mSettings.geometryGeneratorType ) ) );
447 mFieldExpressionWidget->setRow( -1 );
448 mFieldExpressionWidget->setField( mSettings.fieldName );
449 mCheckBoxSubstituteText->setChecked( mSettings.useSubstitutions );
450 mSubstitutions = mSettings.substitutions;
453 mCentroidRadioWhole->setChecked( mSettings.centroidWhole );
454 mCentroidInsideCheckBox->setChecked( mSettings.centroidInside );
455 mFitInsidePolygonCheckBox->setChecked( mSettings.fitInPolygonOnly );
456 mLineDistanceSpnBx->setValue( mSettings.dist );
457 mLineDistanceUnitWidget->setUnit( mSettings.distUnits );
458 mLineDistanceUnitWidget->setMapUnitScale( mSettings.distMapUnitScale );
460 mMaximumDistanceSpnBx->setValue( mSettings.pointSettings().maximumDistance() );
461 mMaximumDistanceUnitWidget->setUnit( mSettings.pointSettings().maximumDistanceUnit() );
462 mMaximumDistanceUnitWidget->setMapUnitScale( mSettings.pointSettings().maximumDistanceMapUnitScale() );
464 mOffsetTypeComboBox->setCurrentIndex( mOffsetTypeComboBox->findData(
static_cast<int>( mSettings.offsetType ) ) );
465 mQuadrantBtnGrp->button(
static_cast<int>( mSettings.pointSettings().quadrant() ) )->setChecked(
true );
466 mPointOffsetXSpinBox->setValue( mSettings.xOffset );
467 mPointOffsetYSpinBox->setValue( mSettings.yOffset );
468 mPointOffsetUnitWidget->setUnit( mSettings.offsetUnits );
469 mPointOffsetUnitWidget->setMapUnitScale( mSettings.labelOffsetMapUnitScale );
470 mPointAngleSpinBox->setValue( mSettings.angleOffset );
478 const int placementIndex = mPlacementModeComboBox->findData(
static_cast<int>( mSettings.placement ) );
479 if ( placementIndex >= 0 )
481 mPlacementModeComboBox->setCurrentIndex( placementIndex );
486 mPlacementModeComboBox->setCurrentIndex( 0 );
490 mRepeatDistanceSpinBox->setValue( mSettings.repeatDistance );
491 mRepeatDistanceUnitWidget->setUnit( mSettings.repeatDistanceUnit );
492 mRepeatDistanceUnitWidget->setMapUnitScale( mSettings.repeatDistanceMapUnitScale );
494 mOverrunDistanceSpinBox->setValue( mSettings.lineSettings().overrunDistance() );
495 mOverrunDistanceUnitWidget->setUnit( mSettings.lineSettings().overrunDistanceUnit() );
496 mOverrunDistanceUnitWidget->setMapUnitScale( mSettings.lineSettings().overrunDistanceMapUnitScale() );
498 mThinningSettings = mSettings.thinningSettings();
500 mLabelMarginSpinBox->setValue( mThinningSettings.labelMarginDistance() );
501 mLabelMarginUnitWidget->setUnit( mThinningSettings.labelMarginDistanceUnit() );
502 mLabelMarginUnitWidget->setMapUnitScale( mThinningSettings.labelMarginDistanceMapUnitScale() );
504 mPrioritySlider->setValue( mSettings.priority );
505 mChkNoObstacle->setChecked( mSettings.obstacleSettings().isObstacle() );
507 mObstacleSettings = mSettings.obstacleSettings();
509 mChkNoDuplicates->setChecked( mThinningSettings.allowDuplicateRemoval() );
511 mLineSettings = mSettings.lineSettings();
513 mComboMultipartBehavior->setCurrentIndex( mComboMultipartBehavior->findData( QVariant::fromValue( mSettings.placementSettings().multiPartBehavior() ) ) );
515 mComboOverlapHandling->setCurrentIndex( mComboOverlapHandling->findData(
static_cast<int>( mSettings.placementSettings().overlapHandling() ) ) );
516 mCheckAllowDegradedPlacement->setChecked( mSettings.placementSettings().allowDegradedPlacement() );
517 mPrioritizationComboBox->setCurrentIndex( mPrioritizationComboBox->findData( QVariant::fromValue( mSettings.placementSettings().prioritization() ) ) );
519 mComboCurvedLabelMode->setCurrentIndex( mComboCurvedLabelMode->findData( QVariant::fromValue( mSettings.lineSettings().curvedLabelMode() ) ) );
523 chkMergeLines->setChecked( mSettings.lineSettings().mergeLines() );
524 mMinSizeSpinBox->setValue( mThinningSettings.minimumFeatureSize() );
525 mLimitLabelChkBox->setChecked( mThinningSettings.limitNumberOfLabelsEnabled() );
526 mLimitLabelSpinBox->setValue( mThinningSettings.maximumNumberLabels() );
529 mDirectSymbChkBx->setChecked( mSettings.lineSettings().addDirectionSymbol() );
530 mDirectSymbLeftLineEdit->setText( mSettings.lineSettings().leftDirectionSymbol() );
531 mDirectSymbRightLineEdit->setText( mSettings.lineSettings().rightDirectionSymbol() );
532 mDirectSymbRevChkBx->setChecked( mSettings.lineSettings().reverseDirectionSymbol() );
534 mDirectSymbBtnGrp->button(
static_cast<int>( mSettings.lineSettings().directionSymbolPlacement() ) )->setChecked(
true );
535 mUpsidedownBtnGrp->button(
static_cast<int>( mSettings.upsidedownLabels ) )->setChecked(
true );
538 mMaxCharAngleInDSpinBox->setValue( mSettings.maxCurvedCharAngleIn );
540 mMaxCharAngleOutDSpinBox->setValue( std::fabs( mSettings.maxCurvedCharAngleOut ) );
542 wrapCharacterEdit->setText( mSettings.wrapChar );
543 mAutoWrapLengthSpinBox->setValue( mSettings.autoWrapLength );
544 mAutoWrapTypeComboBox->setCurrentIndex( mSettings.useMaxLineLengthForAutoWrap ? 0 : 1 );
546 if ( mFontMultiLineAlignComboBox->findData(
static_cast<int>( mSettings.multilineAlign ) ) != -1 )
548 mFontMultiLineAlignComboBox->setCurrentIndex( mFontMultiLineAlignComboBox->findData(
static_cast<int>( mSettings.multilineAlign ) ) );
554 mFontMultiLineAlignComboBox->setCurrentIndex( 0 );
557 chkPreserveRotation->setChecked( mSettings.preserveRotation );
559 mCoordRotationUnitComboBox->setCurrentIndex( 0 );
560 if ( mCoordRotationUnitComboBox->findData(
static_cast<unsigned int>( mSettings.rotationUnit() ) ) >= 0 )
561 mCoordRotationUnitComboBox->setCurrentIndex( mCoordRotationUnitComboBox->findData(
static_cast<unsigned int>( mSettings.rotationUnit() ) ) );
563 mScaleBasedVisibilityChkBx->setChecked( mSettings.scaleVisibility );
564 mMinScaleWidget->setScale( mSettings.minimumScale );
565 mMaxScaleWidget->setScale( mSettings.maximumScale );
567 mFormatNumChkBx->setChecked( mSettings.formatNumbers );
568 mFormatNumDecimalsSpnBx->setValue( mSettings.decimals );
569 mFormatNumPlusSignChkBx->setChecked( mSettings.plusSign );
573 mFontLimitPixelChkBox->setChecked( mSettings.fontLimitPixelSize );
574 mMinPixelLimit = mSettings.fontMinPixelSize;
575 mFontMinPixelSpinBox->setValue( mSettings.fontMinPixelSize == 0 ? 3 : mSettings.fontMinPixelSize );
576 mFontMaxPixelSpinBox->setValue( mSettings.fontMaxPixelSize );
578 mZIndexSpinBox->setValue( mSettings.zIndex );
580 mDataDefinedProperties = mSettings.dataDefinedProperties();
583 if (
auto *lCallout = mSettings.callout() )
585 whileBlocking( mCalloutsDrawCheckBox )->setChecked( lCallout->enabled() );
586 whileBlocking( mCalloutStyleComboBox )->setCurrentIndex( mCalloutStyleComboBox->findData( lCallout->type() ) );
587 updateCalloutWidget( lCallout );
592 whileBlocking( mCalloutStyleComboBox )->setCurrentIndex( mCalloutStyleComboBox->findData( defaultCallout->type() ) );
594 updateCalloutWidget( defaultCallout.get() );
597 updatePlacementWidgets();
598 updateLinePlacementOptions();
601 blockInitSignals(
false );
605 populateDataDefinedButtons();
612 mSettings = settings;
616void QgsLabelingGui::blockInitSignals(
bool block )
618 chkLineAbove->blockSignals( block );
619 chkLineBelow->blockSignals( block );
620 mPlacementModeComboBox->blockSignals( block );
623void QgsLabelingGui::setLabelMode( LabelMode mode )
626 mFieldExpressionWidget->setEnabled( mMode == Labels );
627 mLabelingFrame->setEnabled( mMode == Labels );
632 QgsPalLayerSettings lyr;
637 lyr.
drawLabels = ( mMode == Labels ) || !mLayer;
640 lyr.
fieldName = mFieldExpressionWidget->currentField( &isExpression );
646 if ( mCheckAllowLabelsOutsidePolygons->isChecked() )
653 lyr.
dist = mLineDistanceSpnBx->value();
654 lyr.
distUnits = mLineDistanceUnitWidget->unit();
662 if ( mQuadrantBtnGrp )
666 lyr.
xOffset = mPointOffsetXSpinBox->value();
667 lyr.
yOffset = mPointOffsetYSpinBox->value();
673 if ( chkLineAbove->isChecked() )
675 if ( chkLineBelow->isChecked() )
677 if ( chkLineOn->isChecked() )
679 if ( !chkLineOrientationDependent->isChecked() )
693 mThinningSettings.setLabelMarginDistance( mLabelMarginSpinBox->value() );
694 mThinningSettings.setLabelMarginDistanceUnit( mLabelMarginUnitWidget->unit() );
695 mThinningSettings.setLabelMarginDistanceMapUnitScale( mLabelMarginUnitWidget->getMapUnitScale() );
697 lyr.
priority = mPrioritySlider->value();
699 mObstacleSettings.setIsObstacle( mChkNoObstacle->isChecked() || mMode == ObstaclesOnly );
707 mThinningSettings.setAllowDuplicateRemoval( mChkNoDuplicates->isChecked() );
728 lyr.
decimals = mFormatNumDecimalsSpnBx->value();
729 lyr.
plusSign = mFormatNumPlusSignChkBx->isChecked();
736 if ( mDirectSymbBtnGrp )
740 if ( mUpsidedownBtnGrp )
749 mThinningSettings.setMinimumFeatureSize( mMinSizeSpinBox->value() );
750 mThinningSettings.setLimitNumberLabelsEnabled( mLimitLabelChkBox->isChecked() );
751 mThinningSettings.setMaximumNumberLabels( mLimitLabelSpinBox->value() );
758 lyr.
wrapChar = wrapCharacterEdit->text();
768 QgsVectorLayer *vLayer = qobject_cast<QgsVectorLayer *>( mLayer );
771 lyr.
zIndex = mZIndexSpinBox->value();
776 const QString calloutType = mCalloutStyleComboBox->currentData().toString();
777 std::unique_ptr<QgsCallout> callout;
778 if ( QgsCalloutWidget *pew = qobject_cast<QgsCalloutWidget *>( mCalloutStackedWidget->currentWidget() ) )
780 callout.reset( pew->callout()->clone() );
785 callout->setEnabled( mCalloutsDrawCheckBox->isChecked() );
793 f->setEnabled( chkBx->isChecked() || ddBtn->
isActive() );
796bool QgsLabelingGui::eventFilter( QObject *
object, QEvent *event )
798 if (
object == mLblNoObstacle1 )
800 if ( event->type() == QEvent::MouseButtonPress && qgis::down_cast<QMouseEvent *>( event )->button() == Qt::LeftButton )
803 mChkNoObstacle->setChecked( !mChkNoObstacle->isChecked() );
808 return QgsTextFormatWidget::eventFilter(
object, event );
811void QgsLabelingGui::updateUi()
815 syncDefinedCheckboxFrame( mBufferDrawDDBtn, mBufferDrawChkBx, mBufferFrame );
816 syncDefinedCheckboxFrame( mEnableMaskDDBtn, mEnableMaskChkBx, mMaskFrame );
817 syncDefinedCheckboxFrame( mShapeDrawDDBtn, mShapeDrawChkBx, mShapeFrame );
818 syncDefinedCheckboxFrame( mShadowDrawDDBtn, mShadowDrawChkBx, mShadowFrame );
819 syncDefinedCheckboxFrame( mCalloutDrawDDBtn, mCalloutsDrawCheckBox, mCalloutFrame );
821 syncDefinedCheckboxFrame( mDirectSymbDDBtn, mDirectSymbChkBx, mDirectSymbFrame );
822 syncDefinedCheckboxFrame( mFormatNumDDBtn, mFormatNumChkBx, mFormatNumFrame );
823 syncDefinedCheckboxFrame( mScaleBasedVisibilityDDBtn, mScaleBasedVisibilityChkBx, mScaleBasedVisibilityFrame );
824 syncDefinedCheckboxFrame( mFontLimitPixelDDBtn, mFontLimitPixelChkBox, mFontLimitPixelFrame );
826 chkMergeLines->setEnabled( !mDirectSymbChkBx->isChecked() );
827 if ( mDirectSymbChkBx->isChecked() )
829 chkMergeLines->setToolTip( tr(
"This option is not compatible with line direction symbols." ) );
833 chkMergeLines->setToolTip( QString() );
837void QgsLabelingGui::setFormatFromStyle(
const QString &name,
QgsStyle::StyleEntity type,
const QString &stylePath )
868 settings.
fieldName = mFieldExpressionWidget->currentField( &isExpression );
871 setSettings( settings );
879 if ( QgsCalloutWidget *cw = qobject_cast<QgsCalloutWidget *>( mCalloutStackedWidget->currentWidget() ) )
881 cw->setContext( context );
886void QgsLabelingGui::saveFormat()
889 saveDlg.setDefaultTags( mTextFormatsListWidget->currentTagFilter() );
890 if ( !saveDlg.exec() )
893 if ( saveDlg.name().isEmpty() )
896 QgsStyle *style = saveDlg.destinationStyle();
900 switch ( saveDlg.selectedType() )
907 const int res = QMessageBox::warning(
this, tr(
"Save Text Format" ), tr(
"Format with name '%1' already exists. Overwrite?" ).arg( saveDlg.name() ), QMessageBox::Yes | QMessageBox::No );
908 if ( res != QMessageBox::Yes )
914 const QStringList symbolTags = saveDlg.tags().split(
',' );
916 const QgsTextFormat newFormat = format();
918 style->
saveTextFormat( saveDlg.name(), newFormat, saveDlg.isFavorite(), symbolTags );
927 const int res = QMessageBox::warning(
this, tr(
"Save Label Settings" ), tr(
"Label settings with the name '%1' already exist. Overwrite?" ).arg( saveDlg.name() ), QMessageBox::Yes | QMessageBox::No );
928 if ( res != QMessageBox::Yes )
934 const QStringList symbolTags = saveDlg.tags().split(
',' );
936 const QgsPalLayerSettings newSettings = layerSettings();
938 style->
saveLabelSettings( saveDlg.name(), newSettings, saveDlg.isFavorite(), symbolTags );
952void QgsLabelingGui::updateGeometryTypeBasedWidgets()
956 QgsVectorLayer *vLayer = qobject_cast<QgsVectorLayer *>( mLayer );
958 if ( mGeometryGeneratorGroupBox->isChecked() )
971 mPlacementModeComboBox->clear();
973 switch ( geometryType )
1000 qFatal(
"unknown geometry type unexpected" );
1003 if ( mPlacementModeComboBox->findData(
static_cast<int>( prevPlacement ) ) != -1 )
1005 mPlacementModeComboBox->setCurrentIndex( mPlacementModeComboBox->findData(
static_cast<int>( prevPlacement ) ) );
1018 mFontMultiLineAlignComboBox->removeItem( idx );
1021 updatePlacementWidgets();
1022 updateLinePlacementOptions();
1025void QgsLabelingGui::showGeometryGeneratorExpressionBuilder()
1027 QgsVectorLayer *vLayer = qobject_cast<QgsVectorLayer *>( mLayer );
1028 QgsExpressionBuilderDialog expressionBuilder( vLayer );
1030 expressionBuilder.setExpressionText( mGeometryGenerator->text() );
1031 expressionBuilder.setExpressionContext( createExpressionContext() );
1033 if ( expressionBuilder.exec() )
1035 mGeometryGenerator->setText( expressionBuilder.expressionText() );
1039void QgsLabelingGui::validateGeometryGeneratorExpression()
1043 QgsVectorLayer *vLayer = qobject_cast<QgsVectorLayer *>( mLayer );
1045 if ( mGeometryGeneratorGroupBox->isChecked() )
1047 if ( !mPreviewFeature.isValid() && vLayer )
1050 QgsExpression expression( mGeometryGenerator->text() );
1051 QgsExpressionContext context = createExpressionContext();
1054 expression.prepare( &context );
1056 if ( expression.hasParserError() )
1058 mGeometryGeneratorWarningLabel->setText( expression.parserErrorString() );
1063 const QVariant result = expression.evaluate( &context );
1064 const QgsGeometry geometry = result.value<QgsGeometry>();
1068 mGeometryGeneratorWarningLabel->setText( tr(
"Result of the expression is not a geometry" ) );
1071 else if ( geometry.
type() != configuredGeometryType )
1073 mGeometryGeneratorWarningLabel->setText( u
"<p>%1</p><p><a href=\"#determineGeometryGeneratorType\">%2</a></p>"_s.arg( tr(
"Result of the expression does not match configured geometry type." ), tr(
"Change to %1" ).arg(
QgsWkbTypes::geometryDisplayString( geometry.
type() ) ) ) );
1081 QTimer *timer =
new QTimer();
1082 connect( timer, &QTimer::timeout,
this, [
this, valid]() {
1083 mGeometryGeneratorWarningLabel->setVisible( !valid );
1085 connect( timer, &QTimer::timeout, timer, &QTimer::deleteLater );
1089void QgsLabelingGui::determineGeometryGeneratorType()
1091 QgsVectorLayer *vLayer = qobject_cast<QgsVectorLayer *>( mLayer );
1092 if ( !mPreviewFeature.isValid() && vLayer )
1095 QgsExpression expression( mGeometryGenerator->text() );
1096 QgsExpressionContext context = createExpressionContext();
1099 expression.prepare( &context );
1100 const QgsGeometry geometry = expression.evaluate( &context ).value<QgsGeometry>();
1102 mGeometryGeneratorType->setCurrentIndex( mGeometryGeneratorType->findData( QVariant::fromValue( geometry.
type() ) ) );
1105void QgsLabelingGui::calloutTypeChanged()
1107 const QString newCalloutType = mCalloutStyleComboBox->currentData().toString();
1108 QgsCalloutWidget *pew = qobject_cast<QgsCalloutWidget *>( mCalloutStackedWidget->currentWidget() );
1117 QgsCalloutAbstractMetadata *am = registry->
calloutMetadata( newCalloutType );
1123 const std::unique_ptr<QgsCallout> newCallout( am->
createCallout( pew && pew->
callout() ? pew->
callout()->
properties( QgsReadWriteContext() ) : QVariantMap(), QgsReadWriteContext() ) );
1127 updateCalloutWidget( newCallout.get() );
1139 QVBoxLayout *vLayout =
new QVBoxLayout();
1140 mWidget =
new QgsLabelingGui( layer, mapCanvas, settings,
nullptr, geomType );
1141 vLayout->addWidget( mWidget );
1142 mButtonBox =
new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok, Qt::Horizontal );
1143 connect( mButtonBox, &QDialogButtonBox::accepted,
this, &QDialog::accept );
1144 connect( mButtonBox, &QDialogButtonBox::rejected,
this, &QDialog::reject );
1145 connect( mButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsLabelSettingsDialog::showHelp );
1146 vLayout->addWidget( mButtonBox );
1147 setLayout( vLayout );
1148 setWindowTitle( tr(
"Label Settings" ) );
1151QDialogButtonBox *QgsLabelSettingsDialog::buttonBox()
const
1156void QgsLabelSettingsDialog::showHelp()
CurvedLabelMode
Modes which determine how curved labels are generated and placed.
MultiPartLabelingBehavior
Behavior modifier for labeling features with multi-part geometries.
@ BelowLine
Labels can be placed below a line feature. Unless MapOrientation is also specified this mode respects...
@ MapOrientation
Signifies that the AboveLine and BelowLine flags should respect the map's orientation rather than the...
@ OnLine
Labels can be placed directly over a line feature.
@ AboveLine
Labels can be placed above a line feature. Unless MapOrientation is also specified this mode respects...
AngleUnit
Units of angles.
@ SecondsOfArc
Seconds of arc.
@ Radians
Square kilometers.
@ MinutesOfArc
Minutes of arc.
@ MilliradiansSI
Angular milliradians (SI definition, 1/1000 of radian).
@ MilNATO
Angular mil (NATO definition, 6400 mil = 2PI radians).
LabelOffsetType
Behavior modifier for label offset and distance, only applies in some label placement modes.
LabelPrioritization
Label prioritization.
LabelPlacement
Placement modes which determine how label candidates are generated for a feature.
@ OverPoint
Arranges candidates over a point (or centroid of a polygon), or at a preset offset from the point....
@ Curved
Arranges candidates following the curvature of a line feature. Applies to line layers only.
@ AroundPoint
Arranges candidates in a circle around a point (or centroid of a polygon). Applies to point or polygo...
@ Line
Arranges candidates parallel to a generalised line representing the feature or parallel to a polygon'...
@ Free
Arranges candidates scattered throughout a polygon feature. Candidates are rotated to respect the pol...
@ OrderedPositionsAroundPoint
Candidates are placed in predefined positions around a point. Preference is given to positions with g...
@ Horizontal
Arranges horizontal candidates scattered throughout a polygon feature. Applies to polygon layers only...
@ PerimeterCurved
Arranges candidates following the curvature of a polygon's boundary. Applies to polygon layers only.
@ OutsidePolygons
Candidates are placed outside of polygon boundaries. Applies to polygon layers only.
@ AllowPlacementInsideOfPolygon
Labels can be placed inside a polygon feature.
@ AllowPlacementOutsideOfPolygon
Labels can be placed outside of a polygon feature.
QFlags< LabelLinePlacementFlag > LabelLinePlacementFlags
Line placement flags, which control how candidates are generated for a linear feature.
QFlags< LabelPolygonPlacementFlag > LabelPolygonPlacementFlags
Polygon placement flags, which control how candidates are generated for a polygon feature.
LabelQuadrantPosition
Label quadrant positions.
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
LabelMultiLineAlignment
Text alignment for multi-line labels.
@ FollowPlacement
Alignment follows placement of label, e.g., labels to the left of a feature will be drawn with right ...
@ Mesh
Mesh layer. Added in QGIS 3.2.
@ TreatWhitespaceAsCollision
Treat overlapping whitespace text in labels and whitespace overlapping obstacles as collisions.
@ IgnoreWhitespaceCollisions
Ignore overlapping whitespace text in labels and whitespace overlapping obstacles.
LabelOverlapHandling
Label overlap handling.
UpsideDownLabelHandling
Handling techniques for upside down labels.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QgsCalloutRegistry * calloutRegistry()
Returns the application's callout registry, used for managing callout types.
QgsCalloutAbstractMetadata * calloutMetadata(const QString &type) const
Returns the metadata for specified the specified callout type.
static QgsCallout * defaultCallout()
Create a new instance of a callout with default settings.
QStringList calloutTypes() const
Returns a list of all available callout types.
Abstract base class for callout renderers.
virtual QString type() const =0
Returns a unique string representing the callout type.
virtual QVariantMap properties(const QgsReadWriteContext &context) const
Returns the properties describing the callout encoded in a string format.
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
static QgsExpressionContextScope * updateSymbolScope(const QgsSymbol *symbol, QgsExpressionContextScope *symbolScope=nullptr)
Updates a symbol scope related to a QgsSymbol to an expression context.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * atlasScope(const QgsLayoutAtlas *atlas)
Creates a new scope which contains variables and functions relating to a QgsLayoutAtlas.
static QgsExpressionContextScope * meshExpressionScope(QgsMesh::ElementType elementType)
Creates a new scope which contains functions relating to mesh layer element elementType.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
static const QString EXPR_SYMBOL_COLOR
Inbuilt variable name for symbol color variable.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user.
static const QString EXPR_ORIGINAL_VALUE
Inbuilt variable name for value original value variable.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
static void initCalloutWidgets()
Initializes callout widgets.
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
void setPlacementFlags(Qgis::LabelLinePlacementFlags flags)
Returns the line placement flags, which dictate how line labels can be placed above or below the line...
void setLineAnchorPercent(double percent)
Sets the percent along the line at which labels should be placed.
void setDirectionSymbolPlacement(DirectionSymbolPlacement placement)
Sets the placement for direction symbols.
AnchorType anchorType() const
Returns the line anchor type, which dictates how the lineAnchorPercent() setting is handled.
void setAnchorTextPoint(AnchorTextPoint point)
Sets the line anchor text point, which dictates which part of the label text should be placed at the ...
void setLeftDirectionSymbol(const QString &symbol)
Sets the string to use for left direction arrows.
AnchorTextPoint anchorTextPoint() const
Returns the line anchor text point, which dictates which part of the label text should be placed at t...
void setMergeLines(bool merge)
Sets whether connected line features with identical label text should be merged prior to generating l...
DirectionSymbolPlacement
Placement options for direction symbols.
void setRightDirectionSymbol(const QString &symbol)
Sets the string to use for right direction arrows.
void setAnchorClipping(AnchorClipping clipping)
Sets the line anchor clipping mode, which dictates how line strings are clipped before calculating th...
void setOverrunDistanceMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for label overrun distance.
double lineAnchorPercent() const
Returns the percent along the line at which labels should be placed.
void setAnchorType(AnchorType type)
Sets the line anchor type, which dictates how the lineAnchorPercent() setting is handled.
void setOverrunDistanceUnit(const Qgis::RenderUnit &unit)
Sets the unit for label overrun distance.
void setOverrunDistance(double distance)
Sets the distance which labels are allowed to overrun past the start or end of line features.
AnchorClipping anchorClipping() const
Returns the line anchor clipping mode, which dictates how line strings are clipped before calculating...
void setReverseDirectionSymbol(bool reversed)
Sets whether the direction symbols should be reversed.
void setAddDirectionSymbol(bool enabled)
Sets whether '<' or '>' (or custom strings set via leftDirectionSymbol and rightDirectionSymbol) will...
void setCurvedLabelMode(Qgis::CurvedLabelMode mode)
Sets the mode which determine how curved labels are generated and placed.
void setOverlapHandling(Qgis::LabelOverlapHandling handling)
Sets the technique used to handle overlapping labels.
void setMultiPartBehavior(Qgis::MultiPartLabelingBehavior behavior)
Sets the multipart labeling behavior.
void setPrioritization(Qgis::LabelPrioritization prioritization)
Sets the technique used to prioritize labels.
void setAllowDegradedPlacement(bool allow)
Sets whether labels can be placed in inferior fallback positions if they cannot otherwise be placed.
void setWhitespaceCollisionHandling(Qgis::LabelWhitespaceCollisionHandling handling)
Sets the whitespace collision handling.
void setMaximumDistance(double distance)
Sets the maximum distance which labels are allowed to be from their corresponding points.
void setMaximumDistanceMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for label maximum distance.
void setQuadrant(Qgis::LabelQuadrantPosition quadrant)
Sets the quadrant in which to offset labels from the point.
void setMaximumDistanceUnit(Qgis::RenderUnit unit)
Sets the unit for label maximum distance.
Map canvas is a class for displaying all GIS data types on a canvas.
Base class for all map layer types.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
Contains settings for how a map layer will be labeled.
bool fitInPolygonOnly
true if only labels which completely fit within a polygon are allowed.
double yOffset
Vertical offset of label.
QgsMapUnitScale labelOffsetMapUnitScale
Map unit scale for label offset.
int fontMaxPixelSize
Maximum pixel size for showing rendered map unit labels (1 - 10000).
void setObstacleSettings(const QgsLabelObstacleSettings &settings)
Sets the label obstacle settings.
const QgsLabelPlacementSettings & placementSettings() const
Returns the label placement settings.
double maxCurvedCharAngleIn
Maximum angle between inside curved label characters (valid range 20.0 to 60.0).
void setFormat(const QgsTextFormat &format)
Sets the label text formatting settings, e.g., font settings, buffer settings, etc.
double zIndex
Z-Index of label, where labels with a higher z-index are rendered on top of labels with a lower z-ind...
void setPolygonPlacementFlags(Qgis::LabelPolygonPlacementFlags flags)
Sets the polygon placement flags, which dictate how polygon labels can be placed.
QString wrapChar
Wrapping character string.
Qgis::LabelOffsetType offsetType
Offset type for layer (only applies in certain placement modes).
double xOffset
Horizontal offset of label.
Qgis::LabelPlacement placement
Label placement mode.
bool drawLabels
Whether to draw labels for this layer.
bool fontLimitPixelSize
true if label sizes should be limited by pixel size.
double minimumScale
The minimum map scale (i.e.
bool scaleVisibility
Set to true to limit label visibility to a range of scales.
double repeatDistance
Distance for repeating labels for a single feature.
bool geometryGeneratorEnabled
Defines if the geometry generator is enabled or not. If disabled, the standard geometry will be taken...
Qgis::LabelMultiLineAlignment multilineAlign
Horizontal alignment of multi-line labels.
bool centroidInside
true if centroid positioned labels must be placed inside their corresponding feature polygon,...
int priority
Label priority.
Qgis::GeometryType geometryGeneratorType
The type of the result geometry of the geometry generator.
int fontMinPixelSize
Minimum pixel size for showing rendered map unit labels (1 - 1000).
double angleOffset
Label rotation, in degrees clockwise.
double maxCurvedCharAngleOut
Maximum angle between outside curved label characters (valid range -20.0 to -95.0).
Qgis::GeometryType layerType
Geometry type of layers associated with these settings.
void setThinningSettings(const QgsLabelThinningSettings &settings)
Sets the label thinning settings.
Qgis::RenderUnit offsetUnits
Units for offsets of label.
void setDataDefinedProperties(const QgsPropertyCollection &collection)
Sets the label's property collection, used for data defined overrides.
bool isExpression
true if this label is made from a expression string, e.g., FieldName || 'mm'
bool preserveRotation
True if label rotation should be preserved during label pin/unpin operations.
bool plusSign
Whether '+' signs should be prepended to positive numeric labels.
QString geometryGenerator
The geometry generator expression. Null if disabled.
const QgsLabelLineSettings & lineSettings() const
Returns the label line settings, which contain settings related to how the label engine places and fo...
QgsMapUnitScale distMapUnitScale
Map unit scale for label feature distance.
QgsStringReplacementCollection substitutions
Substitution collection for automatic text substitution with labels.
int decimals
Number of decimal places to show for numeric labels.
double dist
Distance from feature to the label.
void setRotationUnit(Qgis::AngleUnit angleUnit)
Set unit for rotation of labels.
QgsMapUnitScale repeatDistanceMapUnitScale
Map unit scale for repeating labels for a single feature.
Qgis::RenderUnit distUnits
Units the distance from feature to the label.
bool centroidWhole
true if feature centroid should be calculated from the whole feature, or false if only the visible pa...
Qgis::RenderUnit repeatDistanceUnit
Units for repeating labels for a single feature.
Qgis::UpsideDownLabelHandling upsidedownLabels
Controls whether upside down labels are displayed and how they are handled.
QString fieldName
Name of field (or an expression) to use for label text.
bool formatNumbers
Set to true to format numeric label text as numbers (e.g.
void setCallout(QgsCallout *callout)
Sets the label callout renderer, responsible for drawing label callouts.
double maximumScale
The maximum map scale (i.e.
int autoWrapLength
If non-zero, indicates that label text should be automatically wrapped to (ideally) the specified num...
bool useMaxLineLengthForAutoWrap
If true, indicates that when auto wrapping label text the autoWrapLength length indicates the maximum...
void setUnplacedVisibility(Qgis::UnplacedLabelVisibility visibility)
Sets the layer's unplaced label visibility.
const QgsLabelPointSettings & pointSettings() const
Returns the label point settings, which contain settings related to how the label engine places and f...
bool useSubstitutions
True if substitutions should be applied.
QgsStyle * styleAtPath(const QString &path)
Returns a reference to the style database associated with the project with matching file path.
static QgsProject * instance()
Returns the QgsProject singleton instance.
const QgsProjectStyleSettings * styleSettings() const
Returns the project's style settings, which contains settings and properties relating to how a QgsPro...
QgsCoordinateTransformContext transformContext
bool removeLabelSettings(const QString &name)
Removes label settings from the style.
bool saveLabelSettings(const QString &name, const QgsPalLayerSettings &settings, bool favorite, const QStringList &tags)
Adds label settings to the database.
QStringList textFormatNames() const
Returns a list of names of text formats in the style.
bool removeTextFormat(const QString &name)
Removes a text format from the style.
StyleEntity
Enum for Entities involved in a style.
@ LabelSettingsEntity
Label settings.
@ TextFormatEntity
Text formats.
@ SmartgroupEntity
Smart groups.
@ Symbol3DEntity
3D symbol entity
@ ColorrampEntity
Color ramps.
@ LegendPatchShapeEntity
Legend patch shape.
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
QStringList labelSettingsNames() const
Returns a list of names of label settings in the style.
static QgsTextFormat defaultTextFormatForProject(QgsProject *project, QgsStyle::TextFormatContext context=QgsStyle::TextFormatContext::Labeling)
Returns the default text format to use for new text based objects for the specified project,...
bool addTextFormat(const QString &name, const QgsTextFormat &format, bool update=false)
Adds a text format with the specified name to the style.
QgsPalLayerSettings labelSettings(const QString &name) const
Returns the label settings with the specified name.
@ Labeling
Text format used in labeling.
bool saveTextFormat(const QString &name, const QgsTextFormat &format, bool favorite, const QStringList &tags)
Adds a text format to the database.
bool addLabelSettings(const QString &name, const QgsPalLayerSettings &settings, bool update=false)
Adds label settings with the specified name to the style.
Contains settings which reflect the context in which a symbol (or renderer) widget is shown,...
void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
void setExpressionContext(QgsExpressionContext *context)
Sets the optional expression context used for the widget.
A widget for customizing text formatting settings.
virtual void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the widget is shown, e.g., the associated map canvas and expression context...
virtual void setFormatFromStyle(const QString &name, QgsStyle::StyleEntity type, const QString &stylePath)
Sets the current text settings from a style entry.
static Q_INVOKABLE QString toString(Qgis::DistanceUnit unit)
Returns a translated string representing a distance unit.
Represents a vector layer which manages a vector based dataset.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const final
Queries the layer for features specified in request.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
Implements a map layer that is dedicated to rendering of vector tiles.
static Q_INVOKABLE QString geometryDisplayString(Qgis::GeometryType type)
Returns a display string for a geometry type.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.