1 /***************************************************************************
2 qgslabelpropertydialog.cpp
3 --------------------------
4 begin : 2010-11-12
5 copyright : (C) 2010 by Marco Hugentobler
6 email : marco dot hugentobler at sourcepole dot ch
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18 #include "qgslabelpropertydialog.h"
19 #include "qgsfontutils.h"
20 #include "qgslogger.h"
21 #include "qgsfeatureiterator.h"
22 #include "qgsproject.h"
23 #include "qgsvectorlayer.h"
24 #include "qgisapp.h"
25 #include "qgsmapcanvas.h"
26 #include "qgsvectorlayerlabeling.h"
27 #include "qgsproperty.h"
28 #include "qgssettings.h"
29 #include "qgsexpressioncontextutils.h"
30 #include "qgsgui.h"
31 #include "qgshelp.h"
32
33 #include <QColorDialog>
34 #include <QFontDatabase>
35 #include <QDialogButtonBox>
36
37
QgsLabelPropertyDialog(const QString & layerId,const QString & providerId,QgsFeatureId featureId,const QFont & labelFont,const QString & labelText,bool isPinned,const QgsPalLayerSettings & layerSettings,QWidget * parent,Qt::WindowFlags f)38 QgsLabelPropertyDialog::QgsLabelPropertyDialog( const QString &layerId, const QString &providerId, QgsFeatureId featureId, const QFont &labelFont, const QString &labelText, bool isPinned, const QgsPalLayerSettings &layerSettings, QWidget *parent, Qt::WindowFlags f )
39 : QDialog( parent, f )
40 , mLabelFont( labelFont )
41 , mIsPinned( isPinned )
42 {
43 setupUi( this );
44 QgsGui::instance()->enableAutoGeometryRestore( this );
45
46 // set defaults to layer defaults
47 mLabelAllPartsCheckBox->setChecked( layerSettings.labelPerPart );
48
49 connect( buttonBox, &QDialogButtonBox::clicked, this, &QgsLabelPropertyDialog::buttonBox_clicked );
50 connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsLabelPropertyDialog::showHelp );
51 connect( mShowLabelChkbx, &QCheckBox::toggled, this, &QgsLabelPropertyDialog::mShowLabelChkbx_toggled );
52 connect( mAlwaysShowChkbx, &QCheckBox::toggled, this, &QgsLabelPropertyDialog::mAlwaysShowChkbx_toggled );
53 connect( mShowCalloutChkbx, &QCheckBox::toggled, this, &QgsLabelPropertyDialog::showCalloutToggled );
54 connect( mBufferDrawChkbx, &QCheckBox::toggled, this, &QgsLabelPropertyDialog::bufferDrawToggled );
55 connect( mLabelDistanceSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLabelPropertyDialog::mLabelDistanceSpinBox_valueChanged );
56 connect( mXCoordSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLabelPropertyDialog::mXCoordSpinBox_valueChanged );
57 connect( mYCoordSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLabelPropertyDialog::mYCoordSpinBox_valueChanged );
58 connect( mFontFamilyCmbBx, &QFontComboBox::currentFontChanged, this, &QgsLabelPropertyDialog::mFontFamilyCmbBx_currentFontChanged );
59 connect( mFontStyleCmbBx, &QComboBox::currentTextChanged, this, &QgsLabelPropertyDialog::mFontStyleCmbBx_currentIndexChanged );
60 connect( mFontUnderlineBtn, &QToolButton::toggled, this, &QgsLabelPropertyDialog::mFontUnderlineBtn_toggled );
61 connect( mFontStrikethroughBtn, &QToolButton::toggled, this, &QgsLabelPropertyDialog::mFontStrikethroughBtn_toggled );
62 connect( mFontBoldBtn, &QToolButton::toggled, this, &QgsLabelPropertyDialog::mFontBoldBtn_toggled );
63 connect( mFontItalicBtn, &QToolButton::toggled, this, &QgsLabelPropertyDialog::mFontItalicBtn_toggled );
64 connect( mFontSizeSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLabelPropertyDialog::mFontSizeSpinBox_valueChanged );
65 connect( mBufferSizeSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLabelPropertyDialog::mBufferSizeSpinBox_valueChanged );
66 connect( mRotationSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLabelPropertyDialog::mRotationSpinBox_valueChanged );
67 connect( mFontColorButton, &QgsColorButton::colorChanged, this, &QgsLabelPropertyDialog::mFontColorButton_colorChanged );
68 connect( mBufferColorButton, &QgsColorButton::colorChanged, this, &QgsLabelPropertyDialog::mBufferColorButton_colorChanged );
69 connect( mMultiLineAlignComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLabelPropertyDialog::mMultiLineAlignComboBox_currentIndexChanged );
70 connect( mHaliComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLabelPropertyDialog::mHaliComboBox_currentIndexChanged );
71 connect( mValiComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLabelPropertyDialog::mValiComboBox_currentIndexChanged );
72 connect( mLabelTextLineEdit, &QLineEdit::textChanged, this, &QgsLabelPropertyDialog::mLabelTextLineEdit_textChanged );
73 connect( mLabelAllPartsCheckBox, &QCheckBox::toggled, this, &QgsLabelPropertyDialog::labelAllPartsToggled );
74
75 mRotationSpinBox->setClearValue( 0 );
76 fillMultiLineAlignComboBox();
77 fillHaliComboBox();
78 fillValiComboBox();
79
80 init( layerId, providerId, featureId, labelText );
81
82 connect( mMinScaleWidget, &QgsScaleWidget::scaleChanged, this, &QgsLabelPropertyDialog::minScaleChanged );
83 connect( mMaxScaleWidget, &QgsScaleWidget::scaleChanged, this, &QgsLabelPropertyDialog::maxScaleChanged );
84 }
85
setMapCanvas(QgsMapCanvas * canvas)86 void QgsLabelPropertyDialog::setMapCanvas( QgsMapCanvas *canvas )
87 {
88 mMinScaleWidget->setMapCanvas( canvas );
89 mMinScaleWidget->setShowCurrentScaleButton( true );
90 mMaxScaleWidget->setMapCanvas( canvas );
91 mMaxScaleWidget->setShowCurrentScaleButton( true );
92 }
93
buttonBox_clicked(QAbstractButton * button)94 void QgsLabelPropertyDialog::buttonBox_clicked( QAbstractButton *button )
95 {
96 if ( buttonBox->buttonRole( button ) == QDialogButtonBox::ApplyRole )
97 {
98 emit applied();
99 }
100 }
101
init(const QString & layerId,const QString & providerId,QgsFeatureId featureId,const QString & labelText)102 void QgsLabelPropertyDialog::init( const QString &layerId, const QString &providerId, QgsFeatureId featureId, const QString &labelText )
103 {
104 //get feature attributes
105 QgsVectorLayer *vlayer = QgsProject::instance()->mapLayer<QgsVectorLayer *>( layerId );
106 if ( !vlayer )
107 {
108 return;
109 }
110 if ( !vlayer->labeling() )
111 {
112 return;
113 }
114
115 if ( !vlayer->getFeatures( QgsFeatureRequest().setFilterFid( featureId ).setFlags( QgsFeatureRequest::NoGeometry ) ).nextFeature( mCurLabelFeat ) )
116 {
117 return;
118 }
119 QgsAttributes attributeValues = mCurLabelFeat.attributes();
120
121 //get layerproperties. Problem: only for pallabeling...
122
123 blockElementSignals( true );
124
125 QgsPalLayerSettings layerSettings = vlayer->labeling()->settings( providerId );
126
127 //get label field and fill line edit
128 if ( layerSettings.isExpression && !labelText.isNull() )
129 {
130 mLabelTextLineEdit->setText( labelText );
131 mLabelTextLineEdit->setEnabled( false );
132 mLabelTextLabel->setText( tr( "Expression result" ) );
133 }
134 else
135 {
136 QString labelFieldName = layerSettings.fieldName;
137 if ( !labelFieldName.isEmpty() )
138 {
139 mCurLabelField = vlayer->fields().lookupField( labelFieldName );
140 if ( mCurLabelField >= 0 )
141 {
142 mLabelTextLineEdit->setText( attributeValues.at( mCurLabelField ).toString() );
143
144 if ( vlayer->isEditable() )
145 mLabelTextLineEdit->setEnabled( true );
146 else
147 mLabelTextLineEdit->setEnabled( false );
148
149 const QgsFields &layerFields = vlayer->fields();
150 switch ( layerFields.at( mCurLabelField ).type() )
151 {
152 case QVariant::Double:
153 mLabelTextLineEdit->setValidator( new QDoubleValidator( this ) );
154 break;
155 case QVariant::Int:
156 case QVariant::UInt:
157 case QVariant::LongLong:
158 mLabelTextLineEdit->setValidator( new QIntValidator( this ) );
159 break;
160 default:
161 break;
162 }
163 }
164 else
165 {
166 mLabelTextLineEdit->setEnabled( false );
167 }
168 }
169 }
170
171 //get attributes of the feature and fill data defined values
172
173 // font is set directly from QgsLabelPosition
174 updateFont( mLabelFont, false );
175
176 QgsTextFormat format = layerSettings.format();
177 QgsTextBufferSettings buffer = format.buffer();
178
179 //set all the gui elements to the default layer-level values
180 mLabelDistanceSpinBox->clear();
181 mLabelDistanceSpinBox->setSpecialValueText( tr( "Layer default (%1)" ).arg( QString::number( layerSettings.dist, 'f', mLabelDistanceSpinBox->decimals() ) ) );
182 mBufferSizeSpinBox->clear();
183 mBufferSizeSpinBox->setSpecialValueText( tr( "Layer default (%1)" ).arg( QString::number( buffer.size(), 'f', mBufferSizeSpinBox->decimals() ) ) );
184 mRotationSpinBox->clear();
185 mXCoordSpinBox->clear();
186 mYCoordSpinBox->clear();
187
188 mShowLabelChkbx->setChecked( true );
189 mBufferDrawChkbx->setChecked( buffer.enabled() );
190 mFontColorButton->setColor( format.color() );
191 mBufferColorButton->setColor( buffer.color() );
192 mMinScaleWidget->setScale( layerSettings.minimumScale );
193 mMaxScaleWidget->setScale( layerSettings.maximumScale );
194
195 QString defaultMultilineAlign;
196 switch ( layerSettings.multilineAlign )
197 {
198 case QgsPalLayerSettings::MultiLeft:
199 defaultMultilineAlign = QStringLiteral( "left" );
200 break;
201 case QgsPalLayerSettings::MultiCenter:
202 defaultMultilineAlign = QStringLiteral( "center" );
203 break;
204 case QgsPalLayerSettings::MultiRight:
205 defaultMultilineAlign = QStringLiteral( "right" );
206 break;
207 case QgsPalLayerSettings::MultiJustify:
208 defaultMultilineAlign = QStringLiteral( "justify" );
209 break;
210 case QgsPalLayerSettings::MultiFollowPlacement:
211 defaultMultilineAlign = QStringLiteral( "follow label placement" );
212 break;
213 }
214 mMultiLineAlignComboBox->setItemText( mMultiLineAlignComboBox->findData( "" ), tr( "Layer default (%1)" ).arg( defaultMultilineAlign ) );
215 mMultiLineAlignComboBox->setCurrentIndex( mMultiLineAlignComboBox->findData( "" ) );
216
217 mHaliComboBox->setCurrentIndex( mHaliComboBox->findData( "left", Qt::UserRole, Qt::MatchFixedString ) );
218 mValiComboBox->setCurrentIndex( mValiComboBox->findData( "bottom", Qt::UserRole, Qt::MatchFixedString ) );
219 mFontColorButton->setColorDialogTitle( tr( "Font Color" ) );
220 mBufferColorButton->setColorDialogTitle( tr( "Buffer Color" ) );
221
222 disableGuiElements();
223
224 mDataDefinedProperties = layerSettings.dataDefinedProperties();
225
226 //set widget values from data defined results
227 setDataDefinedValues( vlayer );
228 //enable widgets connected to data defined fields
229 enableDataDefinedWidgets( vlayer );
230
231 blockElementSignals( false );
232 }
233
disableGuiElements()234 void QgsLabelPropertyDialog::disableGuiElements()
235 {
236 mShowLabelChkbx->setEnabled( false );
237 mAlwaysShowChkbx->setEnabled( false );
238 mShowCalloutChkbx->setEnabled( false );
239 mMinScaleWidget->setEnabled( false );
240 mMaxScaleWidget->setEnabled( false );
241 mFontFamilyCmbBx->setEnabled( false );
242 mFontStyleCmbBx->setEnabled( false );
243 mFontUnderlineBtn->setEnabled( false );
244 mFontStrikethroughBtn->setEnabled( false );
245 mFontBoldBtn->setEnabled( false );
246 mFontItalicBtn->setEnabled( false );
247 mFontSizeSpinBox->setEnabled( false );
248 mBufferSizeSpinBox->setEnabled( false );
249 mFontColorButton->setEnabled( false );
250 mBufferColorButton->setEnabled( false );
251 mBufferDrawChkbx->setEnabled( false );
252 mLabelDistanceSpinBox->setEnabled( false );
253 mXCoordSpinBox->setEnabled( false );
254 mYCoordSpinBox->setEnabled( false );
255 mMultiLineAlignComboBox->setEnabled( false );
256 mHaliComboBox->setEnabled( false );
257 mValiComboBox->setEnabled( false );
258 mRotationSpinBox->setEnabled( false );
259 mLabelAllPartsCheckBox->setEnabled( false );
260 }
261
blockElementSignals(bool block)262 void QgsLabelPropertyDialog::blockElementSignals( bool block )
263 {
264 mShowLabelChkbx->blockSignals( block );
265 mAlwaysShowChkbx->blockSignals( block );
266 mShowCalloutChkbx->blockSignals( block );
267 mMinScaleWidget->blockSignals( block );
268 mMaxScaleWidget->blockSignals( block );
269 mFontFamilyCmbBx->blockSignals( block );
270 mFontStyleCmbBx->blockSignals( block );
271 mFontUnderlineBtn->blockSignals( block );
272 mFontStrikethroughBtn->blockSignals( block );
273 mFontBoldBtn->blockSignals( block );
274 mFontItalicBtn->blockSignals( block );
275 mFontSizeSpinBox->blockSignals( block );
276 mBufferSizeSpinBox->blockSignals( block );
277 mFontColorButton->blockSignals( block );
278 mBufferColorButton->blockSignals( block );
279 mBufferDrawChkbx->blockSignals( block );
280 mLabelDistanceSpinBox->blockSignals( block );
281 mXCoordSpinBox->blockSignals( block );
282 mYCoordSpinBox->blockSignals( block );
283 mMultiLineAlignComboBox->blockSignals( block );
284 mHaliComboBox->blockSignals( block );
285 mValiComboBox->blockSignals( block );
286 mRotationSpinBox->blockSignals( block );
287 mLabelAllPartsCheckBox->blockSignals( block );
288 }
289
setDataDefinedValues(QgsVectorLayer * vlayer)290 void QgsLabelPropertyDialog::setDataDefinedValues( QgsVectorLayer *vlayer )
291 {
292 //loop through data defined properties and set all the GUI widget values. We can do this
293 //even if the data defined property is set to an expression, as it's useful to show
294 //users what the evaluated property is...
295
296 QgsExpressionContext context;
297 context << QgsExpressionContextUtils::globalScope()
298 << QgsExpressionContextUtils::projectScope( QgsProject::instance() )
299 << QgsExpressionContextUtils::atlasScope( nullptr )
300 << QgsExpressionContextUtils::mapSettingsScope( QgisApp::instance()->mapCanvas()->mapSettings() )
301 << QgsExpressionContextUtils::layerScope( vlayer );
302 context.setFeature( mCurLabelFeat );
303
304 const auto constPropertyKeys = mDataDefinedProperties.propertyKeys();
305 for ( int key : constPropertyKeys )
306 {
307 if ( !mDataDefinedProperties.isActive( key ) )
308 continue;
309
310 //TODO - pass expression context
311 QVariant result = mDataDefinedProperties.value( key, context );
312 if ( !result.isValid() || result.isNull() )
313 {
314 //could not evaluate data defined value
315 continue;
316 }
317
318 bool ok = false;
319 switch ( key )
320 {
321 case QgsPalLayerSettings::Show:
322 {
323 int showLabel = result.toInt( &ok );
324 mShowLabelChkbx->setChecked( !ok || showLabel != 0 );
325 break;
326 }
327 case QgsPalLayerSettings::AlwaysShow:
328 mAlwaysShowChkbx->setChecked( result.toBool() );
329 break;
330
331 case QgsPalLayerSettings::CalloutDraw:
332 mShowCalloutChkbx->setChecked( result.toBool() );
333 break;
334
335 case QgsPalLayerSettings::LabelAllParts:
336 mLabelAllPartsCheckBox->setChecked( result.toBool() );
337 break;
338
339 case QgsPalLayerSettings::MinimumScale:
340 {
341 double minScale = result.toDouble( &ok );
342 if ( ok )
343 {
344 mMinScaleWidget->setScale( minScale );
345 }
346 break;
347 }
348 case QgsPalLayerSettings::MaximumScale:
349 {
350 double maxScale = result.toDouble( &ok );
351 if ( ok )
352 {
353 mMaxScaleWidget->setScale( maxScale );
354 }
355 break;
356 }
357 case QgsPalLayerSettings::BufferSize:
358 {
359 double bufferSize = result.toDouble( &ok );
360 if ( ok )
361 {
362 mBufferSizeSpinBox->setValue( bufferSize );
363 }
364 break;
365 }
366 case QgsPalLayerSettings::PositionX:
367 {
368 double posX = result.toDouble( &ok );
369 if ( ok )
370 {
371 mXCoordSpinBox->setValue( posX );
372 }
373 break;
374 }
375 case QgsPalLayerSettings::PositionY:
376 {
377 double posY = result.toDouble( &ok );
378 if ( ok )
379 {
380 mYCoordSpinBox->setValue( posY );
381 }
382 break;
383 }
384 case QgsPalLayerSettings::LabelDistance:
385 {
386 double labelDist = result.toDouble( &ok );
387 if ( ok )
388 {
389 mLabelDistanceSpinBox->setValue( labelDist );
390 }
391 break;
392 }
393 case QgsPalLayerSettings::MultiLineAlignment:
394 mMultiLineAlignComboBox->setCurrentIndex( mMultiLineAlignComboBox->findData( result.toString(), Qt::UserRole, Qt::MatchFixedString ) );
395 break;
396 case QgsPalLayerSettings::Hali:
397 mHaliComboBox->setCurrentIndex( mHaliComboBox->findData( result.toString(), Qt::UserRole, Qt::MatchFixedString ) );
398 break;
399 case QgsPalLayerSettings::Vali:
400 mValiComboBox->setCurrentIndex( mValiComboBox->findData( result.toString(), Qt::UserRole, Qt::MatchFixedString ) );
401 break;
402 case QgsPalLayerSettings::BufferColor:
403 mBufferColorButton->setColor( QColor( result.toString() ) );
404 break;
405
406 case QgsPalLayerSettings::BufferDraw:
407 mBufferDrawChkbx->setChecked( result.toBool() );
408 break;
409
410 case QgsPalLayerSettings::Color:
411 mFontColorButton->setColor( QColor( result.toString() ) );
412 break;
413 case QgsPalLayerSettings::LabelRotation:
414 {
415 double rot = result.toDouble( &ok );
416 if ( ok )
417 {
418 mRotationSpinBox->setValue( rot );
419 }
420 break;
421 }
422
423 case QgsPalLayerSettings::Size:
424 {
425 double size = result.toDouble( &ok );
426 if ( ok )
427 {
428 mFontSizeSpinBox->setValue( size );
429 }
430 else
431 {
432 mFontSizeSpinBox->setValue( 0 );
433 }
434 break;
435 }
436 default:
437 break;
438 }
439 }
440 enableWidgetsForPinnedLabels();
441 }
442
enableDataDefinedWidgets(QgsVectorLayer * vlayer)443 void QgsLabelPropertyDialog::enableDataDefinedWidgets( QgsVectorLayer *vlayer )
444 {
445 //loop through data defined properties, this time setting whether or not the widgets are enabled
446 //this can only be done for properties which are assigned to fields
447 const auto constPropertyKeys = mDataDefinedProperties.propertyKeys();
448 for ( int key : constPropertyKeys )
449 {
450 QgsProperty prop = mDataDefinedProperties.property( key );
451 if ( !prop || !prop.isActive() || prop.propertyType() != QgsProperty::FieldBasedProperty )
452 {
453 continue; // can only modify attributes with an active data definition of a mapped field
454 }
455
456 QString ddField = prop.field();
457 if ( ddField.isEmpty() )
458 {
459 continue;
460 }
461
462 int ddIndx = vlayer->fields().lookupField( ddField );
463 if ( ddIndx == -1 )
464 {
465 continue;
466 }
467
468 QgsDebugMsg( QStringLiteral( "ddField: %1" ).arg( ddField ) );
469
470 switch ( key )
471 {
472 case QgsPalLayerSettings::Show:
473 mShowLabelChkbx->setEnabled( true );
474 break;
475 case QgsPalLayerSettings::AlwaysShow:
476 mAlwaysShowChkbx->setEnabled( true );
477 break;
478 case QgsPalLayerSettings::MinimumScale:
479 mMinScaleWidget->setEnabled( true );
480 break;
481 case QgsPalLayerSettings::MaximumScale:
482 mMaxScaleWidget->setEnabled( true );
483 break;
484 case QgsPalLayerSettings::BufferSize:
485 mBufferSizeSpinBox->setEnabled( true );
486 break;
487 case QgsPalLayerSettings::PositionX:
488 mXCoordSpinBox->setEnabled( true );
489 break;
490 case QgsPalLayerSettings::PositionY:
491 mYCoordSpinBox->setEnabled( true );
492 break;
493 case QgsPalLayerSettings::LabelDistance:
494 mLabelDistanceSpinBox->setEnabled( true );
495 break;
496 case QgsPalLayerSettings::MultiLineAlignment:
497 mMultiLineAlignComboBox->setEnabled( true );
498 break;
499 case QgsPalLayerSettings::Hali:
500 mCanSetHAlignment = true;
501 mHaliComboBox->setEnabled( mIsPinned );
502 break;
503 case QgsPalLayerSettings::Vali:
504 mCanSetVAlignment = true;
505 mValiComboBox->setEnabled( mIsPinned );
506 break;
507 case QgsPalLayerSettings::BufferColor:
508 mBufferColorButton->setEnabled( true );
509 break;
510 case QgsPalLayerSettings::BufferDraw:
511 mBufferDrawChkbx->setEnabled( true );
512 break;
513 case QgsPalLayerSettings::Color:
514 mFontColorButton->setEnabled( true );
515 break;
516 case QgsPalLayerSettings::LabelRotation:
517 mRotationSpinBox->setEnabled( true );
518 break;
519 //font related properties
520 case QgsPalLayerSettings::Family:
521 mFontFamilyCmbBx->setEnabled( true );
522 break;
523 case QgsPalLayerSettings::FontStyle:
524 mFontStyleCmbBx->setEnabled( true );
525 break;
526 case QgsPalLayerSettings::Underline:
527 mFontUnderlineBtn->setEnabled( true );
528 break;
529 case QgsPalLayerSettings::Strikeout:
530 mFontStrikethroughBtn->setEnabled( true );
531 break;
532 case QgsPalLayerSettings::Bold:
533 mFontBoldBtn->setEnabled( true );
534 break;
535 case QgsPalLayerSettings::Italic:
536 mFontItalicBtn->setEnabled( true );
537 break;
538 case QgsPalLayerSettings::Size:
539 mFontSizeSpinBox->setEnabled( true );
540 break;
541 case QgsPalLayerSettings::CalloutDraw:
542 mShowCalloutChkbx->setEnabled( true );
543 break;
544 case QgsPalLayerSettings::LabelAllParts:
545 mLabelAllPartsCheckBox->setEnabled( true );
546 break;
547 default:
548 break;
549 }
550 }
551 }
552
updateFont(const QFont & font,bool block)553 void QgsLabelPropertyDialog::updateFont( const QFont &font, bool block )
554 {
555 // update background reference font
556 if ( font != mLabelFont )
557 {
558 mLabelFont = font;
559 }
560
561 if ( block )
562 blockElementSignals( true );
563
564 mFontFamilyCmbBx->setCurrentFont( mLabelFont );
565 populateFontStyleComboBox();
566 mFontUnderlineBtn->setChecked( mLabelFont.underline() );
567 mFontStrikethroughBtn->setChecked( mLabelFont.strikeOut() );
568 mFontBoldBtn->setChecked( mLabelFont.bold() );
569 mFontItalicBtn->setChecked( mLabelFont.italic() );
570 if ( block )
571 blockElementSignals( false );
572 }
573
populateFontStyleComboBox()574 void QgsLabelPropertyDialog::populateFontStyleComboBox()
575 {
576 mFontStyleCmbBx->clear();
577 const auto constFamily = mFontDB.styles( mLabelFont.family() );
578 for ( const QString &style : constFamily )
579 {
580 mFontStyleCmbBx->addItem( style );
581 }
582
583 int curIndx = 0;
584 int stylIndx = mFontStyleCmbBx->findText( mFontDB.styleString( mLabelFont ) );
585 if ( stylIndx > -1 )
586 {
587 curIndx = stylIndx;
588 }
589
590 mFontStyleCmbBx->setCurrentIndex( curIndx );
591 }
592
fillMultiLineAlignComboBox()593 void QgsLabelPropertyDialog::fillMultiLineAlignComboBox()
594 {
595 mMultiLineAlignComboBox->addItem( tr( "Layer Default" ), "" );
596 mMultiLineAlignComboBox->addItem( tr( "Left" ), "Left" );
597 mMultiLineAlignComboBox->addItem( tr( "Center" ), "Center" );
598 mMultiLineAlignComboBox->addItem( tr( "Right" ), "Right" );
599 mMultiLineAlignComboBox->addItem( tr( "Justify" ), "Justify" );
600 }
601
fillHaliComboBox()602 void QgsLabelPropertyDialog::fillHaliComboBox()
603 {
604 mHaliComboBox->addItem( tr( "Left" ), "Left" );
605 mHaliComboBox->addItem( tr( "Center" ), "Center" );
606 mHaliComboBox->addItem( tr( "Right" ), "Right" );
607 }
608
fillValiComboBox()609 void QgsLabelPropertyDialog::fillValiComboBox()
610 {
611 mValiComboBox->addItem( tr( "Bottom" ), "Bottom" );
612 mValiComboBox->addItem( tr( "Base" ), "Base" );
613 mValiComboBox->addItem( tr( "Half" ), "Half" );
614 mValiComboBox->addItem( tr( "Cap" ), "Cap" );
615 mValiComboBox->addItem( tr( "Top" ), "Top" );
616 }
617
mShowLabelChkbx_toggled(bool chkd)618 void QgsLabelPropertyDialog::mShowLabelChkbx_toggled( bool chkd )
619 {
620 insertChangedValue( QgsPalLayerSettings::Show, ( chkd ? 1 : 0 ) );
621 }
622
mAlwaysShowChkbx_toggled(bool chkd)623 void QgsLabelPropertyDialog::mAlwaysShowChkbx_toggled( bool chkd )
624 {
625 insertChangedValue( QgsPalLayerSettings::AlwaysShow, ( chkd ? 1 : 0 ) );
626 }
627
labelAllPartsToggled(bool checked)628 void QgsLabelPropertyDialog::labelAllPartsToggled( bool checked )
629 {
630 insertChangedValue( QgsPalLayerSettings::LabelAllParts, ( checked ? 1 : 0 ) );
631 }
632
showCalloutToggled(bool chkd)633 void QgsLabelPropertyDialog::showCalloutToggled( bool chkd )
634 {
635 insertChangedValue( QgsPalLayerSettings::CalloutDraw, ( chkd ? 1 : 0 ) );
636 }
637
bufferDrawToggled(bool chkd)638 void QgsLabelPropertyDialog::bufferDrawToggled( bool chkd )
639 {
640 insertChangedValue( QgsPalLayerSettings::BufferDraw, ( chkd ? 1 : 0 ) );
641 }
642
minScaleChanged(double scale)643 void QgsLabelPropertyDialog::minScaleChanged( double scale )
644 {
645 insertChangedValue( QgsPalLayerSettings::MinimumScale, scale );
646 }
647
maxScaleChanged(double scale)648 void QgsLabelPropertyDialog::maxScaleChanged( double scale )
649 {
650 insertChangedValue( QgsPalLayerSettings::MaximumScale, scale );
651 }
652
mLabelDistanceSpinBox_valueChanged(double d)653 void QgsLabelPropertyDialog::mLabelDistanceSpinBox_valueChanged( double d )
654 {
655 QVariant distance( d );
656 if ( d < 0 )
657 {
658 //null value so that distance is reset to default
659 distance.clear();
660 }
661 insertChangedValue( QgsPalLayerSettings::LabelDistance, distance );
662 }
663
mXCoordSpinBox_valueChanged(double d)664 void QgsLabelPropertyDialog::mXCoordSpinBox_valueChanged( double d )
665 {
666 QVariant x( d );
667 if ( d < mXCoordSpinBox->minimum() + mXCoordSpinBox->singleStep() )
668 {
669 //null value
670 x.clear();
671 }
672
673 insertChangedValue( QgsPalLayerSettings::PositionX, x );
674 enableWidgetsForPinnedLabels();
675 }
676
mYCoordSpinBox_valueChanged(double d)677 void QgsLabelPropertyDialog::mYCoordSpinBox_valueChanged( double d )
678 {
679 QVariant y( d );
680 if ( d < mYCoordSpinBox->minimum() + mYCoordSpinBox->singleStep() )
681 {
682 //null value
683 y.clear();
684 }
685 insertChangedValue( QgsPalLayerSettings::PositionY, y );
686 enableWidgetsForPinnedLabels();
687 }
688
mFontFamilyCmbBx_currentFontChanged(const QFont & f)689 void QgsLabelPropertyDialog::mFontFamilyCmbBx_currentFontChanged( const QFont &f )
690 {
691 mLabelFont.setFamily( f.family() );
692 updateFont( mLabelFont );
693 insertChangedValue( QgsPalLayerSettings::Family, f.family() );
694 }
695
mFontStyleCmbBx_currentIndexChanged(const QString & text)696 void QgsLabelPropertyDialog::mFontStyleCmbBx_currentIndexChanged( const QString &text )
697 {
698 QgsFontUtils::updateFontViaStyle( mLabelFont, text );
699 updateFont( mLabelFont );
700 insertChangedValue( QgsPalLayerSettings::FontStyle, text );
701 }
702
mFontUnderlineBtn_toggled(bool ckd)703 void QgsLabelPropertyDialog::mFontUnderlineBtn_toggled( bool ckd )
704 {
705 mLabelFont.setUnderline( ckd );
706 updateFont( mLabelFont );
707 insertChangedValue( QgsPalLayerSettings::Underline, ckd );
708 }
709
mFontStrikethroughBtn_toggled(bool ckd)710 void QgsLabelPropertyDialog::mFontStrikethroughBtn_toggled( bool ckd )
711 {
712 mLabelFont.setStrikeOut( ckd );
713 updateFont( mLabelFont );
714 insertChangedValue( QgsPalLayerSettings::Strikeout, ckd );
715 }
716
mFontBoldBtn_toggled(bool ckd)717 void QgsLabelPropertyDialog::mFontBoldBtn_toggled( bool ckd )
718 {
719 mLabelFont.setBold( ckd );
720 updateFont( mLabelFont );
721 insertChangedValue( QgsPalLayerSettings::Bold, ckd );
722 }
723
mFontItalicBtn_toggled(bool ckd)724 void QgsLabelPropertyDialog::mFontItalicBtn_toggled( bool ckd )
725 {
726 mLabelFont.setItalic( ckd );
727 updateFont( mLabelFont );
728 insertChangedValue( QgsPalLayerSettings::Italic, ckd );
729 }
730
mFontSizeSpinBox_valueChanged(double d)731 void QgsLabelPropertyDialog::mFontSizeSpinBox_valueChanged( double d )
732 {
733 QVariant size( d );
734 if ( d <= 0 )
735 {
736 //null value so that font size is reset to default
737 size.clear();
738 }
739 insertChangedValue( QgsPalLayerSettings::Size, size );
740 }
741
mBufferSizeSpinBox_valueChanged(double d)742 void QgsLabelPropertyDialog::mBufferSizeSpinBox_valueChanged( double d )
743 {
744 QVariant size( d );
745 if ( d < 0 )
746 {
747 //null value so that size is reset to default
748 size.clear();
749 }
750 insertChangedValue( QgsPalLayerSettings::BufferSize, size );
751 }
752
mRotationSpinBox_valueChanged(double d)753 void QgsLabelPropertyDialog::mRotationSpinBox_valueChanged( double d )
754 {
755 QVariant rotation( d );
756 if ( d < 0 )
757 {
758 //null value so that size is reset to default
759 rotation.clear();
760 }
761 insertChangedValue( QgsPalLayerSettings::LabelRotation, rotation );
762 }
763
mFontColorButton_colorChanged(const QColor & color)764 void QgsLabelPropertyDialog::mFontColorButton_colorChanged( const QColor &color )
765 {
766 insertChangedValue( QgsPalLayerSettings::Color, color.name() );
767 }
768
mBufferColorButton_colorChanged(const QColor & color)769 void QgsLabelPropertyDialog::mBufferColorButton_colorChanged( const QColor &color )
770 {
771 insertChangedValue( QgsPalLayerSettings::BufferColor, color.name() );
772 }
773
mMultiLineAlignComboBox_currentIndexChanged(const int index)774 void QgsLabelPropertyDialog::mMultiLineAlignComboBox_currentIndexChanged( const int index )
775 {
776 insertChangedValue( QgsPalLayerSettings::MultiLineAlignment, mMultiLineAlignComboBox->itemData( index ) );
777 }
778
mHaliComboBox_currentIndexChanged(const int index)779 void QgsLabelPropertyDialog::mHaliComboBox_currentIndexChanged( const int index )
780 {
781 insertChangedValue( QgsPalLayerSettings::Hali, mHaliComboBox->itemData( index ) );
782 }
783
mValiComboBox_currentIndexChanged(const int index)784 void QgsLabelPropertyDialog::mValiComboBox_currentIndexChanged( const int index )
785 {
786 insertChangedValue( QgsPalLayerSettings::Vali, mValiComboBox->itemData( index ) );
787 }
788
mLabelTextLineEdit_textChanged(const QString & text)789 void QgsLabelPropertyDialog::mLabelTextLineEdit_textChanged( const QString &text )
790 {
791 if ( mCurLabelField != -1 )
792 {
793 mChangedProperties.insert( mCurLabelField, text );
794 }
795 }
796
insertChangedValue(QgsPalLayerSettings::Property p,const QVariant & value)797 void QgsLabelPropertyDialog::insertChangedValue( QgsPalLayerSettings::Property p, const QVariant &value )
798 {
799 if ( mDataDefinedProperties.isActive( p ) )
800 {
801 QgsProperty prop = mDataDefinedProperties.property( p );
802 if ( prop.propertyType() == QgsProperty::FieldBasedProperty )
803 {
804 mChangedProperties.insert( mCurLabelFeat.fieldNameIndex( prop.field() ), value );
805 }
806 }
807 }
808
enableWidgetsForPinnedLabels()809 void QgsLabelPropertyDialog::enableWidgetsForPinnedLabels()
810 {
811 const bool pinned = mXCoordSpinBox->value() >= ( mXCoordSpinBox->minimum() + mXCoordSpinBox->singleStep() ) &&
812 mYCoordSpinBox->value() >= ( mYCoordSpinBox->minimum() + mYCoordSpinBox->singleStep() );
813
814 mHaliComboBox->setEnabled( pinned && mCanSetHAlignment );
815 mValiComboBox->setEnabled( pinned && mCanSetVAlignment );
816
817 if ( !pinned )
818 {
819 mHaliComboBox->setToolTip( tr( "Alignment can only be set for pinned labels" ) );
820 mValiComboBox->setToolTip( tr( "Alignment can only be set for pinned labels" ) );
821 }
822 else
823 {
824 mHaliComboBox->setToolTip( QString() );
825 mValiComboBox->setToolTip( QString() );
826 }
827 }
828
showHelp()829 void QgsLabelPropertyDialog::showHelp()
830 {
831 QgsHelp::openHelp( QStringLiteral( "working_with_vector/vector_properties.html#the-label-toolbar" ) );
832 }
833