36#include <QButtonGroup>
67 if ( !abstractMetadata )
69 QgsDebugMsg( QStringLiteral(
"Failed to find callout entry in registry: %1" ).arg( name ) );
75 QgsDebugMsg( QStringLiteral(
"Failed to cast callout's metadata: " ) .arg( name ) );
82void QgsLabelingGui::initCalloutWidgets()
84 _initCalloutWidgetFunction( QStringLiteral(
"simple" ), QgsSimpleLineCalloutWidget::create );
85 _initCalloutWidgetFunction( QStringLiteral(
"manhattan" ), QgsManhattanLineCalloutWidget::create );
86 _initCalloutWidgetFunction( QStringLiteral(
"curved" ), QgsCurvedLineCalloutWidget::create );
87 _initCalloutWidgetFunction( QStringLiteral(
"balloon" ), QgsBalloonCalloutWidget::create );
90void QgsLabelingGui::updateCalloutWidget(
QgsCallout *callout )
94 mCalloutStackedWidget->setCurrentWidget( pageDummy );
98 if ( mCalloutStackedWidget->currentWidget() != pageDummy )
101 if (
QgsCalloutWidget *pew = qobject_cast< QgsCalloutWidget * >( mCalloutStackedWidget->currentWidget() ) )
112 if ( mGeometryGeneratorGroupBox->isChecked() )
115 geometryType = mLayer->geometryType();
116 w->setGeometryType( geometryType );
117 w->setCallout( callout );
119 w->setContext( context() );
120 mCalloutStackedWidget->addWidget( w );
121 mCalloutStackedWidget->setCurrentWidget( w );
128 mCalloutStackedWidget->setCurrentWidget( pageDummy );
131void QgsLabelingGui::showObstacleSettings()
142 widget->
setGeometryType( mLayer ? mLayer->geometryType() : Qgis::GeometryType::Unknown );
145 auto applySettings = [ = ]
147 mObstacleSettings = widget->
settings();
150 emit widgetChanged();
166 dialog.buttonBox()->addButton( QDialogButtonBox::Help );
167 connect( dialog.buttonBox(), &QDialogButtonBox::helpRequested,
this, [ = ]
169 QgsHelp::openHelp( QStringLiteral(
"style_library/label_settings.html#obstacles" ) );
181void QgsLabelingGui::showLineAnchorSettings()
192 widget->
setGeometryType( mLayer ? mLayer->geometryType() : Qgis::GeometryType::Unknown );
195 auto applySettings = [ = ]
199 mLineSettings.setAnchorType( widgetSettings.
anchorType() );
200 mLineSettings.setAnchorClipping( widgetSettings.
anchorClipping() );
204 emit widgetChanged();
220 dialog.buttonBox()->addButton( QDialogButtonBox::Help );
221 connect( dialog.buttonBox(), &QDialogButtonBox::helpRequested,
this, [ = ]
223 QgsHelp::openHelp( QStringLiteral(
"style_library/label_settings.html#placement-for-line-layers" ) );
237 , mSettings( layerSettings )
239 , mCanvas( mapCanvas )
241 mGeomType = geomType;
242 static std::once_flag initialized;
243 std::call_once( initialized, [ = ]( )
245 initCalloutWidgets();
248 mFontMultiLineAlignComboBox->addItem( tr(
"Left" ),
static_cast< int >( Qgis::LabelMultiLineAlignment::Left ) );
249 mFontMultiLineAlignComboBox->addItem( tr(
"Center" ),
static_cast< int >( Qgis::LabelMultiLineAlignment::Center ) );
250 mFontMultiLineAlignComboBox->addItem( tr(
"Right" ),
static_cast< int >( Qgis::LabelMultiLineAlignment::Right ) );
251 mFontMultiLineAlignComboBox->addItem( tr(
"Justify" ),
static_cast< int >( Qgis::LabelMultiLineAlignment::Justify ) );
253 mCoordRotationUnitComboBox->addItem(
QgsUnitTypes::toString( Qgis::AngleUnit::Degrees ),
static_cast< int >( Qgis::AngleUnit::Degrees ) );
254 mCoordRotationUnitComboBox->addItem(
QgsUnitTypes::toString( Qgis::AngleUnit::Radians ),
static_cast< int >( Qgis::AngleUnit::Radians ) );
255 mCoordRotationUnitComboBox->addItem(
QgsUnitTypes::toString( Qgis::AngleUnit::Gon ),
static_cast< int >( Qgis::AngleUnit::Gon ) );
256 mCoordRotationUnitComboBox->addItem(
QgsUnitTypes::toString( Qgis::AngleUnit::MinutesOfArc ),
static_cast< int >( Qgis::AngleUnit::MinutesOfArc ) );
257 mCoordRotationUnitComboBox->addItem(
QgsUnitTypes::toString( Qgis::AngleUnit::SecondsOfArc ),
static_cast< int >( Qgis::AngleUnit::SecondsOfArc ) );
258 mCoordRotationUnitComboBox->addItem(
QgsUnitTypes::toString( Qgis::AngleUnit::Turn ),
static_cast< int >( Qgis::AngleUnit::Turn ) );
259 mCoordRotationUnitComboBox->addItem(
QgsUnitTypes::toString( Qgis::AngleUnit::MilliradiansSI ),
static_cast< int >( Qgis::AngleUnit::MilliradiansSI ) );
260 mCoordRotationUnitComboBox->addItem(
QgsUnitTypes::toString( Qgis::AngleUnit::MilNATO ),
static_cast< int >( Qgis::AngleUnit::MilNATO ) );
263 connect( mBufferDrawChkBx, &QAbstractButton::toggled,
this, &QgsLabelingGui::updateUi );
265 connect( mEnableMaskChkBx, &QAbstractButton::toggled,
this, &QgsLabelingGui::updateUi );
266 connect( mShapeDrawChkBx, &QAbstractButton::toggled,
this, &QgsLabelingGui::updateUi );
267 connect( mCalloutsDrawCheckBox, &QAbstractButton::toggled,
this, &QgsLabelingGui::updateUi );
268 connect( mShadowDrawChkBx, &QAbstractButton::toggled,
this, &QgsLabelingGui::updateUi );
269 connect( mDirectSymbChkBx, &QAbstractButton::toggled,
this, &QgsLabelingGui::updateUi );
270 connect( mFormatNumChkBx, &QAbstractButton::toggled,
this, &QgsLabelingGui::updateUi );
271 connect( mScaleBasedVisibilityChkBx, &QAbstractButton::toggled,
this, &QgsLabelingGui::updateUi );
272 connect( mFontLimitPixelChkBox, &QAbstractButton::toggled,
this, &QgsLabelingGui::updateUi );
273 connect( mGeometryGeneratorGroupBox, &QGroupBox::toggled,
this, &QgsLabelingGui::updateGeometryTypeBasedWidgets );
274 connect( mGeometryGeneratorType, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsLabelingGui::updateGeometryTypeBasedWidgets );
275 connect( mGeometryGeneratorExpressionButton, &QToolButton::clicked,
this, &QgsLabelingGui::showGeometryGeneratorExpressionBuilder );
276 connect( mGeometryGeneratorGroupBox, &QGroupBox::toggled,
this, &QgsLabelingGui::validateGeometryGeneratorExpression );
277 connect( mGeometryGenerator, &QgsCodeEditorExpression::textChanged,
this, &QgsLabelingGui::validateGeometryGeneratorExpression );
278 connect( mGeometryGeneratorType, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsLabelingGui::validateGeometryGeneratorExpression );
279 connect( mObstacleSettingsButton, &QAbstractButton::clicked,
this, &QgsLabelingGui::showObstacleSettings );
280 connect( mLineAnchorSettingsButton, &QAbstractButton::clicked,
this, &QgsLabelingGui::showLineAnchorSettings );
282 mFieldExpressionWidget->registerExpressionContextGenerator(
this );
284 mMinScaleWidget->setMapCanvas( mCanvas );
285 mMinScaleWidget->setShowCurrentScaleButton(
true );
286 mMaxScaleWidget->setMapCanvas( mCanvas );
287 mMaxScaleWidget->setShowCurrentScaleButton(
true );
290 for (
const QString &type : calloutTypes )
296 mGeometryGeneratorWarningLabel->setStyleSheet( QStringLiteral(
"color: #FFC107;" ) );
297 mGeometryGeneratorWarningLabel->setTextInteractionFlags( Qt::TextBrowserInteraction );
298 connect( mGeometryGeneratorWarningLabel, &QLabel::linkActivated,
this, [
this](
const QString & link )
300 if ( link == QLatin1String(
"#determineGeometryGeneratorType" ) )
301 determineGeometryGeneratorType();
304 connect( mCalloutStyleComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsLabelingGui::calloutTypeChanged );
306 mLblNoObstacle1->installEventFilter(
this );
311void QgsLabelingGui::setLayer(
QgsMapLayer *mapLayer )
315 if ( ( !mapLayer || mapLayer->
type() != Qgis::LayerType::Vector ) && mGeomType == Qgis::GeometryType::Unknown )
326 mTextFormatsListWidget->setLayerType( mLayer ? mLayer->geometryType() : mGeomType );
327 mBackgroundMarkerSymbolButton->setLayer( mLayer );
328 mBackgroundFillSymbolButton->setLayer( mLayer );
331 updateGeometryTypeBasedWidgets();
333 mFieldExpressionWidget->setLayer( mLayer );
338 mFieldExpressionWidget->setGeomCalculator( da );
340 mFieldExpressionWidget->setEnabled( mMode == Labels || !mLayer );
341 mLabelingFrame->setEnabled( mMode == Labels || !mLayer );
343 blockInitSignals(
true );
345 mGeometryGenerator->setText( mSettings.geometryGenerator );
346 mGeometryGeneratorGroupBox->setChecked( mSettings.geometryGeneratorEnabled );
347 if ( !mSettings.geometryGeneratorEnabled )
348 mGeometryGeneratorGroupBox->setCollapsed(
true );
349 mGeometryGeneratorType->setCurrentIndex( mGeometryGeneratorType->findData( QVariant::fromValue( mSettings.geometryGeneratorType ) ) );
353 mFieldExpressionWidget->setRow( -1 );
354 mFieldExpressionWidget->setField( mSettings.fieldName );
355 mCheckBoxSubstituteText->setChecked( mSettings.useSubstitutions );
356 mSubstitutions = mSettings.substitutions;
359 mCentroidRadioWhole->setChecked( mSettings.centroidWhole );
360 mCentroidInsideCheckBox->setChecked( mSettings.centroidInside );
361 mFitInsidePolygonCheckBox->setChecked( mSettings.fitInPolygonOnly );
362 mLineDistanceSpnBx->setValue( mSettings.dist );
363 mLineDistanceUnitWidget->setUnit( mSettings.distUnits );
364 mLineDistanceUnitWidget->setMapUnitScale( mSettings.distMapUnitScale );
365 mOffsetTypeComboBox->setCurrentIndex( mOffsetTypeComboBox->findData(
static_cast< int >( mSettings.offsetType ) ) );
366 mQuadrantBtnGrp->button(
static_cast<int>( mSettings.quadOffset ) )->setChecked(
true );
367 mPointOffsetXSpinBox->setValue( mSettings.xOffset );
368 mPointOffsetYSpinBox->setValue( mSettings.yOffset );
369 mPointOffsetUnitWidget->setUnit( mSettings.offsetUnits );
370 mPointOffsetUnitWidget->setMapUnitScale( mSettings.labelOffsetMapUnitScale );
371 mPointAngleSpinBox->setValue( mSettings.angleOffset );
372 chkLineAbove->setChecked( mSettings.lineSettings().placementFlags() & QgsLabeling::LinePlacementFlag::AboveLine );
373 chkLineBelow->setChecked( mSettings.lineSettings().placementFlags() & QgsLabeling::LinePlacementFlag::BelowLine );
374 chkLineOn->setChecked( mSettings.lineSettings().placementFlags() & QgsLabeling::LinePlacementFlag::OnLine );
375 chkLineOrientationDependent->setChecked( !( mSettings.lineSettings().placementFlags() & QgsLabeling::LinePlacementFlag::MapOrientation ) );
377 mCheckAllowLabelsOutsidePolygons->setChecked( mSettings.polygonPlacementFlags() & QgsLabeling::PolygonPlacementFlag::AllowPlacementOutsideOfPolygon );
379 const int placementIndex = mPlacementModeComboBox->findData(
static_cast< int >( mSettings.placement ) );
380 if ( placementIndex >= 0 )
382 mPlacementModeComboBox->setCurrentIndex( placementIndex );
387 mPlacementModeComboBox->setCurrentIndex( 0 );
391 mRepeatDistanceSpinBox->setValue( mSettings.repeatDistance );
392 mRepeatDistanceUnitWidget->setUnit( mSettings.repeatDistanceUnit );
393 mRepeatDistanceUnitWidget->setMapUnitScale( mSettings.repeatDistanceMapUnitScale );
395 mOverrunDistanceSpinBox->setValue( mSettings.lineSettings().overrunDistance() );
396 mOverrunDistanceUnitWidget->setUnit( mSettings.lineSettings().overrunDistanceUnit() );
397 mOverrunDistanceUnitWidget->setMapUnitScale( mSettings.lineSettings().overrunDistanceMapUnitScale() );
399 mPrioritySlider->setValue( mSettings.priority );
400 mChkNoObstacle->setChecked( mSettings.obstacleSettings().isObstacle() );
402 mObstacleSettings = mSettings.obstacleSettings();
403 mLineSettings = mSettings.lineSettings();
405 chkLabelPerFeaturePart->setChecked( mSettings.labelPerPart );
407 mComboOverlapHandling->setCurrentIndex( mComboOverlapHandling->findData(
static_cast< int >( mSettings.placementSettings().overlapHandling() ) ) );
408 mCheckAllowDegradedPlacement->setChecked( mSettings.placementSettings().allowDegradedPlacement() );
410 chkMergeLines->setChecked( mSettings.lineSettings().mergeLines() );
411 mMinSizeSpinBox->setValue( mSettings.thinningSettings().minimumFeatureSize() );
412 mLimitLabelChkBox->setChecked( mSettings.thinningSettings().limitNumberOfLabelsEnabled() );
413 mLimitLabelSpinBox->setValue( mSettings.thinningSettings().maximumNumberLabels() );
416 mDirectSymbChkBx->setChecked( mSettings.lineSettings().addDirectionSymbol() );
417 mDirectSymbLeftLineEdit->setText( mSettings.lineSettings().leftDirectionSymbol() );
418 mDirectSymbRightLineEdit->setText( mSettings.lineSettings().rightDirectionSymbol() );
419 mDirectSymbRevChkBx->setChecked( mSettings.lineSettings().reverseDirectionSymbol() );
421 mDirectSymbBtnGrp->button(
static_cast<int>( mSettings.lineSettings().directionSymbolPlacement() ) )->setChecked(
true );
422 mUpsidedownBtnGrp->button(
static_cast<int>( mSettings.upsidedownLabels ) )->setChecked(
true );
425 mMaxCharAngleInDSpinBox->setValue( mSettings.maxCurvedCharAngleIn );
427 mMaxCharAngleOutDSpinBox->setValue( std::fabs( mSettings.maxCurvedCharAngleOut ) );
429 wrapCharacterEdit->setText( mSettings.wrapChar );
430 mAutoWrapLengthSpinBox->setValue( mSettings.autoWrapLength );
431 mAutoWrapTypeComboBox->setCurrentIndex( mSettings.useMaxLineLengthForAutoWrap ? 0 : 1 );
433 if ( mFontMultiLineAlignComboBox->findData(
static_cast< int >( mSettings.multilineAlign ) ) != -1 )
435 mFontMultiLineAlignComboBox->setCurrentIndex( mFontMultiLineAlignComboBox->findData(
static_cast< int >( mSettings.multilineAlign ) ) );
441 mFontMultiLineAlignComboBox->setCurrentIndex( 0 );
444 chkPreserveRotation->setChecked( mSettings.preserveRotation );
446 mCoordRotationUnitComboBox->setCurrentIndex( 0 );
447 if ( mCoordRotationUnitComboBox->findData(
static_cast< unsigned int >( mSettings.rotationUnit() ) ) >= 0 )
448 mCoordRotationUnitComboBox->setCurrentIndex( mCoordRotationUnitComboBox->findData(
static_cast< unsigned int >( mSettings.rotationUnit() ) ) );
450 mScaleBasedVisibilityChkBx->setChecked( mSettings.scaleVisibility );
451 mMinScaleWidget->setScale( mSettings.minimumScale );
452 mMaxScaleWidget->setScale( mSettings.maximumScale );
454 mFormatNumChkBx->setChecked( mSettings.formatNumbers );
455 mFormatNumDecimalsSpnBx->setValue( mSettings.decimals );
456 mFormatNumPlusSignChkBx->setChecked( mSettings.plusSign );
460 mFontLimitPixelChkBox->setChecked( mSettings.fontLimitPixelSize );
461 mMinPixelLimit = mSettings.fontMinPixelSize;
462 mFontMinPixelSpinBox->setValue( mSettings.fontMinPixelSize == 0 ? 3 : mSettings.fontMinPixelSize );
463 mFontMaxPixelSpinBox->setValue( mSettings.fontMaxPixelSize );
465 mZIndexSpinBox->setValue( mSettings.zIndex );
467 mDataDefinedProperties = mSettings.dataDefinedProperties();
470 if (
auto *lCallout = mSettings.callout() )
472 whileBlocking( mCalloutsDrawCheckBox )->setChecked( lCallout->enabled() );
473 whileBlocking( mCalloutStyleComboBox )->setCurrentIndex( mCalloutStyleComboBox->findData( lCallout->type() ) );
474 updateCalloutWidget( lCallout );
479 whileBlocking( mCalloutStyleComboBox )->setCurrentIndex( mCalloutStyleComboBox->findData( defaultCallout->type() ) );
481 updateCalloutWidget( defaultCallout.get() );
484 updatePlacementWidgets();
485 updateLinePlacementOptions();
488 blockInitSignals(
false );
492 populateDataDefinedButtons();
499 mSettings = settings;
503void QgsLabelingGui::blockInitSignals(
bool block )
505 chkLineAbove->blockSignals( block );
506 chkLineBelow->blockSignals( block );
507 mPlacementModeComboBox->blockSignals( block );
510void QgsLabelingGui::setLabelMode( LabelMode mode )
513 mFieldExpressionWidget->setEnabled( mMode == Labels );
514 mLabelingFrame->setEnabled( mMode == Labels );
524 lyr.
drawLabels = ( mMode == Labels ) || !mLayer;
527 lyr.
fieldName = mFieldExpressionWidget->currentField( &isExpression );
532 QgsLabeling::PolygonPlacementFlags polygonPlacementFlags = QgsLabeling::PolygonPlacementFlag::AllowPlacementInsideOfPolygon;
533 if ( mCheckAllowLabelsOutsidePolygons->isChecked() )
534 polygonPlacementFlags |= QgsLabeling::PolygonPlacementFlag::AllowPlacementOutsideOfPolygon;
540 lyr.
dist = mLineDistanceSpnBx->value();
541 lyr.
distUnits = mLineDistanceUnitWidget->unit();
544 if ( mQuadrantBtnGrp )
548 lyr.
xOffset = mPointOffsetXSpinBox->value();
549 lyr.
yOffset = mPointOffsetYSpinBox->value();
554 QgsLabeling::LinePlacementFlags linePlacementFlags = QgsLabeling::LinePlacementFlags();
555 if ( chkLineAbove->isChecked() )
556 linePlacementFlags |= QgsLabeling::LinePlacementFlag::AboveLine;
557 if ( chkLineBelow->isChecked() )
558 linePlacementFlags |= QgsLabeling::LinePlacementFlag::BelowLine;
559 if ( chkLineOn->isChecked() )
560 linePlacementFlags |= QgsLabeling::LinePlacementFlag::OnLine;
561 if ( ! chkLineOrientationDependent->isChecked() )
562 linePlacementFlags |= QgsLabeling::LinePlacementFlag::MapOrientation;
575 lyr.
priority = mPrioritySlider->value();
577 mObstacleSettings.setIsObstacle( mChkNoObstacle->isChecked() || mMode == ObstaclesOnly );
601 lyr.
decimals = mFormatNumDecimalsSpnBx->value();
602 lyr.
plusSign = mFormatNumPlusSignChkBx->isChecked();
609 if ( mDirectSymbBtnGrp )
613 if ( mUpsidedownBtnGrp )
629 lyr.
wrapChar = wrapCharacterEdit->text();
639 lyr.
layerType = mLayer ? mLayer->geometryType() : mGeomType;
641 lyr.
zIndex = mZIndexSpinBox->value();
646 const QString calloutType = mCalloutStyleComboBox->currentData().toString();
647 std::unique_ptr< QgsCallout > callout;
648 if (
QgsCalloutWidget *pew = qobject_cast< QgsCalloutWidget * >( mCalloutStackedWidget->currentWidget() ) )
650 callout.reset( pew->callout()->clone() );
655 callout->
setEnabled( mCalloutsDrawCheckBox->isChecked() );
663 f->setEnabled( chkBx->isChecked() || ddBtn->
isActive() );
666bool QgsLabelingGui::eventFilter( QObject *
object, QEvent *event )
668 if (
object == mLblNoObstacle1 )
670 if ( event->type() == QEvent::MouseButtonPress && qgis::down_cast< QMouseEvent * >( event )->button() == Qt::LeftButton )
673 mChkNoObstacle->setChecked( !mChkNoObstacle->isChecked() );
678 return QgsTextFormatWidget::eventFilter(
object, event );
681void QgsLabelingGui::updateUi()
685 syncDefinedCheckboxFrame( mBufferDrawDDBtn, mBufferDrawChkBx, mBufferFrame );
686 syncDefinedCheckboxFrame( mEnableMaskDDBtn, mEnableMaskChkBx, mMaskFrame );
687 syncDefinedCheckboxFrame( mShapeDrawDDBtn, mShapeDrawChkBx, mShapeFrame );
688 syncDefinedCheckboxFrame( mShadowDrawDDBtn, mShadowDrawChkBx, mShadowFrame );
689 syncDefinedCheckboxFrame( mCalloutDrawDDBtn, mCalloutsDrawCheckBox, mCalloutFrame );
691 syncDefinedCheckboxFrame( mDirectSymbDDBtn, mDirectSymbChkBx, mDirectSymbFrame );
692 syncDefinedCheckboxFrame( mFormatNumDDBtn, mFormatNumChkBx, mFormatNumFrame );
693 syncDefinedCheckboxFrame( mScaleBasedVisibilityDDBtn, mScaleBasedVisibilityChkBx, mScaleBasedVisibilityFrame );
694 syncDefinedCheckboxFrame( mFontLimitPixelDDBtn, mFontLimitPixelChkBox, mFontLimitPixelFrame );
696 chkMergeLines->setEnabled( !mDirectSymbChkBx->isChecked() );
697 if ( mDirectSymbChkBx->isChecked() )
699 chkMergeLines->setToolTip( tr(
"This option is not compatible with line direction symbols." ) );
703 chkMergeLines->setToolTip( QString() );
707void QgsLabelingGui::setFormatFromStyle(
const QString &name,
QgsStyle::StyleEntity type,
const QString &stylePath )
738 settings.
fieldName = mFieldExpressionWidget->currentField( &isExpression );
741 setSettings( settings );
749 if (
QgsCalloutWidget *cw = qobject_cast< QgsCalloutWidget * >( mCalloutStackedWidget->currentWidget() ) )
751 cw->setContext( context );
756void QgsLabelingGui::saveFormat()
759 saveDlg.setDefaultTags( mTextFormatsListWidget->currentTagFilter() );
760 if ( !saveDlg.exec() )
763 if ( saveDlg.name().isEmpty() )
766 QgsStyle *style = saveDlg.destinationStyle();
770 switch ( saveDlg.selectedType() )
777 const int res = QMessageBox::warning(
this, tr(
"Save Text Format" ),
778 tr(
"Format with name '%1' already exists. Overwrite?" )
779 .arg( saveDlg.name() ),
780 QMessageBox::Yes | QMessageBox::No );
781 if ( res != QMessageBox::Yes )
787 const QStringList symbolTags = saveDlg.tags().split(
',' );
791 style->
saveTextFormat( saveDlg.name(), newFormat, saveDlg.isFavorite(), symbolTags );
800 const int res = QMessageBox::warning(
this, tr(
"Save Label Settings" ),
801 tr(
"Label settings with the name '%1' already exist. Overwrite?" )
802 .arg( saveDlg.name() ),
803 QMessageBox::Yes | QMessageBox::No );
804 if ( res != QMessageBox::Yes )
810 const QStringList symbolTags = saveDlg.tags().split(
',' );
814 style->
saveLabelSettings( saveDlg.name(), newSettings, saveDlg.isFavorite(), symbolTags );
828void QgsLabelingGui::updateGeometryTypeBasedWidgets()
832 if ( mGeometryGeneratorGroupBox->isChecked() )
835 geometryType = mLayer->geometryType();
838 chkMergeLines->setVisible( geometryType == Qgis::GeometryType::Line );
839 mDirectSymbolsFrame->setVisible( geometryType == Qgis::GeometryType::Line );
840 mMinSizeFrame->setVisible( geometryType != Qgis::GeometryType::Point );
841 mPolygonFeatureOptionsFrame->setVisible( geometryType == Qgis::GeometryType::Polygon );
845 mPlacementModeComboBox->clear();
847 switch ( geometryType )
849 case Qgis::GeometryType::Point:
855 case Qgis::GeometryType::Line:
861 case Qgis::GeometryType::Polygon:
871 case Qgis::GeometryType::Null:
873 case Qgis::GeometryType::Unknown:
874 qFatal(
"unknown geometry type unexpected" );
877 if ( mPlacementModeComboBox->findData(
static_cast< int >( prevPlacement ) ) != -1 )
879 mPlacementModeComboBox->setCurrentIndex( mPlacementModeComboBox->findData(
static_cast< int >( prevPlacement ) ) );
882 if ( geometryType == Qgis::GeometryType::Point || geometryType == Qgis::GeometryType::Polygon )
885 if ( mFontMultiLineAlignComboBox->findData(
static_cast< int >( Qgis::LabelMultiLineAlignment::FollowPlacement ) ) == -1 )
886 mFontMultiLineAlignComboBox->addItem( tr(
"Follow Label Placement" ),
static_cast< int >( Qgis::LabelMultiLineAlignment::FollowPlacement ) );
890 const int idx = mFontMultiLineAlignComboBox->findData(
static_cast< int >( Qgis::LabelMultiLineAlignment::FollowPlacement ) );
892 mFontMultiLineAlignComboBox->removeItem( idx );
895 updatePlacementWidgets();
896 updateLinePlacementOptions();
899void QgsLabelingGui::showGeometryGeneratorExpressionBuilder()
903 expressionBuilder.setExpressionText( mGeometryGenerator->text() );
904 expressionBuilder.setExpressionContext( createExpressionContext() );
906 if ( expressionBuilder.exec() )
908 mGeometryGenerator->setText( expressionBuilder.expressionText() );
912void QgsLabelingGui::validateGeometryGeneratorExpression()
916 if ( mGeometryGeneratorGroupBox->isChecked() )
918 if ( !mPreviewFeature.isValid() && mLayer )
919 mLayer->getFeatures(
QgsFeatureRequest().setLimit( 1 ) ).nextFeature( mPreviewFeature );
925 expression.prepare( &context );
927 if ( expression.hasParserError() )
929 mGeometryGeneratorWarningLabel->setText( expression.parserErrorString() );
934 const QVariant result = expression.evaluate( &context );
939 mGeometryGeneratorWarningLabel->setText( tr(
"Result of the expression is not a geometry" ) );
942 else if ( geometry.
type() != configuredGeometryType )
944 mGeometryGeneratorWarningLabel->setText( QStringLiteral(
"<p>%1</p><p><a href=\"#determineGeometryGeneratorType\">%2</a></p>" ).arg(
945 tr(
"Result of the expression does not match configured geometry type." ),
954 QTimer *timer =
new QTimer();
955 connect( timer, &QTimer::timeout,
this, [
this, valid]()
957 mGeometryGeneratorWarningLabel->setVisible( !valid );
959 connect( timer, &QTimer::timeout, timer, &QTimer::deleteLater );
963void QgsLabelingGui::determineGeometryGeneratorType()
965 if ( !mPreviewFeature.isValid() && mLayer )
966 mLayer->getFeatures(
QgsFeatureRequest().setLimit( 1 ) ).nextFeature( mPreviewFeature );
972 expression.prepare( &context );
975 mGeometryGeneratorType->setCurrentIndex( mGeometryGeneratorType->findData( QVariant::fromValue( geometry.
type() ) ) );
978void QgsLabelingGui::calloutTypeChanged()
980 const QString newCalloutType = mCalloutStyleComboBox->currentData().toString();
981 QgsCalloutWidget *pew = qobject_cast< QgsCalloutWidget * >( mCalloutStackedWidget->currentWidget() );
1000 updateCalloutWidget( newCallout.get() );
1013 QVBoxLayout *vLayout =
new QVBoxLayout();
1014 mWidget =
new QgsLabelingGui( layer, mapCanvas, settings,
nullptr, geomType );
1015 vLayout->addWidget( mWidget );
1016 mButtonBox =
new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok, Qt::Horizontal );
1017 connect( mButtonBox, &QDialogButtonBox::accepted,
this, &QDialog::accept );
1018 connect( mButtonBox, &QDialogButtonBox::rejected,
this, &QDialog::reject );
1019 connect( mButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsLabelSettingsDialog::showHelp );
1020 vLayout->addWidget( mButtonBox );
1021 setLayout( vLayout );
1022 setWindowTitle( tr(
"Label Settings" ) );
1025QDialogButtonBox *QgsLabelSettingsDialog::buttonBox()
const
1030void QgsLabelSettingsDialog::showHelp()
AngleUnit
Units of angles.
LabelOffsetType
Behavior modifier for label offset and distance, only applies in some label placement modes.
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....
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.
LabelOverlapHandling
Label overlap handling.
UpsideDownLabelHandling
Handling techniques for upside down labels.
static QgsCalloutRegistry * calloutRegistry()
Returns the application's callout registry, used for managing callout types.
Registry of available callout classes.
QgsCalloutAbstractMetadata * calloutMetadata(const QString &type) const
Returns the metadata for specified the specified callout type.
static QgsCallout * defaultCallout()
Create a new instance of a callout with default settings.
QStringList calloutTypes() const
Returns a list of all available callout types.
QgsCallout * createCallout(const QString &type, const QVariantMap &properties=QVariantMap(), const QgsReadWriteContext &context=QgsReadWriteContext()) const
Creates a new instance of a callout, given the callout type and properties.
Abstract base class for callout renderers.
void setEnabled(bool enabled)
Sets whether the callout is enabled.
virtual QString type() const =0
Returns a unique string representing the callout type.
virtual QVariantMap properties(const QgsReadWriteContext &context) const
Returns the properties describing the callout encoded in a string format.
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
A generic dialog for building expression strings.
Single scope for storing variables and functions for use within a QgsExpressionContext.
static QgsExpressionContextScope * updateSymbolScope(const QgsSymbol *symbol, QgsExpressionContextScope *symbolScope=nullptr)
Updates a symbol scope related to a QgsSymbol to an expression context.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * atlasScope(const QgsLayoutAtlas *atlas)
Creates a new scope which contains variables and functions relating to a QgsLayoutAtlas.
static QgsExpressionContextScope * 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.
static const QString EXPR_SYMBOL_COLOR
Inbuilt variable name for symbol color variable.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user.
static const QString EXPR_ORIGINAL_VALUE
Inbuilt variable name for value original value variable.
Class for parsing and evaluation of expressions (formerly called "search strings").
This class wraps a request for features to a vector layer (or directly its vector data provider).
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
A geometry is the spatial representation of a feature.
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Contains settings related to how the label engine places and formats labels for line features (or pol...
void setPlacementFlags(QgsLabeling::LinePlacementFlags 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 setOverlapHandling(Qgis::LabelOverlapHandling handling)
Sets the technique used to handle overlapping labels.
void setAllowDegradedPlacement(bool allow)
Sets whether labels can be placed in inferior fallback positions if they cannot otherwise be placed.
void setMaximumNumberLabels(int number)
Sets the maximum number of labels which should be drawn for this layer.
void setLimitNumberLabelsEnabled(bool enabled)
Sets whether the the number of labels drawn for the layer should be limited.
void setMinimumFeatureSize(double size)
Sets the minimum feature size (in millimeters) for a feature to be labelled.
Map canvas is a class for displaying all GIS data types on a canvas.
Base class for all map layer types.
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...
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.
Qgis::LabelQuadrantPosition quadOffset
Sets the quadrant in which to offset labels from feature.
bool scaleVisibility
Set to true to limit label visibility to a range of scales.
double repeatDistance
Distance for repeating labels for a single feature.
bool geometryGeneratorEnabled
Defines if the geometry generator is enabled or not. If disabled, the standard geometry will be taken...
Qgis::LabelMultiLineAlignment multilineAlign
Horizontal alignment of multi-line labels.
bool centroidInside
true if centroid positioned labels must be placed inside their corresponding feature polygon,...
int priority
Label priority.
Qgis::GeometryType geometryGeneratorType
The type of the result geometry of the geometry generator.
bool labelPerPart
true if every part of a multi-part feature should be labeled.
int fontMinPixelSize
Minimum pixel size for showing rendered map unit labels (1 - 1000).
double angleOffset
Label rotation, in degrees clockwise.
double maxCurvedCharAngleOut
Maximum angle between outside curved label characters (valid range -20.0 to -95.0)
const QgsLabelThinningSettings & thinningSettings() const
Returns the label thinning settings.
void setPolygonPlacementFlags(QgsLabeling::PolygonPlacementFlags flags)
Sets the polygon placement flags, which dictate how polygon labels can be placed.
Qgis::GeometryType layerType
Geometry type of layers associated with these settings.
Qgis::RenderUnit offsetUnits
Units for offsets of label.
void setDataDefinedProperties(const QgsPropertyCollection &collection)
Sets the label's property collection, used for data defined overrides.
bool isExpression
true if this label is made from a expression string, e.g., FieldName || 'mm'
bool preserveRotation
True if label rotation should be preserved during label pin/unpin operations.
bool plusSign
Whether '+' signs should be prepended to positive numeric labels.
QString geometryGenerator
The geometry generator expression. Null if disabled.
const QgsLabelLineSettings & lineSettings() const
Returns the label line settings, which contain settings related to how the label engine places and fo...
QgsMapUnitScale distMapUnitScale
Map unit scale for label feature distance.
QgsStringReplacementCollection substitutions
Substitution collection for automatic text substitution with labels.
int decimals
Number of decimal places to show for numeric labels.
double dist
Distance from feature to the label.
void setRotationUnit(Qgis::AngleUnit angleUnit)
Set unit for rotation of labels.
QgsMapUnitScale repeatDistanceMapUnitScale
Map unit scale for repeating labels for a single feature.
Qgis::RenderUnit distUnits
Units the distance from feature to the label.
bool centroidWhole
true if feature centroid should be calculated from the whole feature, or false if only the visible pa...
Qgis::RenderUnit repeatDistanceUnit
Units for repeating labels for a single feature.
Qgis::UpsideDownLabelHandling upsidedownLabels
Controls whether upside down labels are displayed and how they are handled.
QString fieldName
Name of field (or an expression) to use for label text.
bool formatNumbers
Set to true to format numeric label text as numbers (e.g.
void setCallout(QgsCallout *callout)
Sets the label callout renderer, responsible for drawing label callouts.
double maximumScale
The maximum map scale (i.e.
int autoWrapLength
If non-zero, indicates that label text should be automatically wrapped to (ideally) the specified num...
bool useMaxLineLengthForAutoWrap
If true, indicates that when auto wrapping label text the autoWrapLength length indicates the maximum...
void setUnplacedVisibility(Qgis::UnplacedLabelVisibility visibility)
Sets the layer's unplaced label visibility.
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
A grouped map of multiple QgsProperty objects, each referenced by a integer key value.
The class is used as a container of context for various read/write operations on other objects.
a dialog for setting properties of a newly saved style.
bool removeLabelSettings(const QString &name)
Removes label settings from the style.
bool saveLabelSettings(const QString &name, const QgsPalLayerSettings &settings, bool favorite, const QStringList &tags)
Adds label settings to the database.
QStringList textFormatNames() const
Returns a list of names of text formats in the style.
bool removeTextFormat(const QString &name)
Removes a text format from the style.
StyleEntity
Enum for Entities involved in a style.
@ LabelSettingsEntity
Label settings.
@ TextFormatEntity
Text formats.
@ SmartgroupEntity
Smart groups.
@ Symbol3DEntity
3D symbol entity (since QGIS 3.14)
@ ColorrampEntity
Color ramps.
@ LegendPatchShapeEntity
Legend patch shape (since QGIS 3.14)
static QgsStyle * defaultStyle()
Returns 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.
Container for all settings relating to text rendering.
static Q_INVOKABLE QString toString(Qgis::DistanceUnit unit)
Returns a translated string representing a distance unit.
Represents a vector layer which manages a vector based data sets.
static QString geometryDisplayString(Qgis::GeometryType type) SIP_HOLDGIL
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.
QgsCalloutWidget *(* QgsCalloutWidgetFunc)(QgsVectorLayer *)