QGIS API Documentation  3.17.0-Master (a035f434f4)
qgssymbollayerwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgssymbollayerwidget.cpp - symbol layer widgets
3 
4  ---------------------
5  begin : November 2009
6  copyright : (C) 2009 by Martin Dobias
7  email : wonder dot sk at gmail dot com
8  ***************************************************************************
9  * *
10  * This program is free software; you can redistribute it and/or modify *
11  * it under the terms of the GNU General Public License as published by *
12  * the Free Software Foundation; either version 2 of the License, or *
13  * (at your option) any later version. *
14  * *
15  ***************************************************************************/
16 
17 #include "qgssymbollayerwidget.h"
18 
19 #include "qgsdataitem.h"
20 #include "qgslinesymbollayer.h"
21 #include "qgsmarkersymbollayer.h"
22 #include "qgsfillsymbollayer.h"
24 #include "qgssymbolslistwidget.h"
26 
27 #include "characterwidget.h"
28 #include "qgsdashspacedialog.h"
30 #include "qgssvgcache.h"
31 #include "qgssymbollayerutils.h"
32 #include "qgscolorramp.h"
33 #include "qgscolorrampbutton.h"
34 #include "qgsfontutils.h"
36 #include "qgsproperty.h"
37 #include "qgsstyle.h" //for symbol selector dialog
38 #include "qgsmapcanvas.h"
39 #include "qgsapplication.h"
40 #include "qgsvectorlayer.h"
41 #include "qgssvgselectorwidget.h"
42 #include "qgslogger.h"
43 #include "qgssettings.h"
46 #include "qgsauxiliarystorage.h"
47 #include "qgsimagecache.h"
48 
49 #include <QAbstractButton>
50 #include <QButtonGroup>
51 #include <QColorDialog>
52 #include <QCursor>
53 #include <QDir>
54 #include <QFileDialog>
55 #include <QPainter>
56 #include <QStandardItemModel>
57 #include <QSvgRenderer>
58 #include <QMessageBox>
59 #include <QMenu>
60 #include <QAction>
61 #include <QInputDialog>
62 
64 {
65  if ( auto *lExpressionContext = mContext.expressionContext() )
66  return *lExpressionContext;
67 
69 
71  if ( const QgsSymbolLayer *symbolLayer = const_cast< QgsSymbolLayerWidget * >( this )->symbolLayer() )
72  {
73  //cheat a bit - set the symbol color variable to match the symbol layer's color (when we should really be using the *symbols*
74  //color, but that's not accessible here). 99% of the time these will be the same anyway
76  }
77  expContext << symbolScope;
78  expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_COUNT, 1, true ) );
79  expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, 1, true ) );
80  expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_POINT_COUNT, 1, true ) );
81  expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_POINT_NUM, 1, true ) );
82  expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "symbol_layer_count" ), 1, true ) );
83  expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "symbol_layer_index" ), 1, true ) );
84  expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "symbol_marker_row" ), 1, true ) );
85  expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "symbol_marker_column" ), 1, true ) );
86 
87  // additional scopes
88  const auto constAdditionalExpressionContextScopes = mContext.additionalExpressionContextScopes();
89  for ( const QgsExpressionContextScope &scope : constAdditionalExpressionContextScopes )
90  {
91  expContext.appendScope( new QgsExpressionContextScope( scope ) );
92  }
93 
94  //TODO - show actual value
95  expContext.setOriginalValueVariable( QVariant() );
96 
97  QStringList highlights;
102  << QStringLiteral( "symbol_layer_count" ) << QStringLiteral( "symbol_layer_index" );
103 
104 
105  if ( expContext.hasVariable( QStringLiteral( "zoom_level" ) ) )
106  {
107  highlights << QStringLiteral( "zoom_level" );
108  }
109  if ( expContext.hasVariable( QStringLiteral( "vector_tile_zoom" ) ) )
110  {
111  highlights << QStringLiteral( "vector_tile_zoom" );
112  }
113 
114  expContext.setHighlightedVariables( highlights );
115 
116  return expContext;
117 }
118 
120 {
121  mContext = context;
122  const auto unitSelectionWidgets = findChildren<QgsUnitSelectionWidget *>();
123  for ( QgsUnitSelectionWidget *unitWidget : unitSelectionWidgets )
124  {
125  unitWidget->setMapCanvas( mContext.mapCanvas() );
126  }
127 }
128 
130 {
131  return mContext;
132 }
133 
135 {
136  button->init( key, symbolLayer()->dataDefinedProperties(), QgsSymbolLayer::propertyDefinitions(), mVectorLayer, true );
138  connect( button, &QgsPropertyOverrideButton::createAuxiliaryField, this, &QgsSymbolLayerWidget::createAuxiliaryField );
139 
140  button->registerExpressionContextGenerator( this );
141 }
142 
143 void QgsSymbolLayerWidget::createAuxiliaryField()
144 {
145  // try to create an auxiliary layer if not yet created
146  if ( !mVectorLayer->auxiliaryLayer() )
147  {
148  QgsNewAuxiliaryLayerDialog dlg( mVectorLayer, this );
149  dlg.exec();
150  }
151 
152  // return if still not exists
153  if ( !mVectorLayer->auxiliaryLayer() )
154  return;
155 
156  QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
157  QgsSymbolLayer::Property key = static_cast< QgsSymbolLayer::Property >( button->propertyKey() );
159 
160  // create property in auxiliary storage if necessary
161  if ( !mVectorLayer->auxiliaryLayer()->exists( def ) )
162  {
163  QgsNewAuxiliaryFieldDialog dlg( def, mVectorLayer, true, this );
164  if ( dlg.exec() == QDialog::Accepted )
165  def = dlg.propertyDefinition();
166  }
167 
168  // return if still not exist
169  if ( !mVectorLayer->auxiliaryLayer()->exists( def ) )
170  return;
171 
172  // update property with join field name from auxiliary storage
173  QgsProperty property = button->toProperty();
174  property.setField( QgsAuxiliaryLayer::nameFromProperty( def, true ) );
175  property.setActive( true );
176  button->updateFieldLists();
177  button->setToProperty( property );
178  symbolLayer()->setDataDefinedProperty( key, button->toProperty() );
179 
180  emit changed();
181 }
182 
184 {
185  QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
186  QgsSymbolLayer::Property key = static_cast< QgsSymbolLayer::Property >( button->propertyKey() );
187  symbolLayer()->setDataDefinedProperty( key, button->toProperty() );
188  emit changed();
189 }
190 
192  : QgsSymbolLayerWidget( parent, vl )
193 {
194  mLayer = nullptr;
195 
196  setupUi( this );
197  connect( mCustomCheckBox, &QCheckBox::stateChanged, this, &QgsSimpleLineSymbolLayerWidget::mCustomCheckBox_stateChanged );
198  connect( mChangePatternButton, &QPushButton::clicked, this, &QgsSimpleLineSymbolLayerWidget::mChangePatternButton_clicked );
199  connect( mPenWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::mPenWidthUnitWidget_changed );
200  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::mOffsetUnitWidget_changed );
201  connect( mDashPatternUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::mDashPatternUnitWidget_changed );
202  connect( mDrawInsideCheckBox, &QCheckBox::stateChanged, this, &QgsSimpleLineSymbolLayerWidget::mDrawInsideCheckBox_stateChanged );
203  connect( mPatternOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::patternOffsetUnitChanged );
204  connect( mCheckAlignDash, &QCheckBox::toggled, this, [ = ]
205  {
206  mCheckDashCorners->setEnabled( mCheckAlignDash->isChecked() );
207  if ( !mCheckAlignDash->isChecked() )
208  mCheckDashCorners->setChecked( false );
209 
210  if ( mLayer )
211  {
212  mLayer->setAlignDashPattern( mCheckAlignDash->isChecked() );
213  emit changed();
214  }
215  } );
216  connect( mCheckDashCorners, &QCheckBox::toggled, this, [ = ]
217  {
218  if ( mLayer )
219  {
220  mLayer->setTweakDashPatternOnCorners( mCheckDashCorners->isChecked() );
221  emit changed();
222  }
223  } );
224 
233 
234  btnChangeColor->setAllowOpacity( true );
235  btnChangeColor->setColorDialogTitle( tr( "Select Line Color" ) );
236  btnChangeColor->setContext( QStringLiteral( "symbology" ) );
237 
238  mColorDDBtn->registerLinkedWidget( btnChangeColor );
239 
240  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconAllRings.svg" ) ), tr( "All Rings" ), QgsLineSymbolLayer::AllRings );
241  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconExteriorRing.svg" ) ), tr( "Exterior Ring Only" ), QgsLineSymbolLayer::ExteriorRingOnly );
242  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconInteriorRings.svg" ) ), tr( "Interior Rings Only" ), QgsLineSymbolLayer::InteriorRingsOnly );
243  connect( mRingFilterComboBox, qgis::overload< int >::of( &QComboBox::currentIndexChanged ), this, [ = ]( int )
244  {
245  if ( mLayer )
246  {
247  mLayer->setRingFilter( static_cast< QgsLineSymbolLayer::RenderRingFilter >( mRingFilterComboBox->currentData().toInt() ) );
248  emit changed();
249  }
250  } );
251 
252  spinOffset->setClearValue( 0.0 );
253  spinPatternOffset->setClearValue( 0.0 );
254 
255  if ( vl && vl->geometryType() != QgsWkbTypes::PolygonGeometry )
256  {
257  //draw inside polygon checkbox only makes sense for polygon layers
258  mDrawInsideCheckBox->hide();
259  mRingFilterComboBox->hide();
260  mRingsLabel->hide();
261  }
262 
263  //make a temporary symbol for the size assistant preview
264  mAssistantPreviewSymbol.reset( new QgsLineSymbol() );
265 
266  if ( vectorLayer() )
267  mPenWidthDDBtn->setSymbol( mAssistantPreviewSymbol );
268 
269  connect( spinWidth, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleLineSymbolLayerWidget::penWidthChanged );
270  connect( btnChangeColor, &QgsColorButton::colorChanged, this, &QgsSimpleLineSymbolLayerWidget::colorChanged );
271  connect( cboPenStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleLineSymbolLayerWidget::penStyleChanged );
272  connect( spinOffset, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleLineSymbolLayerWidget::offsetChanged );
273  connect( cboCapStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleLineSymbolLayerWidget::penStyleChanged );
274  connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleLineSymbolLayerWidget::penStyleChanged );
275  connect( spinPatternOffset, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleLineSymbolLayerWidget::patternOffsetChanged );
276 
278 
279  connect( this, &QgsSymbolLayerWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::updateAssistantSymbol );
280 }
281 
282 void QgsSimpleLineSymbolLayerWidget::updateAssistantSymbol()
283 {
284  for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
285  {
286  mAssistantPreviewSymbol->deleteSymbolLayer( i );
287  }
288  mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
290  if ( ddWidth )
291  mAssistantPreviewSymbol->setDataDefinedWidth( ddWidth );
292 }
293 
294 
296 {
297  if ( !layer || layer->layerType() != QLatin1String( "SimpleLine" ) )
298  return;
299 
300  // layer type is correct, we can do the cast
301  mLayer = static_cast<QgsSimpleLineSymbolLayer *>( layer );
302 
303  // set units
304  mPenWidthUnitWidget->blockSignals( true );
305  mPenWidthUnitWidget->setUnit( mLayer->widthUnit() );
306  mPenWidthUnitWidget->setMapUnitScale( mLayer->widthMapUnitScale() );
307  mPenWidthUnitWidget->blockSignals( false );
308  mOffsetUnitWidget->blockSignals( true );
309  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
310  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
311  mOffsetUnitWidget->blockSignals( false );
312  mDashPatternUnitWidget->blockSignals( true );
313  mDashPatternUnitWidget->setUnit( mLayer->customDashPatternUnit() );
314  mDashPatternUnitWidget->setMapUnitScale( mLayer->customDashPatternMapUnitScale() );
315  mDashPatternUnitWidget->blockSignals( false );
316 
317  whileBlocking( mPatternOffsetUnitWidget )->setUnit( mLayer->dashPatternOffsetUnit() );
318  whileBlocking( mPatternOffsetUnitWidget )->setMapUnitScale( mLayer->dashPatternOffsetMapUnitScale() );
319 
320  // set values
321  spinWidth->blockSignals( true );
322  spinWidth->setValue( mLayer->width() );
323  spinWidth->blockSignals( false );
324  btnChangeColor->blockSignals( true );
325  btnChangeColor->setColor( mLayer->color() );
326  btnChangeColor->blockSignals( false );
327  spinOffset->blockSignals( true );
328  spinOffset->setValue( mLayer->offset() );
329  spinOffset->blockSignals( false );
330  cboPenStyle->blockSignals( true );
331  cboJoinStyle->blockSignals( true );
332  cboCapStyle->blockSignals( true );
333  cboPenStyle->setPenStyle( mLayer->penStyle() );
334  cboJoinStyle->setPenJoinStyle( mLayer->penJoinStyle() );
335  cboCapStyle->setPenCapStyle( mLayer->penCapStyle() );
336  cboPenStyle->blockSignals( false );
337  cboJoinStyle->blockSignals( false );
338  cboCapStyle->blockSignals( false );
339  whileBlocking( spinPatternOffset )->setValue( mLayer->dashPatternOffset() );
340 
341  //use a custom dash pattern?
342  bool useCustomDashPattern = mLayer->useCustomDashPattern();
343  mChangePatternButton->setEnabled( useCustomDashPattern );
344  label_3->setEnabled( !useCustomDashPattern );
345  cboPenStyle->setEnabled( !useCustomDashPattern );
346  mCustomCheckBox->blockSignals( true );
347  mCustomCheckBox->setCheckState( useCustomDashPattern ? Qt::Checked : Qt::Unchecked );
348  mCustomCheckBox->blockSignals( false );
349 
350  //make sure height of custom dash button looks good under different platforms
351  QSize size = mChangePatternButton->minimumSizeHint();
352  int fontHeight = static_cast< int >( Qgis::UI_SCALE_FACTOR * fontMetrics().height() * 1.4 );
353  mChangePatternButton->setMinimumSize( QSize( size.width(), std::max( size.height(), fontHeight ) ) );
354 
355  //draw inside polygon?
356  const bool drawInsidePolygon = mLayer->drawInsidePolygon();
357  whileBlocking( mDrawInsideCheckBox )->setCheckState( drawInsidePolygon ? Qt::Checked : Qt::Unchecked );
358 
359  whileBlocking( mRingFilterComboBox )->setCurrentIndex( mRingFilterComboBox->findData( mLayer->ringFilter() ) );
360 
361  whileBlocking( mCheckAlignDash )->setChecked( mLayer->alignDashPattern() );
362  mCheckDashCorners->setEnabled( mLayer->alignDashPattern() );
363  whileBlocking( mCheckDashCorners )->setChecked( mLayer->tweakDashPatternOnCorners() && mLayer->alignDashPattern() );
364 
366 
375 
376  updateAssistantSymbol();
377 }
378 
380 {
381  return mLayer;
382 }
383 
384 void QgsSimpleLineSymbolLayerWidget::penWidthChanged()
385 {
386  mLayer->setWidth( spinWidth->value() );
388  emit changed();
389 }
390 
391 void QgsSimpleLineSymbolLayerWidget::colorChanged( const QColor &color )
392 {
393  mLayer->setColor( color );
394  emit changed();
395 }
396 
397 void QgsSimpleLineSymbolLayerWidget::penStyleChanged()
398 {
399  mLayer->setPenStyle( cboPenStyle->penStyle() );
400  mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
401  mLayer->setPenCapStyle( cboCapStyle->penCapStyle() );
403  emit changed();
404 }
405 
406 void QgsSimpleLineSymbolLayerWidget::offsetChanged()
407 {
408  mLayer->setOffset( spinOffset->value() );
410  emit changed();
411 }
412 
413 void QgsSimpleLineSymbolLayerWidget::patternOffsetChanged()
414 {
415  mLayer->setDashPatternOffset( spinPatternOffset->value() );
417  emit changed();
418 }
419 
420 void QgsSimpleLineSymbolLayerWidget::mCustomCheckBox_stateChanged( int state )
421 {
422  bool checked = ( state == Qt::Checked );
423  mChangePatternButton->setEnabled( checked );
424  label_3->setEnabled( !checked );
425  cboPenStyle->setEnabled( !checked );
426 
427  mLayer->setUseCustomDashPattern( checked );
428  emit changed();
429 }
430 
431 void QgsSimpleLineSymbolLayerWidget::mChangePatternButton_clicked()
432 {
434  if ( panel && panel->dockMode() )
435  {
437  widget->setPanelTitle( tr( "Custom Dash Pattern" ) );
438  widget->setUnit( mDashPatternUnitWidget->unit() );
439  connect( widget, &QgsPanelWidget::widgetChanged, this, [ this, widget ]()
440  {
443  } );
445  panel->openPanel( widget );
446  return;
447  }
448 
450  d.setUnit( mDashPatternUnitWidget->unit() );
451  if ( d.exec() == QDialog::Accepted )
452  {
453  mLayer->setCustomDashVector( d.dashDotVector() );
455  emit changed();
456  }
457 }
458 
459 void QgsSimpleLineSymbolLayerWidget::mPenWidthUnitWidget_changed()
460 {
461  if ( mLayer )
462  {
463  mLayer->setWidthUnit( mPenWidthUnitWidget->unit() );
464  mLayer->setWidthMapUnitScale( mPenWidthUnitWidget->getMapUnitScale() );
466  emit changed();
467  }
468 }
469 
470 void QgsSimpleLineSymbolLayerWidget::mOffsetUnitWidget_changed()
471 {
472  if ( mLayer )
473  {
474  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
475  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
476  emit changed();
477  }
478 }
479 
480 void QgsSimpleLineSymbolLayerWidget::mDashPatternUnitWidget_changed()
481 {
482  if ( mLayer )
483  {
484  mLayer->setCustomDashPatternUnit( mDashPatternUnitWidget->unit() );
485  mLayer->setCustomDashPatternMapUnitScale( mDashPatternUnitWidget->getMapUnitScale() );
487  emit changed();
488  }
489 }
490 
491 void QgsSimpleLineSymbolLayerWidget::mDrawInsideCheckBox_stateChanged( int state )
492 {
493  bool checked = ( state == Qt::Checked );
494  mLayer->setDrawInsidePolygon( checked );
495  emit changed();
496 }
497 
498 void QgsSimpleLineSymbolLayerWidget::patternOffsetUnitChanged()
499 {
500  if ( mLayer )
501  {
502  mLayer->setDashPatternOffsetUnit( mPatternOffsetUnitWidget->unit() );
503  mLayer->setDashPatternOffsetMapUnitScale( mPatternOffsetUnitWidget->getMapUnitScale() );
505  emit changed();
506  }
507 }
508 
510 {
511  if ( !mLayer )
512  {
513  return;
514  }
515  std::unique_ptr< QgsSimpleLineSymbolLayer > layerCopy( mLayer->clone() );
516  if ( !layerCopy )
517  {
518  return;
519  }
520  QColor color = qApp->palette().color( QPalette::WindowText );
521  layerCopy->setColor( color );
522  // reset offset, we don't want to show that in the preview
523  layerCopy->setOffset( 0 );
524  layerCopy->setUseCustomDashPattern( true );
525 
526  QSize currentIconSize;
527  //icon size is button size with a small margin
528 #ifdef Q_OS_WIN
529  currentIconSize = QSize( mChangePatternButton->width() - 10, mChangePatternButton->height() - 6 );
530 #else
531  currentIconSize = QSize( mChangePatternButton->width() - 10, mChangePatternButton->height() - 12 );
532 #endif
533 
534  if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 )
535  {
536  return;
537  }
538 
539  //create an icon pixmap
540  std::unique_ptr< QgsLineSymbol > previewSymbol = qgis::make_unique< QgsLineSymbol >( QgsSymbolLayerList() << layerCopy.release() );
541  const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( previewSymbol.get(), currentIconSize );
542  mChangePatternButton->setIconSize( currentIconSize );
543  mChangePatternButton->setIcon( icon );
544 
545  // set tooltip
546  // create very large preview image
547 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
548  int width = static_cast< int >( Qgis::UI_SCALE_FACTOR * fontMetrics().width( 'X' ) * 23 );
549 #else
550  int width = static_cast< int >( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 23 );
551 #endif
552  int height = static_cast< int >( width / 1.61803398875 ); // golden ratio
553 
554  QPixmap pm = QgsSymbolLayerUtils::symbolPreviewPixmap( previewSymbol.get(), QSize( width, height ), height / 20 );
555  QByteArray data;
556  QBuffer buffer( &data );
557  pm.save( &buffer, "PNG", 100 );
558  mChangePatternButton->setToolTip( QStringLiteral( "<img src='data:image/png;base64, %3'>" ).arg( QString( data.toBase64() ) ) );
559 }
560 
562 {
563  QgsSymbolLayerWidget::resizeEvent( event );
564  // redraw custom dash pattern icon -- the button size has changed
566 }
567 
568 
570 
571 
573  : QgsSymbolLayerWidget( parent, vl )
574 {
575  mLayer = nullptr;
576 
577  setupUi( this );
578  connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
579  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
580  connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
581  connect( mStrokeStyleComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mStrokeStyleComboBox_currentIndexChanged );
582  connect( mStrokeWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
583  connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
584  connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
591 
592  btnChangeColorFill->setAllowOpacity( true );
593  btnChangeColorFill->setColorDialogTitle( tr( "Select Fill Color" ) );
594  btnChangeColorFill->setContext( QStringLiteral( "symbology" ) );
595  btnChangeColorFill->setShowNoColor( true );
596  btnChangeColorFill->setNoColorString( tr( "Transparent Fill" ) );
597  btnChangeColorStroke->setAllowOpacity( true );
598  btnChangeColorStroke->setColorDialogTitle( tr( "Select Stroke Color" ) );
599  btnChangeColorStroke->setContext( QStringLiteral( "symbology" ) );
600  btnChangeColorStroke->setShowNoColor( true );
601  btnChangeColorStroke->setNoColorString( tr( "Transparent Stroke" ) );
602 
603  mFillColorDDBtn->registerLinkedWidget( btnChangeColorFill );
604  mStrokeColorDDBtn->registerLinkedWidget( btnChangeColorStroke );
605 
606  spinOffsetX->setClearValue( 0.0 );
607  spinOffsetY->setClearValue( 0.0 );
608  spinAngle->setClearValue( 0.0 );
609 
610  //make a temporary symbol for the size assistant preview
611  mAssistantPreviewSymbol.reset( new QgsMarkerSymbol() );
612 
613  if ( vectorLayer() )
614  mSizeDDBtn->setSymbol( mAssistantPreviewSymbol );
615 
616  int size = lstNames->iconSize().width();
617 
618 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
619  size = std::max( 30, static_cast< int >( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().width( 'X' ) * 3 ) ) );
620 #else
621  size = std::max( 30, static_cast< int >( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 3 ) ) );
622 #endif
623 
624  lstNames->setGridSize( QSize( size * 1.2, size * 1.2 ) );
625  lstNames->setIconSize( QSize( size, size ) );
626 
627  double markerSize = size * 0.8;
629  for ( QgsSimpleMarkerSymbolLayerBase::Shape shape : shapes )
630  {
631  QgsSimpleMarkerSymbolLayer *lyr = new QgsSimpleMarkerSymbolLayer( shape, markerSize );
633  lyr->setColor( QColor( 200, 200, 200 ) );
634  lyr->setStrokeColor( QColor( 0, 0, 0 ) );
635  QIcon icon = QgsSymbolLayerUtils::symbolLayerPreviewIcon( lyr, QgsUnitTypes::RenderPixels, QSize( size, size ) );
636  QListWidgetItem *item = new QListWidgetItem( icon, QString(), lstNames );
637  item->setData( Qt::UserRole, static_cast< int >( shape ) );
638  item->setToolTip( QgsSimpleMarkerSymbolLayerBase::encodeShape( shape ) );
639  delete lyr;
640  }
641  // show at least 3 rows
642  lstNames->setMinimumHeight( lstNames->gridSize().height() * 3.1 );
643 
644  connect( lstNames, &QListWidget::currentRowChanged, this, &QgsSimpleMarkerSymbolLayerWidget::setShape );
645  connect( btnChangeColorStroke, &QgsColorButton::colorChanged, this, &QgsSimpleMarkerSymbolLayerWidget::setColorStroke );
647  connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::penJoinStyleChanged );
648  connect( spinSize, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setSize );
649  connect( spinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setAngle );
650  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setOffset );
651  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setOffset );
652  connect( this, &QgsSymbolLayerWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::updateAssistantSymbol );
653 }
654 
656 {
657  if ( layer->layerType() != QLatin1String( "SimpleMarker" ) )
658  return;
659 
660  // layer type is correct, we can do the cast
661  mLayer = static_cast<QgsSimpleMarkerSymbolLayer *>( layer );
662 
663  // set values
665  for ( int i = 0; i < lstNames->count(); ++i )
666  {
667  if ( static_cast< QgsSimpleMarkerSymbolLayerBase::Shape >( lstNames->item( i )->data( Qt::UserRole ).toInt() ) == shape )
668  {
669  lstNames->setCurrentRow( i );
670  break;
671  }
672  }
673  btnChangeColorStroke->blockSignals( true );
674  btnChangeColorStroke->setColor( mLayer->strokeColor() );
675  btnChangeColorStroke->blockSignals( false );
676  btnChangeColorFill->blockSignals( true );
677  btnChangeColorFill->setColor( mLayer->fillColor() );
678  btnChangeColorFill->setEnabled( QgsSimpleMarkerSymbolLayerBase::shapeIsFilled( mLayer->shape() ) );
679  btnChangeColorFill->blockSignals( false );
680  spinSize->blockSignals( true );
681  spinSize->setValue( mLayer->size() );
682  spinSize->blockSignals( false );
683  spinAngle->blockSignals( true );
684  spinAngle->setValue( mLayer->angle() );
685  spinAngle->blockSignals( false );
686  mStrokeStyleComboBox->blockSignals( true );
687  mStrokeStyleComboBox->setPenStyle( mLayer->strokeStyle() );
688  mStrokeStyleComboBox->blockSignals( false );
689  mStrokeWidthSpinBox->blockSignals( true );
690  mStrokeWidthSpinBox->setValue( mLayer->strokeWidth() );
691  mStrokeWidthSpinBox->blockSignals( false );
692  cboJoinStyle->blockSignals( true );
693  cboJoinStyle->setPenJoinStyle( mLayer->penJoinStyle() );
694  cboJoinStyle->blockSignals( false );
695 
696  // without blocking signals the value gets changed because of slot setOffset()
697  spinOffsetX->blockSignals( true );
698  spinOffsetX->setValue( mLayer->offset().x() );
699  spinOffsetX->blockSignals( false );
700  spinOffsetY->blockSignals( true );
701  spinOffsetY->setValue( mLayer->offset().y() );
702  spinOffsetY->blockSignals( false );
703 
704  mSizeUnitWidget->blockSignals( true );
705  mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
706  mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
707  mSizeUnitWidget->blockSignals( false );
708  mOffsetUnitWidget->blockSignals( true );
709  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
710  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
711  mOffsetUnitWidget->blockSignals( false );
712  mStrokeWidthUnitWidget->blockSignals( true );
713  mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
714  mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
715  mStrokeWidthUnitWidget->blockSignals( false );
716 
717  //anchor points
718  mHorizontalAnchorComboBox->blockSignals( true );
719  mVerticalAnchorComboBox->blockSignals( true );
720  mHorizontalAnchorComboBox->setCurrentIndex( mLayer->horizontalAnchorPoint() );
721  mVerticalAnchorComboBox->setCurrentIndex( mLayer->verticalAnchorPoint() );
722  mHorizontalAnchorComboBox->blockSignals( false );
723  mVerticalAnchorComboBox->blockSignals( false );
724 
736 
737  updateAssistantSymbol();
738 }
739 
741 {
742  return mLayer;
743 }
744 
745 void QgsSimpleMarkerSymbolLayerWidget::setShape()
746 {
747  mLayer->setShape( static_cast< QgsSimpleMarkerSymbolLayerBase::Shape>( lstNames->currentItem()->data( Qt::UserRole ).toInt() ) );
748  btnChangeColorFill->setEnabled( QgsSimpleMarkerSymbolLayerBase::shapeIsFilled( mLayer->shape() ) );
749  emit changed();
750 }
751 
753 {
754  mLayer->setStrokeColor( color );
755  emit changed();
756 }
757 
759 {
760  mLayer->setColor( color );
761  emit changed();
762 }
763 
764 void QgsSimpleMarkerSymbolLayerWidget::penJoinStyleChanged()
765 {
766  mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
767  emit changed();
768 }
769 
770 void QgsSimpleMarkerSymbolLayerWidget::setSize()
771 {
772  mLayer->setSize( spinSize->value() );
773  emit changed();
774 }
775 
776 void QgsSimpleMarkerSymbolLayerWidget::setAngle()
777 {
778  mLayer->setAngle( spinAngle->value() );
779  emit changed();
780 }
781 
782 void QgsSimpleMarkerSymbolLayerWidget::setOffset()
783 {
784  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
785  emit changed();
786 }
787 
788 void QgsSimpleMarkerSymbolLayerWidget::mStrokeStyleComboBox_currentIndexChanged( int index )
789 {
790  Q_UNUSED( index )
791 
792  if ( mLayer )
793  {
794  mLayer->setStrokeStyle( mStrokeStyleComboBox->penStyle() );
795  emit changed();
796  }
797 }
798 
799 void QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
800 {
801  if ( mLayer )
802  {
803  mLayer->setStrokeWidth( d );
804  emit changed();
805  }
806 }
807 
808 void QgsSimpleMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
809 {
810  if ( mLayer )
811  {
812  mLayer->setSizeUnit( mSizeUnitWidget->unit() );
813  mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
814  emit changed();
815  }
816 }
817 
818 void QgsSimpleMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
819 {
820  if ( mLayer )
821  {
822  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
823  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
824  emit changed();
825  }
826 }
827 
828 void QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
829 {
830  if ( mLayer )
831  {
832  mLayer->setStrokeWidthUnit( mStrokeWidthUnitWidget->unit() );
833  mLayer->setStrokeWidthMapUnitScale( mStrokeWidthUnitWidget->getMapUnitScale() );
834  emit changed();
835  }
836 }
837 
838 void QgsSimpleMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
839 {
840  if ( mLayer )
841  {
843  emit changed();
844  }
845 }
846 
847 void QgsSimpleMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
848 {
849  if ( mLayer )
850  {
852  emit changed();
853  }
854 }
855 
856 void QgsSimpleMarkerSymbolLayerWidget::updateAssistantSymbol()
857 {
858  for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
859  {
860  mAssistantPreviewSymbol->deleteSymbolLayer( i );
861  }
862  mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
864  if ( ddSize )
865  mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
866 }
867 
868 
870 
872  : QgsSymbolLayerWidget( parent, vl )
873 {
874  mLayer = nullptr;
875 
876  setupUi( this );
877  connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleFillSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
878  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleFillSymbolLayerWidget::mOffsetUnitWidget_changed );
883 
884  btnChangeColor->setAllowOpacity( true );
885  btnChangeColor->setColorDialogTitle( tr( "Select Fill Color" ) );
886  btnChangeColor->setContext( QStringLiteral( "symbology" ) );
887  btnChangeColor->setShowNoColor( true );
888  btnChangeColor->setNoColorString( tr( "Transparent Fill" ) );
889  btnChangeStrokeColor->setAllowOpacity( true );
890  btnChangeStrokeColor->setColorDialogTitle( tr( "Select Stroke Color" ) );
891  btnChangeStrokeColor->setContext( QStringLiteral( "symbology" ) );
892  btnChangeStrokeColor->setShowNoColor( true );
893  btnChangeStrokeColor->setNoColorString( tr( "Transparent Stroke" ) );
894 
895  spinOffsetX->setClearValue( 0.0 );
896  spinOffsetY->setClearValue( 0.0 );
897 
899  connect( cboFillStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleFillSymbolLayerWidget::setBrushStyle );
900  connect( btnChangeStrokeColor, &QgsColorButton::colorChanged, this, &QgsSimpleFillSymbolLayerWidget::setStrokeColor );
901  connect( spinStrokeWidth, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleFillSymbolLayerWidget::strokeWidthChanged );
902  connect( cboStrokeStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleFillSymbolLayerWidget::strokeStyleChanged );
903  connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleFillSymbolLayerWidget::strokeStyleChanged );
904  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleFillSymbolLayerWidget::offsetChanged );
905  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleFillSymbolLayerWidget::offsetChanged );
906 
907  mFillColorDDBtn->registerLinkedWidget( btnChangeColor );
908  mStrokeColorDDBtn->registerLinkedWidget( btnChangeStrokeColor );
909 }
910 
912 {
913  if ( layer->layerType() != QLatin1String( "SimpleFill" ) )
914  return;
915 
916  // layer type is correct, we can do the cast
917  mLayer = static_cast<QgsSimpleFillSymbolLayer *>( layer );
918 
919  // set values
920  btnChangeColor->blockSignals( true );
921  btnChangeColor->setColor( mLayer->color() );
922  btnChangeColor->blockSignals( false );
923  cboFillStyle->blockSignals( true );
924  cboFillStyle->setBrushStyle( mLayer->brushStyle() );
925  cboFillStyle->blockSignals( false );
926  btnChangeStrokeColor->blockSignals( true );
927  btnChangeStrokeColor->setColor( mLayer->strokeColor() );
928  btnChangeStrokeColor->blockSignals( false );
929  cboStrokeStyle->blockSignals( true );
930  cboStrokeStyle->setPenStyle( mLayer->strokeStyle() );
931  cboStrokeStyle->blockSignals( false );
932  spinStrokeWidth->blockSignals( true );
933  spinStrokeWidth->setValue( mLayer->strokeWidth() );
934  spinStrokeWidth->blockSignals( false );
935  cboJoinStyle->blockSignals( true );
936  cboJoinStyle->setPenJoinStyle( mLayer->penJoinStyle() );
937  cboJoinStyle->blockSignals( false );
938  spinOffsetX->blockSignals( true );
939  spinOffsetX->setValue( mLayer->offset().x() );
940  spinOffsetX->blockSignals( false );
941  spinOffsetY->blockSignals( true );
942  spinOffsetY->setValue( mLayer->offset().y() );
943  spinOffsetY->blockSignals( false );
944 
945  mStrokeWidthUnitWidget->blockSignals( true );
946  mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
947  mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
948  mStrokeWidthUnitWidget->blockSignals( false );
949  mOffsetUnitWidget->blockSignals( true );
950  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
951  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
952  mOffsetUnitWidget->blockSignals( false );
953 
961 }
962 
964 {
965  return mLayer;
966 }
967 
968 void QgsSimpleFillSymbolLayerWidget::setColor( const QColor &color )
969 {
970  mLayer->setColor( color );
971  emit changed();
972 }
973 
975 {
976  mLayer->setStrokeColor( color );
977  emit changed();
978 }
979 
980 void QgsSimpleFillSymbolLayerWidget::setBrushStyle()
981 {
982  mLayer->setBrushStyle( cboFillStyle->brushStyle() );
983  emit changed();
984 }
985 
986 void QgsSimpleFillSymbolLayerWidget::strokeWidthChanged()
987 {
988  mLayer->setStrokeWidth( spinStrokeWidth->value() );
989  emit changed();
990 }
991 
992 void QgsSimpleFillSymbolLayerWidget::strokeStyleChanged()
993 {
994  mLayer->setStrokeStyle( cboStrokeStyle->penStyle() );
995  mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
996  emit changed();
997 }
998 
999 void QgsSimpleFillSymbolLayerWidget::offsetChanged()
1000 {
1001  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1002  emit changed();
1003 }
1004 
1005 void QgsSimpleFillSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
1006 {
1007  if ( mLayer )
1008  {
1009  mLayer->setStrokeWidthUnit( mStrokeWidthUnitWidget->unit() );
1010  mLayer->setStrokeWidthMapUnitScale( mStrokeWidthUnitWidget->getMapUnitScale() );
1011  emit changed();
1012  }
1013 }
1014 
1015 void QgsSimpleFillSymbolLayerWidget::mOffsetUnitWidget_changed()
1016 {
1017  if ( mLayer )
1018  {
1019  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1020  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1021  emit changed();
1022  }
1023 }
1024 
1026 
1028  : QgsSymbolLayerWidget( parent, vl )
1029 {
1030  mLayer = nullptr;
1031 
1032  setupUi( this );
1033  connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFilledMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
1034  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFilledMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
1035  connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFilledMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
1036  connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFilledMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
1041 
1042  spinOffsetX->setClearValue( 0.0 );
1043  spinOffsetY->setClearValue( 0.0 );
1044  spinAngle->setClearValue( 0.0 );
1045 
1046  //make a temporary symbol for the size assistant preview
1047  mAssistantPreviewSymbol.reset( new QgsMarkerSymbol() );
1048 
1049  if ( vectorLayer() )
1050  mSizeDDBtn->setSymbol( mAssistantPreviewSymbol );
1051 
1052  int size = lstNames->iconSize().width();
1053 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
1054  size = std::max( 30, static_cast< int >( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().width( 'X' ) * 3 ) ) );
1055 #else
1056  size = std::max( 30, static_cast< int >( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 3 ) ) );
1057 #endif
1058  lstNames->setGridSize( QSize( size * 1.2, size * 1.2 ) );
1059  lstNames->setIconSize( QSize( size, size ) );
1060 
1061  double markerSize = size * 0.8;
1063  for ( QgsSimpleMarkerSymbolLayerBase::Shape shape : shapes )
1064  {
1065  QgsSimpleMarkerSymbolLayer *lyr = new QgsSimpleMarkerSymbolLayer( shape, markerSize );
1067  lyr->setColor( QColor( 200, 200, 200 ) );
1068  lyr->setStrokeColor( QColor( 0, 0, 0 ) );
1069  QIcon icon = QgsSymbolLayerUtils::symbolLayerPreviewIcon( lyr, QgsUnitTypes::RenderPixels, QSize( size, size ) );
1070  QListWidgetItem *item = new QListWidgetItem( icon, QString(), lstNames );
1071  item->setData( Qt::UserRole, static_cast< int >( shape ) );
1072  item->setToolTip( QgsSimpleMarkerSymbolLayerBase::encodeShape( shape ) );
1073  delete lyr;
1074  }
1075  // show at least 3 rows
1076  lstNames->setMinimumHeight( lstNames->gridSize().height() * 3.1 );
1077 
1078  connect( lstNames, &QListWidget::currentRowChanged, this, &QgsFilledMarkerSymbolLayerWidget::setShape );
1079  connect( spinSize, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setSize );
1080  connect( spinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setAngle );
1081  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setOffset );
1082  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setOffset );
1083  connect( this, &QgsSymbolLayerWidget::changed, this, &QgsFilledMarkerSymbolLayerWidget::updateAssistantSymbol );
1084 }
1085 
1087 {
1088  if ( layer->layerType() != QLatin1String( "FilledMarker" ) )
1089  return;
1090 
1091  // layer type is correct, we can do the cast
1092  mLayer = static_cast<QgsFilledMarkerSymbolLayer *>( layer );
1093 
1094  // set values
1096  for ( int i = 0; i < lstNames->count(); ++i )
1097  {
1098  if ( static_cast< QgsSimpleMarkerSymbolLayerBase::Shape >( lstNames->item( i )->data( Qt::UserRole ).toInt() ) == shape )
1099  {
1100  lstNames->setCurrentRow( i );
1101  break;
1102  }
1103  }
1104  whileBlocking( spinSize )->setValue( mLayer->size() );
1105  whileBlocking( spinAngle )->setValue( mLayer->angle() );
1106  whileBlocking( spinOffsetX )->setValue( mLayer->offset().x() );
1107  whileBlocking( spinOffsetY )->setValue( mLayer->offset().y() );
1108 
1109  mSizeUnitWidget->blockSignals( true );
1110  mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
1111  mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
1112  mSizeUnitWidget->blockSignals( false );
1113  mOffsetUnitWidget->blockSignals( true );
1114  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1115  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1116  mOffsetUnitWidget->blockSignals( false );
1117 
1118  //anchor points
1119  whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mLayer->horizontalAnchorPoint() );
1120  whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mLayer->verticalAnchorPoint() );
1121 
1128 
1129  updateAssistantSymbol();
1130 }
1131 
1133 {
1134  return mLayer;
1135 }
1136 
1137 void QgsFilledMarkerSymbolLayerWidget::setShape()
1138 {
1139  mLayer->setShape( static_cast< QgsSimpleMarkerSymbolLayerBase::Shape>( lstNames->currentItem()->data( Qt::UserRole ).toInt() ) );
1140  emit changed();
1141 }
1142 
1143 void QgsFilledMarkerSymbolLayerWidget::setSize()
1144 {
1145  mLayer->setSize( spinSize->value() );
1146  emit changed();
1147 }
1148 
1149 void QgsFilledMarkerSymbolLayerWidget::setAngle()
1150 {
1151  mLayer->setAngle( spinAngle->value() );
1152  emit changed();
1153 }
1154 
1155 void QgsFilledMarkerSymbolLayerWidget::setOffset()
1156 {
1157  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1158  emit changed();
1159 }
1160 
1161 void QgsFilledMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
1162 {
1163  if ( mLayer )
1164  {
1165  mLayer->setSizeUnit( mSizeUnitWidget->unit() );
1166  mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
1167  emit changed();
1168  }
1169 }
1170 
1171 void QgsFilledMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
1172 {
1173  if ( mLayer )
1174  {
1175  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1176  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1177  emit changed();
1178  }
1179 }
1180 
1181 void QgsFilledMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
1182 {
1183  if ( mLayer )
1184  {
1186  emit changed();
1187  }
1188 }
1189 
1190 void QgsFilledMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
1191 {
1192  if ( mLayer )
1193  {
1195  emit changed();
1196  }
1197 }
1198 
1199 void QgsFilledMarkerSymbolLayerWidget::updateAssistantSymbol()
1200 {
1201  for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
1202  {
1203  mAssistantPreviewSymbol->deleteSymbolLayer( i );
1204  }
1205  mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
1207  if ( ddSize )
1208  mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
1209 }
1210 
1211 
1213 
1215  : QgsSymbolLayerWidget( parent, vl )
1216 {
1217  mLayer = nullptr;
1218 
1219  setupUi( this );
1220  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsGradientFillSymbolLayerWidget::mOffsetUnitWidget_changed );
1221  connect( mSpinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::mSpinAngle_valueChanged );
1224 
1225  btnColorRamp->setShowGradientOnly( true );
1226 
1227  btnChangeColor->setAllowOpacity( true );
1228  btnChangeColor->setColorDialogTitle( tr( "Select Gradient Color" ) );
1229  btnChangeColor->setContext( QStringLiteral( "symbology" ) );
1230  btnChangeColor->setShowNoColor( true );
1231  btnChangeColor->setNoColorString( tr( "Transparent" ) );
1232  btnChangeColor2->setAllowOpacity( true );
1233  btnChangeColor2->setColorDialogTitle( tr( "Select Gradient Color" ) );
1234  btnChangeColor2->setContext( QStringLiteral( "symbology" ) );
1235  btnChangeColor2->setShowNoColor( true );
1236  btnChangeColor2->setNoColorString( tr( "Transparent" ) );
1237 
1238  mStartColorDDBtn->registerLinkedWidget( btnChangeColor );
1239  mEndColorDDBtn->registerLinkedWidget( btnChangeColor2 );
1240 
1241  spinOffsetX->setClearValue( 0.0 );
1242  spinOffsetY->setClearValue( 0.0 );
1243  mSpinAngle->setClearValue( 0.0 );
1244 
1248  connect( cboGradientType, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGradientFillSymbolLayerWidget::setGradientType );
1249  connect( cboCoordinateMode, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGradientFillSymbolLayerWidget::setCoordinateMode );
1250  connect( cboGradientSpread, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGradientFillSymbolLayerWidget::setGradientSpread );
1251  connect( radioTwoColor, &QAbstractButton::toggled, this, &QgsGradientFillSymbolLayerWidget::colorModeChanged );
1252  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::offsetChanged );
1253  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::offsetChanged );
1254  connect( spinRefPoint1X, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1255  connect( spinRefPoint1Y, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1256  connect( checkRefPoint1Centroid, &QAbstractButton::toggled, this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1257  connect( spinRefPoint2X, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1258  connect( spinRefPoint2Y, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1259  connect( checkRefPoint2Centroid, &QAbstractButton::toggled, this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1260 }
1261 
1263 {
1264  if ( layer->layerType() != QLatin1String( "GradientFill" ) )
1265  return;
1266 
1267  // layer type is correct, we can do the cast
1268  mLayer = static_cast<QgsGradientFillSymbolLayer *>( layer );
1269 
1270  // set values
1271  btnChangeColor->blockSignals( true );
1272  btnChangeColor->setColor( mLayer->color() );
1273  btnChangeColor->blockSignals( false );
1274  btnChangeColor2->blockSignals( true );
1275  btnChangeColor2->setColor( mLayer->color2() );
1276  btnChangeColor2->blockSignals( false );
1277 
1279  {
1280  radioTwoColor->setChecked( true );
1281  btnColorRamp->setEnabled( false );
1282  }
1283  else
1284  {
1285  radioColorRamp->setChecked( true );
1286  btnChangeColor->setEnabled( false );
1287  btnChangeColor2->setEnabled( false );
1288  }
1289 
1290  // set source color ramp
1291  if ( mLayer->colorRamp() )
1292  {
1293  btnColorRamp->blockSignals( true );
1294  btnColorRamp->setColorRamp( mLayer->colorRamp() );
1295  btnColorRamp->blockSignals( false );
1296  }
1297 
1298  cboGradientType->blockSignals( true );
1299  switch ( mLayer->gradientType() )
1300  {
1302  cboGradientType->setCurrentIndex( 0 );
1303  break;
1305  cboGradientType->setCurrentIndex( 1 );
1306  break;
1308  cboGradientType->setCurrentIndex( 2 );
1309  break;
1310  }
1311  cboGradientType->blockSignals( false );
1312 
1313  cboCoordinateMode->blockSignals( true );
1314  switch ( mLayer->coordinateMode() )
1315  {
1317  cboCoordinateMode->setCurrentIndex( 1 );
1318  checkRefPoint1Centroid->setEnabled( false );
1319  checkRefPoint2Centroid->setEnabled( false );
1320  break;
1322  default:
1323  cboCoordinateMode->setCurrentIndex( 0 );
1324  break;
1325  }
1326  cboCoordinateMode->blockSignals( false );
1327 
1328  cboGradientSpread->blockSignals( true );
1329  switch ( mLayer->gradientSpread() )
1330  {
1332  cboGradientSpread->setCurrentIndex( 0 );
1333  break;
1335  cboGradientSpread->setCurrentIndex( 1 );
1336  break;
1338  cboGradientSpread->setCurrentIndex( 2 );
1339  break;
1340  }
1341  cboGradientSpread->blockSignals( false );
1342 
1343  spinRefPoint1X->blockSignals( true );
1344  spinRefPoint1X->setValue( mLayer->referencePoint1().x() );
1345  spinRefPoint1X->blockSignals( false );
1346  spinRefPoint1Y->blockSignals( true );
1347  spinRefPoint1Y->setValue( mLayer->referencePoint1().y() );
1348  spinRefPoint1Y->blockSignals( false );
1349  checkRefPoint1Centroid->blockSignals( true );
1350  checkRefPoint1Centroid->setChecked( mLayer->referencePoint1IsCentroid() );
1352  {
1353  spinRefPoint1X->setEnabled( false );
1354  spinRefPoint1Y->setEnabled( false );
1355  }
1356  checkRefPoint1Centroid->blockSignals( false );
1357  spinRefPoint2X->blockSignals( true );
1358  spinRefPoint2X->setValue( mLayer->referencePoint2().x() );
1359  spinRefPoint2X->blockSignals( false );
1360  spinRefPoint2Y->blockSignals( true );
1361  spinRefPoint2Y->setValue( mLayer->referencePoint2().y() );
1362  spinRefPoint2Y->blockSignals( false );
1363  checkRefPoint2Centroid->blockSignals( true );
1364  checkRefPoint2Centroid->setChecked( mLayer->referencePoint2IsCentroid() );
1366  {
1367  spinRefPoint2X->setEnabled( false );
1368  spinRefPoint2Y->setEnabled( false );
1369  }
1370  checkRefPoint2Centroid->blockSignals( false );
1371 
1372  spinOffsetX->blockSignals( true );
1373  spinOffsetX->setValue( mLayer->offset().x() );
1374  spinOffsetX->blockSignals( false );
1375  spinOffsetY->blockSignals( true );
1376  spinOffsetY->setValue( mLayer->offset().y() );
1377  spinOffsetY->blockSignals( false );
1378  mSpinAngle->blockSignals( true );
1379  mSpinAngle->setValue( mLayer->angle() );
1380  mSpinAngle->blockSignals( false );
1381 
1382  mOffsetUnitWidget->blockSignals( true );
1383  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1384  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1385  mOffsetUnitWidget->blockSignals( false );
1386 
1400 }
1401 
1403 {
1404  return mLayer;
1405 }
1406 
1408 {
1409  mLayer->setColor( color );
1410  emit changed();
1411 }
1412 
1414 {
1415  mLayer->setColor2( color );
1416  emit changed();
1417 }
1418 
1419 void QgsGradientFillSymbolLayerWidget::colorModeChanged()
1420 {
1421  if ( radioTwoColor->isChecked() )
1422  {
1424  }
1425  else
1426  {
1428  }
1429  emit changed();
1430 }
1431 
1433 {
1434  if ( btnColorRamp->isNull() )
1435  return;
1436 
1437  mLayer->setColorRamp( btnColorRamp->colorRamp()->clone() );
1438  emit changed();
1439 }
1440 
1442 {
1443  switch ( index )
1444  {
1445  case 0:
1447  //set sensible default reference points
1448  spinRefPoint1X->setValue( 0.5 );
1449  spinRefPoint1Y->setValue( 0 );
1450  spinRefPoint2X->setValue( 0.5 );
1451  spinRefPoint2Y->setValue( 1 );
1452  break;
1453  case 1:
1455  //set sensible default reference points
1456  spinRefPoint1X->setValue( 0 );
1457  spinRefPoint1Y->setValue( 0 );
1458  spinRefPoint2X->setValue( 1 );
1459  spinRefPoint2Y->setValue( 1 );
1460  break;
1461  case 2:
1463  spinRefPoint1X->setValue( 0.5 );
1464  spinRefPoint1Y->setValue( 0.5 );
1465  spinRefPoint2X->setValue( 1 );
1466  spinRefPoint2Y->setValue( 1 );
1467  break;
1468  }
1469  emit changed();
1470 }
1471 
1473 {
1474 
1475  switch ( index )
1476  {
1477  case 0:
1478  //feature coordinate mode
1480  //allow choice of centroid reference positions
1481  checkRefPoint1Centroid->setEnabled( true );
1482  checkRefPoint2Centroid->setEnabled( true );
1483  break;
1484  case 1:
1485  //viewport coordinate mode
1487  //disable choice of centroid reference positions
1488  checkRefPoint1Centroid->setChecked( Qt::Unchecked );
1489  checkRefPoint1Centroid->setEnabled( false );
1490  checkRefPoint2Centroid->setChecked( Qt::Unchecked );
1491  checkRefPoint2Centroid->setEnabled( false );
1492  break;
1493  }
1494 
1495  emit changed();
1496 }
1497 
1499 {
1500  switch ( index )
1501  {
1502  case 0:
1504  break;
1505  case 1:
1507  break;
1508  case 2:
1510  break;
1511  }
1512 
1513  emit changed();
1514 }
1515 
1516 void QgsGradientFillSymbolLayerWidget::offsetChanged()
1517 {
1518  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1519  emit changed();
1520 }
1521 
1522 void QgsGradientFillSymbolLayerWidget::referencePointChanged()
1523 {
1524  mLayer->setReferencePoint1( QPointF( spinRefPoint1X->value(), spinRefPoint1Y->value() ) );
1525  mLayer->setReferencePoint1IsCentroid( checkRefPoint1Centroid->isChecked() );
1526  mLayer->setReferencePoint2( QPointF( spinRefPoint2X->value(), spinRefPoint2Y->value() ) );
1527  mLayer->setReferencePoint2IsCentroid( checkRefPoint2Centroid->isChecked() );
1528  emit changed();
1529 }
1530 
1531 void QgsGradientFillSymbolLayerWidget::mSpinAngle_valueChanged( double value )
1532 {
1533  mLayer->setAngle( value );
1534  emit changed();
1535 }
1536 
1537 void QgsGradientFillSymbolLayerWidget::mOffsetUnitWidget_changed()
1538 {
1539  if ( mLayer )
1540  {
1541  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1542  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1543  emit changed();
1544  }
1545 }
1546 
1548 
1550  : QgsSymbolLayerWidget( parent, vl )
1551 {
1552  mLayer = nullptr;
1553 
1554  setupUi( this );
1555  connect( mSpinBlurRadius, qgis::overload< int >::of( &QSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::mSpinBlurRadius_valueChanged );
1556  connect( mSpinMaxDistance, qgis::overload< double >::of( &QDoubleSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::mSpinMaxDistance_valueChanged );
1557  connect( mDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsShapeburstFillSymbolLayerWidget::mDistanceUnitWidget_changed );
1558  connect( mRadioUseWholeShape, &QRadioButton::toggled, this, &QgsShapeburstFillSymbolLayerWidget::mRadioUseWholeShape_toggled );
1559  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsShapeburstFillSymbolLayerWidget::mOffsetUnitWidget_changed );
1560  connect( mIgnoreRingsCheckBox, &QCheckBox::stateChanged, this, &QgsShapeburstFillSymbolLayerWidget::mIgnoreRingsCheckBox_stateChanged );
1565 
1566  QButtonGroup *group1 = new QButtonGroup( this );
1567  group1->addButton( radioColorRamp );
1568  group1->addButton( radioTwoColor );
1569  QButtonGroup *group2 = new QButtonGroup( this );
1570  group2->addButton( mRadioUseMaxDistance );
1571  group2->addButton( mRadioUseWholeShape );
1572  btnChangeColor->setAllowOpacity( true );
1573  btnChangeColor->setColorDialogTitle( tr( "Select Gradient Color" ) );
1574  btnChangeColor->setContext( QStringLiteral( "symbology" ) );
1575  btnChangeColor->setShowNoColor( true );
1576  btnChangeColor->setNoColorString( tr( "Transparent" ) );
1577  btnChangeColor2->setAllowOpacity( true );
1578  btnChangeColor2->setColorDialogTitle( tr( "Select Gradient Color" ) );
1579  btnChangeColor2->setContext( QStringLiteral( "symbology" ) );
1580  btnChangeColor2->setShowNoColor( true );
1581  btnChangeColor2->setNoColorString( tr( "Transparent" ) );
1582 
1583  mStartColorDDBtn->registerLinkedWidget( btnChangeColor );
1584  mEndColorDDBtn->registerLinkedWidget( btnChangeColor2 );
1585 
1586  spinOffsetX->setClearValue( 0.0 );
1587  spinOffsetY->setClearValue( 0.0 );
1588  mSpinMaxDistance->setClearValue( 5.0 );
1589 
1590  btnColorRamp->setShowGradientOnly( true );
1591 
1592  connect( btnColorRamp, &QgsColorRampButton::colorRampChanged, this, &QgsShapeburstFillSymbolLayerWidget::applyColorRamp );
1593 
1596  connect( radioTwoColor, &QAbstractButton::toggled, this, &QgsShapeburstFillSymbolLayerWidget::colorModeChanged );
1597  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::offsetChanged );
1598  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::offsetChanged );
1599 
1600  connect( mBlurSlider, &QAbstractSlider::valueChanged, mSpinBlurRadius, &QSpinBox::setValue );
1601  connect( mSpinBlurRadius, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), mBlurSlider, &QAbstractSlider::setValue );
1602 }
1603 
1605 {
1606  if ( layer->layerType() != QLatin1String( "ShapeburstFill" ) )
1607  return;
1608 
1609  // layer type is correct, we can do the cast
1610  mLayer = static_cast<QgsShapeburstFillSymbolLayer *>( layer );
1611 
1612  // set values
1613  btnChangeColor->blockSignals( true );
1614  btnChangeColor->setColor( mLayer->color() );
1615  btnChangeColor->blockSignals( false );
1616  btnChangeColor2->blockSignals( true );
1617  btnChangeColor2->setColor( mLayer->color2() );
1618  btnChangeColor2->blockSignals( false );
1619 
1621  {
1622  radioTwoColor->setChecked( true );
1623  btnColorRamp->setEnabled( false );
1624  }
1625  else
1626  {
1627  radioColorRamp->setChecked( true );
1628  btnChangeColor->setEnabled( false );
1629  btnChangeColor2->setEnabled( false );
1630  }
1631 
1632  mSpinBlurRadius->blockSignals( true );
1633  mBlurSlider->blockSignals( true );
1634  mSpinBlurRadius->setValue( mLayer->blurRadius() );
1635  mBlurSlider->setValue( mLayer->blurRadius() );
1636  mSpinBlurRadius->blockSignals( false );
1637  mBlurSlider->blockSignals( false );
1638 
1639  mSpinMaxDistance->blockSignals( true );
1640  mSpinMaxDistance->setValue( mLayer->maxDistance() );
1641  mSpinMaxDistance->blockSignals( false );
1642 
1643  mRadioUseWholeShape->blockSignals( true );
1644  mRadioUseMaxDistance->blockSignals( true );
1645  if ( mLayer->useWholeShape() )
1646  {
1647  mRadioUseWholeShape->setChecked( true );
1648  mSpinMaxDistance->setEnabled( false );
1649  mDistanceUnitWidget->setEnabled( false );
1650  }
1651  else
1652  {
1653  mRadioUseMaxDistance->setChecked( true );
1654  mSpinMaxDistance->setEnabled( true );
1655  mDistanceUnitWidget->setEnabled( true );
1656  }
1657  mRadioUseWholeShape->blockSignals( false );
1658  mRadioUseMaxDistance->blockSignals( false );
1659 
1660  mDistanceUnitWidget->blockSignals( true );
1661  mDistanceUnitWidget->setUnit( mLayer->distanceUnit() );
1662  mDistanceUnitWidget->setMapUnitScale( mLayer->distanceMapUnitScale() );
1663  mDistanceUnitWidget->blockSignals( false );
1664 
1665  mIgnoreRingsCheckBox->blockSignals( true );
1666  mIgnoreRingsCheckBox->setCheckState( mLayer->ignoreRings() ? Qt::Checked : Qt::Unchecked );
1667  mIgnoreRingsCheckBox->blockSignals( false );
1668 
1669  // set source color ramp
1670  if ( mLayer->colorRamp() )
1671  {
1672  btnColorRamp->blockSignals( true );
1673  btnColorRamp->setColorRamp( mLayer->colorRamp() );
1674  btnColorRamp->blockSignals( false );
1675  }
1676 
1677  spinOffsetX->blockSignals( true );
1678  spinOffsetX->setValue( mLayer->offset().x() );
1679  spinOffsetX->blockSignals( false );
1680  spinOffsetY->blockSignals( true );
1681  spinOffsetY->setValue( mLayer->offset().y() );
1682  spinOffsetY->blockSignals( false );
1683  mOffsetUnitWidget->blockSignals( true );
1684  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1685  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1686  mOffsetUnitWidget->blockSignals( false );
1687 
1695 }
1696 
1698 {
1699  return mLayer;
1700 }
1701 
1703 {
1704  if ( mLayer )
1705  {
1706  mLayer->setColor( color );
1707  emit changed();
1708  }
1709 }
1710 
1712 {
1713  if ( mLayer )
1714  {
1715  mLayer->setColor2( color );
1716  emit changed();
1717  }
1718 }
1719 
1720 void QgsShapeburstFillSymbolLayerWidget::colorModeChanged()
1721 {
1722  if ( !mLayer )
1723  {
1724  return;
1725  }
1726 
1727  if ( radioTwoColor->isChecked() )
1728  {
1730  }
1731  else
1732  {
1734  }
1735  emit changed();
1736 }
1737 
1738 void QgsShapeburstFillSymbolLayerWidget::mSpinBlurRadius_valueChanged( int value )
1739 {
1740  if ( mLayer )
1741  {
1742  mLayer->setBlurRadius( value );
1743  emit changed();
1744  }
1745 }
1746 
1747 void QgsShapeburstFillSymbolLayerWidget::mSpinMaxDistance_valueChanged( double value )
1748 {
1749  if ( mLayer )
1750  {
1751  mLayer->setMaxDistance( value );
1752  emit changed();
1753  }
1754 }
1755 
1756 void QgsShapeburstFillSymbolLayerWidget::mDistanceUnitWidget_changed()
1757 {
1758  if ( mLayer )
1759  {
1760  mLayer->setDistanceUnit( mDistanceUnitWidget->unit() );
1761  mLayer->setDistanceMapUnitScale( mDistanceUnitWidget->getMapUnitScale() );
1762  emit changed();
1763  }
1764 }
1765 
1766 void QgsShapeburstFillSymbolLayerWidget::mRadioUseWholeShape_toggled( bool value )
1767 {
1768  if ( mLayer )
1769  {
1770  mLayer->setUseWholeShape( value );
1771  mDistanceUnitWidget->setEnabled( !value );
1772  emit changed();
1773  }
1774 }
1775 
1776 void QgsShapeburstFillSymbolLayerWidget::applyColorRamp()
1777 {
1778  QgsColorRamp *ramp = btnColorRamp->colorRamp();
1779  if ( !ramp )
1780  return;
1781 
1782  mLayer->setColorRamp( ramp );
1783  emit changed();
1784 }
1785 
1786 void QgsShapeburstFillSymbolLayerWidget::offsetChanged()
1787 {
1788  if ( mLayer )
1789  {
1790  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1791  emit changed();
1792  }
1793 }
1794 
1795 void QgsShapeburstFillSymbolLayerWidget::mOffsetUnitWidget_changed()
1796 {
1797  if ( mLayer )
1798  {
1799  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1800  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1801  emit changed();
1802  }
1803 }
1804 
1805 
1806 void QgsShapeburstFillSymbolLayerWidget::mIgnoreRingsCheckBox_stateChanged( int state )
1807 {
1808  bool checked = ( state == Qt::Checked );
1809  mLayer->setIgnoreRings( checked );
1810  emit changed();
1811 }
1812 
1814 
1816  : QgsSymbolLayerWidget( parent, vl )
1817 {
1818  mLayer = nullptr;
1819 
1820  setupUi( this );
1821  connect( mIntervalUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsMarkerLineSymbolLayerWidget::mIntervalUnitWidget_changed );
1822  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsMarkerLineSymbolLayerWidget::mOffsetUnitWidget_changed );
1823  connect( mOffsetAlongLineUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsMarkerLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed );
1824  connect( mAverageAngleUnit, &QgsUnitSelectionWidget::changed, this, &QgsMarkerLineSymbolLayerWidget::averageAngleUnitChanged );
1833 
1834  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconAllRings.svg" ) ), tr( "All Rings" ), QgsLineSymbolLayer::AllRings );
1835  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconExteriorRing.svg" ) ), tr( "Exterior Ring Only" ), QgsLineSymbolLayer::ExteriorRingOnly );
1836  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconInteriorRings.svg" ) ), tr( "Interior Rings Only" ), QgsLineSymbolLayer::InteriorRingsOnly );
1837  connect( mRingFilterComboBox, qgis::overload< int >::of( &QComboBox::currentIndexChanged ), this, [ = ]( int )
1838  {
1839  if ( mLayer )
1840  {
1841  mLayer->setRingFilter( static_cast< QgsLineSymbolLayer::RenderRingFilter >( mRingFilterComboBox->currentData().toInt() ) );
1842  emit changed();
1843  }
1844  } );
1845 
1846  spinOffset->setClearValue( 0.0 );
1847 
1848 
1849  if ( vl && vl->geometryType() != QgsWkbTypes::PolygonGeometry )
1850  {
1851  mRingFilterComboBox->hide();
1852  mRingsLabel->hide();
1853  }
1854 
1855  mSpinAverageAngleLength->setClearValue( 4.0 );
1856 
1857  connect( spinInterval, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsMarkerLineSymbolLayerWidget::setInterval );
1858  connect( mSpinOffsetAlongLine, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsMarkerLineSymbolLayerWidget::setOffsetAlongLine );
1859  connect( chkRotateMarker, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setRotate );
1860  connect( spinOffset, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsMarkerLineSymbolLayerWidget::setOffset );
1861  connect( mSpinAverageAngleLength, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsMarkerLineSymbolLayerWidget::setAverageAngle );
1862  connect( radInterval, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1863  connect( radVertex, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1864  connect( radVertexLast, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1865  connect( radVertexFirst, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1866  connect( radCentralPoint, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1867  connect( radCurvePoint, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1868  connect( radSegmentCentralPoint, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1869 }
1870 
1872 {
1873  if ( layer->layerType() != QLatin1String( "MarkerLine" ) )
1874  return;
1875 
1876  // layer type is correct, we can do the cast
1877  mLayer = static_cast<QgsMarkerLineSymbolLayer *>( layer );
1878 
1879  // set values
1880  spinInterval->blockSignals( true );
1881  spinInterval->setValue( mLayer->interval() );
1882  spinInterval->blockSignals( false );
1883  mSpinOffsetAlongLine->blockSignals( true );
1884  mSpinOffsetAlongLine->setValue( mLayer->offsetAlongLine() );
1885  mSpinOffsetAlongLine->blockSignals( false );
1886  chkRotateMarker->blockSignals( true );
1887  chkRotateMarker->setChecked( mLayer->rotateSymbols() );
1888  chkRotateMarker->blockSignals( false );
1889  spinOffset->blockSignals( true );
1890  spinOffset->setValue( mLayer->offset() );
1891  spinOffset->blockSignals( false );
1893  radInterval->setChecked( true );
1895  radVertex->setChecked( true );
1897  radVertexLast->setChecked( true );
1899  radCentralPoint->setChecked( true );
1901  radCurvePoint->setChecked( true );
1903  radSegmentCentralPoint->setChecked( true );
1904  else
1905  radVertexFirst->setChecked( true );
1906 
1907  // set units
1908  mIntervalUnitWidget->blockSignals( true );
1909  mIntervalUnitWidget->setUnit( mLayer->intervalUnit() );
1910  mIntervalUnitWidget->setMapUnitScale( mLayer->intervalMapUnitScale() );
1911  mIntervalUnitWidget->blockSignals( false );
1912  mOffsetUnitWidget->blockSignals( true );
1913  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1914  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1915  mOffsetUnitWidget->blockSignals( false );
1916  mOffsetAlongLineUnitWidget->blockSignals( true );
1917  mOffsetAlongLineUnitWidget->setUnit( mLayer->offsetAlongLineUnit() );
1918  mOffsetAlongLineUnitWidget->setMapUnitScale( mLayer->offsetAlongLineMapUnitScale() );
1919  mOffsetAlongLineUnitWidget->blockSignals( false );
1920 
1921  whileBlocking( mAverageAngleUnit )->setUnit( mLayer->averageAngleUnit() );
1922  whileBlocking( mAverageAngleUnit )->setMapUnitScale( mLayer->averageAngleMapUnitScale() );
1923  whileBlocking( mSpinAverageAngleLength )->setValue( mLayer->averageAngleLength() );
1924 
1925  whileBlocking( mRingFilterComboBox )->setCurrentIndex( mRingFilterComboBox->findData( mLayer->ringFilter() ) );
1926 
1927  setPlacement(); // update gui
1928 
1934 }
1935 
1937 {
1938  return mLayer;
1939 }
1940 
1942 {
1943  mLayer->setInterval( val );
1944  emit changed();
1945 }
1946 
1948 {
1949  mLayer->setOffsetAlongLine( val );
1950  emit changed();
1951 }
1952 
1953 void QgsMarkerLineSymbolLayerWidget::setRotate()
1954 {
1955  mSpinAverageAngleLength->setEnabled( chkRotateMarker->isChecked() && ( radInterval->isChecked() || radCentralPoint->isChecked() ) );
1956  mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
1957 
1958  mLayer->setRotateSymbols( chkRotateMarker->isChecked() );
1959  emit changed();
1960 }
1961 
1962 void QgsMarkerLineSymbolLayerWidget::setOffset()
1963 {
1964  mLayer->setOffset( spinOffset->value() );
1965  emit changed();
1966 }
1967 
1968 void QgsMarkerLineSymbolLayerWidget::setPlacement()
1969 {
1970  bool interval = radInterval->isChecked();
1971  spinInterval->setEnabled( interval );
1972  mSpinOffsetAlongLine->setEnabled( radInterval->isChecked() || radVertexLast->isChecked() || radVertexFirst->isChecked() );
1973  mOffsetAlongLineUnitWidget->setEnabled( mSpinOffsetAlongLine->isEnabled() );
1974  mSpinAverageAngleLength->setEnabled( chkRotateMarker->isChecked() && ( radInterval->isChecked() || radCentralPoint->isChecked() ) );
1975  mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
1976  //mLayer->setPlacement( interval ? QgsMarkerLineSymbolLayer::Interval : QgsMarkerLineSymbolLayer::Vertex );
1977  if ( radInterval->isChecked() )
1979  else if ( radVertex->isChecked() )
1981  else if ( radVertexLast->isChecked() )
1983  else if ( radVertexFirst->isChecked() )
1985  else if ( radCurvePoint->isChecked() )
1987  else if ( radSegmentCentralPoint->isChecked() )
1989  else
1991 
1992  emit changed();
1993 }
1994 
1995 void QgsMarkerLineSymbolLayerWidget::mIntervalUnitWidget_changed()
1996 {
1997  if ( mLayer )
1998  {
1999  mLayer->setIntervalUnit( mIntervalUnitWidget->unit() );
2000  mLayer->setIntervalMapUnitScale( mIntervalUnitWidget->getMapUnitScale() );
2001  emit changed();
2002  }
2003 }
2004 
2005 void QgsMarkerLineSymbolLayerWidget::mOffsetUnitWidget_changed()
2006 {
2007  if ( mLayer )
2008  {
2009  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
2010  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
2011  emit changed();
2012  }
2013 }
2014 
2015 void QgsMarkerLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed()
2016 {
2017  if ( mLayer )
2018  {
2019  mLayer->setOffsetAlongLineUnit( mOffsetAlongLineUnitWidget->unit() );
2020  mLayer->setOffsetAlongLineMapUnitScale( mOffsetAlongLineUnitWidget->getMapUnitScale() );
2021  }
2022  emit changed();
2023 }
2024 
2025 void QgsMarkerLineSymbolLayerWidget::averageAngleUnitChanged()
2026 {
2027  if ( mLayer )
2028  {
2029  mLayer->setAverageAngleUnit( mAverageAngleUnit->unit() );
2030  mLayer->setAverageAngleMapUnitScale( mAverageAngleUnit->getMapUnitScale() );
2031  }
2032  emit changed();
2033 }
2034 
2035 void QgsMarkerLineSymbolLayerWidget::setAverageAngle( double val )
2036 {
2037  if ( mLayer )
2038  {
2039  mLayer->setAverageAngleLength( val );
2040  emit changed();
2041  }
2042 }
2043 
2044 
2046 
2048  : QgsSymbolLayerWidget( parent, vl )
2049 {
2050  mLayer = nullptr;
2051 
2052  setupUi( this );
2053  connect( mIntervalUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::mIntervalUnitWidget_changed );
2054  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::mOffsetUnitWidget_changed );
2055  connect( mOffsetAlongLineUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed );
2056  connect( mAverageAngleUnit, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::averageAngleUnitChanged );
2057  connect( mHashLengthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::hashLengthUnitWidgetChanged );
2068 
2069  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconAllRings.svg" ) ), tr( "All Rings" ), QgsLineSymbolLayer::AllRings );
2070  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconExteriorRing.svg" ) ), tr( "Exterior Ring Only" ), QgsLineSymbolLayer::ExteriorRingOnly );
2071  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconInteriorRings.svg" ) ), tr( "Interior Rings Only" ), QgsLineSymbolLayer::InteriorRingsOnly );
2072  connect( mRingFilterComboBox, qgis::overload< int >::of( &QComboBox::currentIndexChanged ), this, [ = ]( int )
2073  {
2074  if ( mLayer )
2075  {
2076  mLayer->setRingFilter( static_cast< QgsLineSymbolLayer::RenderRingFilter >( mRingFilterComboBox->currentData().toInt() ) );
2077  emit changed();
2078  }
2079  } );
2080 
2081  spinOffset->setClearValue( 0.0 );
2082 
2083 
2084  if ( vl && vl->geometryType() != QgsWkbTypes::PolygonGeometry )
2085  {
2086  mRingFilterComboBox->hide();
2087  mRingsLabel->hide();
2088  }
2089 
2090  mHashRotationSpinBox->setClearValue( 0 );
2091  mSpinAverageAngleLength->setClearValue( 4.0 );
2092 
2093  connect( spinInterval, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setInterval );
2094  connect( mSpinOffsetAlongLine, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setOffsetAlongLine );
2095  connect( mSpinHashLength, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setHashLength );
2096  connect( mHashRotationSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setHashAngle );
2097  connect( chkRotateMarker, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setRotate );
2098  connect( spinOffset, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setOffset );
2099  connect( mSpinAverageAngleLength, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setAverageAngle );
2100  connect( radInterval, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2101  connect( radVertex, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2102  connect( radVertexLast, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2103  connect( radVertexFirst, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2104  connect( radCentralPoint, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2105  connect( radCurvePoint, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2106  connect( radSegmentCentralPoint, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2107 }
2108 
2110 {
2111  if ( layer->layerType() != QLatin1String( "HashLine" ) )
2112  return;
2113 
2114  // layer type is correct, we can do the cast
2115  mLayer = static_cast<QgsHashedLineSymbolLayer *>( layer );
2116 
2117  // set values
2118  spinInterval->blockSignals( true );
2119  spinInterval->setValue( mLayer->interval() );
2120  spinInterval->blockSignals( false );
2121  mSpinOffsetAlongLine->blockSignals( true );
2122  mSpinOffsetAlongLine->setValue( mLayer->offsetAlongLine() );
2123  mSpinOffsetAlongLine->blockSignals( false );
2124  whileBlocking( mSpinHashLength )->setValue( mLayer->hashLength() );
2125  whileBlocking( mHashRotationSpinBox )->setValue( mLayer->hashAngle() );
2126  chkRotateMarker->blockSignals( true );
2127  chkRotateMarker->setChecked( mLayer->rotateSymbols() );
2128  chkRotateMarker->blockSignals( false );
2129  spinOffset->blockSignals( true );
2130  spinOffset->setValue( mLayer->offset() );
2131  spinOffset->blockSignals( false );
2133  radInterval->setChecked( true );
2134  else if ( mLayer->placement() == QgsTemplatedLineSymbolLayerBase::Vertex )
2135  radVertex->setChecked( true );
2137  radVertexLast->setChecked( true );
2139  radCentralPoint->setChecked( true );
2141  radCurvePoint->setChecked( true );
2143  radSegmentCentralPoint->setChecked( true );
2144  else
2145  radVertexFirst->setChecked( true );
2146 
2147  // set units
2148  mIntervalUnitWidget->blockSignals( true );
2149  mIntervalUnitWidget->setUnit( mLayer->intervalUnit() );
2150  mIntervalUnitWidget->setMapUnitScale( mLayer->intervalMapUnitScale() );
2151  mIntervalUnitWidget->blockSignals( false );
2152  mOffsetUnitWidget->blockSignals( true );
2153  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
2154  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
2155  mOffsetUnitWidget->blockSignals( false );
2156  mOffsetAlongLineUnitWidget->blockSignals( true );
2157  mOffsetAlongLineUnitWidget->setUnit( mLayer->offsetAlongLineUnit() );
2158  mOffsetAlongLineUnitWidget->setMapUnitScale( mLayer->offsetAlongLineMapUnitScale() );
2159  mOffsetAlongLineUnitWidget->blockSignals( false );
2160  whileBlocking( mAverageAngleUnit )->setUnit( mLayer->averageAngleUnit() );
2161  whileBlocking( mAverageAngleUnit )->setMapUnitScale( mLayer->averageAngleMapUnitScale() );
2162  whileBlocking( mSpinAverageAngleLength )->setValue( mLayer->averageAngleLength() );
2163  whileBlocking( mHashLengthUnitWidget )->setUnit( mLayer->hashLengthUnit() );
2164  whileBlocking( mHashLengthUnitWidget )->setMapUnitScale( mLayer->hashLengthMapUnitScale() );
2165 
2166  whileBlocking( mRingFilterComboBox )->setCurrentIndex( mRingFilterComboBox->findData( mLayer->ringFilter() ) );
2167 
2168  setPlacement(); // update gui
2169 
2177 }
2178 
2180 {
2181  return mLayer;
2182 }
2183 
2184 void QgsHashedLineSymbolLayerWidget::setInterval( double val )
2185 {
2186  mLayer->setInterval( val );
2187  emit changed();
2188 }
2189 
2190 void QgsHashedLineSymbolLayerWidget::setOffsetAlongLine( double val )
2191 {
2192  mLayer->setOffsetAlongLine( val );
2193  emit changed();
2194 }
2195 
2196 void QgsHashedLineSymbolLayerWidget::setHashLength( double val )
2197 {
2198  mLayer->setHashLength( val );
2199  emit changed();
2200 }
2201 
2202 void QgsHashedLineSymbolLayerWidget::setHashAngle( double val )
2203 {
2204  mLayer->setHashAngle( val );
2205  emit changed();
2206 }
2207 
2208 void QgsHashedLineSymbolLayerWidget::setRotate()
2209 {
2210  mSpinAverageAngleLength->setEnabled( chkRotateMarker->isChecked() && ( radInterval->isChecked() || radCentralPoint->isChecked() ) );
2211  mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
2212 
2213  mLayer->setRotateSymbols( chkRotateMarker->isChecked() );
2214  emit changed();
2215 }
2216 
2217 void QgsHashedLineSymbolLayerWidget::setOffset()
2218 {
2219  mLayer->setOffset( spinOffset->value() );
2220  emit changed();
2221 }
2222 
2223 void QgsHashedLineSymbolLayerWidget::setPlacement()
2224 {
2225  bool interval = radInterval->isChecked();
2226  spinInterval->setEnabled( interval );
2227  mSpinOffsetAlongLine->setEnabled( radInterval->isChecked() || radVertexLast->isChecked() || radVertexFirst->isChecked() );
2228  mOffsetAlongLineUnitWidget->setEnabled( mSpinOffsetAlongLine->isEnabled() );
2229  mSpinAverageAngleLength->setEnabled( chkRotateMarker->isChecked() && ( radInterval->isChecked() || radCentralPoint->isChecked() ) );
2230  mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
2231  //mLayer->setPlacement( interval ? QgsMarkerLineSymbolLayer::Interval : QgsMarkerLineSymbolLayer::Vertex );
2232  if ( radInterval->isChecked() )
2234  else if ( radVertex->isChecked() )
2236  else if ( radVertexLast->isChecked() )
2238  else if ( radVertexFirst->isChecked() )
2240  else if ( radCurvePoint->isChecked() )
2242  else if ( radSegmentCentralPoint->isChecked() )
2244  else
2246 
2247  emit changed();
2248 }
2249 
2250 void QgsHashedLineSymbolLayerWidget::mIntervalUnitWidget_changed()
2251 {
2252  if ( mLayer )
2253  {
2254  mLayer->setIntervalUnit( mIntervalUnitWidget->unit() );
2255  mLayer->setIntervalMapUnitScale( mIntervalUnitWidget->getMapUnitScale() );
2256  emit changed();
2257  }
2258 }
2259 
2260 void QgsHashedLineSymbolLayerWidget::mOffsetUnitWidget_changed()
2261 {
2262  if ( mLayer )
2263  {
2264  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
2265  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
2266  emit changed();
2267  }
2268 }
2269 
2270 void QgsHashedLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed()
2271 {
2272  if ( mLayer )
2273  {
2274  mLayer->setOffsetAlongLineUnit( mOffsetAlongLineUnitWidget->unit() );
2275  mLayer->setOffsetAlongLineMapUnitScale( mOffsetAlongLineUnitWidget->getMapUnitScale() );
2276  }
2277  emit changed();
2278 }
2279 
2280 void QgsHashedLineSymbolLayerWidget::hashLengthUnitWidgetChanged()
2281 {
2282  if ( mLayer )
2283  {
2284  mLayer->setHashLengthUnit( mHashLengthUnitWidget->unit() );
2285  mLayer->setHashLengthMapUnitScale( mHashLengthUnitWidget->getMapUnitScale() );
2286  }
2287  emit changed();
2288 }
2289 
2290 void QgsHashedLineSymbolLayerWidget::averageAngleUnitChanged()
2291 {
2292  if ( mLayer )
2293  {
2294  mLayer->setAverageAngleUnit( mAverageAngleUnit->unit() );
2295  mLayer->setAverageAngleMapUnitScale( mAverageAngleUnit->getMapUnitScale() );
2296  }
2297  emit changed();
2298 }
2299 
2300 void QgsHashedLineSymbolLayerWidget::setAverageAngle( double val )
2301 {
2302  if ( mLayer )
2303  {
2304  mLayer->setAverageAngleLength( val );
2305  emit changed();
2306  }
2307 }
2308 
2310 
2311 
2313  : QgsSymbolLayerWidget( parent, vl )
2314 {
2315  mLayer = nullptr;
2316 
2317  setupUi( this );
2318 
2319  mSvgSelectorWidget->sourceLineEdit()->setPropertyOverrideToolButtonVisible( true );
2320  mSvgSelectorWidget->sourceLineEdit()->setLastPathSettingsKey( QStringLiteral( "/UI/lastSVGMarkerDir" ) );
2321 
2322  connect( mSvgSelectorWidget->sourceLineEdit(), &QgsSvgSourceLineEdit::sourceChanged, this, &QgsSvgMarkerSymbolLayerWidget::svgSourceChanged );
2323  connect( mChangeColorButton, &QgsColorButton::colorChanged, this, &QgsSvgMarkerSymbolLayerWidget::mChangeColorButton_colorChanged );
2324  connect( mChangeStrokeColorButton, &QgsColorButton::colorChanged, this, &QgsSvgMarkerSymbolLayerWidget::mChangeStrokeColorButton_colorChanged );
2325  connect( mStrokeWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
2326  connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
2327  connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
2328  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
2329  connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSvgMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
2330  connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSvgMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
2337  mChangeColorButton->setAllowOpacity( true );
2338  mChangeColorButton->setColorDialogTitle( tr( "Select Fill color" ) );
2339  mChangeColorButton->setContext( QStringLiteral( "symbology" ) );
2340  mChangeStrokeColorButton->setAllowOpacity( true );
2341  mChangeStrokeColorButton->setColorDialogTitle( tr( "Select Stroke Color" ) );
2342  mChangeStrokeColorButton->setContext( QStringLiteral( "symbology" ) );
2343 
2344  mFillColorDDBtn->registerLinkedWidget( mChangeColorButton );
2345  mStrokeColorDDBtn->registerLinkedWidget( mChangeStrokeColorButton );
2346 
2347  spinOffsetX->setClearValue( 0.0 );
2348  spinOffsetY->setClearValue( 0.0 );
2349  spinAngle->setClearValue( 0.0 );
2350 
2351  connect( spinWidth, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setWidth );
2352  connect( spinHeight, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setHeight );
2353  connect( mLockAspectRatio, static_cast < void ( QgsRatioLockButton::* )( bool ) > ( &QgsRatioLockButton::lockChanged ), this, &QgsSvgMarkerSymbolLayerWidget::lockAspectRatioChanged );
2354  connect( spinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setAngle );
2355  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setOffset );
2356  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setOffset );
2357  connect( this, &QgsSymbolLayerWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::updateAssistantSymbol );
2358 
2359  connect( mSvgSelectorWidget, &QgsSvgSelectorWidget::svgSelected, this, &QgsSvgMarkerSymbolLayerWidget::setSvgPath );
2360 
2361 
2362  //make a temporary symbol for the size assistant preview
2363  mAssistantPreviewSymbol.reset( new QgsMarkerSymbol() );
2364 
2365  if ( vectorLayer() )
2366  {
2367  mWidthDDBtn->setSymbol( mAssistantPreviewSymbol );
2368  mHeightDDBtn->setSymbol( mAssistantPreviewSymbol );
2369  }
2370 }
2371 
2372 #include <QTime>
2373 #include <QAbstractListModel>
2374 #include <QPixmapCache>
2375 #include <QStyle>
2376 
2377 
2378 
2379 
2380 void QgsSvgMarkerSymbolLayerWidget::setGuiForSvg( const QgsSvgMarkerSymbolLayer *layer, bool skipDefaultColors )
2381 {
2382  if ( !layer )
2383  {
2384  return;
2385  }
2386 
2387  //activate gui for svg parameters only if supported by the svg file
2388  bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2389  QColor defaultFill, defaultStroke;
2390  double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2391  bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
2392  QgsApplication::svgCache()->containsParams( layer->path(), hasFillParam, hasDefaultFillColor, defaultFill,
2393  hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity,
2394  hasStrokeParam, hasDefaultStrokeColor, defaultStroke,
2395  hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth,
2396  hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
2397  mChangeColorButton->setEnabled( hasFillParam );
2398  mChangeColorButton->setAllowOpacity( hasFillOpacityParam );
2399  mChangeStrokeColorButton->setEnabled( hasStrokeParam );
2400  mChangeStrokeColorButton->setAllowOpacity( hasStrokeOpacityParam );
2401  mStrokeWidthSpinBox->setEnabled( hasStrokeWidthParam );
2402 
2403  if ( hasFillParam )
2404  {
2405  QColor fill = layer->fillColor();
2406  double existingOpacity = hasFillOpacityParam ? fill.alphaF() : 1.0;
2407  if ( hasDefaultFillColor && !skipDefaultColors )
2408  {
2409  fill = defaultFill;
2410  }
2411  fill.setAlphaF( hasDefaultFillOpacity ? defaultFillOpacity : existingOpacity );
2412  mChangeColorButton->setColor( fill );
2413  }
2414  if ( hasStrokeParam )
2415  {
2416  QColor stroke = layer->strokeColor();
2417  double existingOpacity = hasStrokeOpacityParam ? stroke.alphaF() : 1.0;
2418  if ( hasDefaultStrokeColor && !skipDefaultColors )
2419  {
2420  stroke = defaultStroke;
2421  }
2422  stroke.setAlphaF( hasDefaultStrokeOpacity ? defaultStrokeOpacity : existingOpacity );
2423  mChangeStrokeColorButton->setColor( stroke );
2424  }
2425 
2426  whileBlocking( mSvgSelectorWidget->sourceLineEdit() )->setSource( layer->path() );
2427 
2428  mStrokeWidthSpinBox->blockSignals( true );
2429  mStrokeWidthSpinBox->setValue( hasDefaultStrokeWidth ? defaultStrokeWidth : layer->strokeWidth() );
2430  mStrokeWidthSpinBox->blockSignals( false );
2431 
2432  bool preservedAspectRatio = layer->preservedAspectRatio();
2433  spinHeight->blockSignals( true );
2434  if ( preservedAspectRatio )
2435  {
2436  spinHeight->setValue( layer->size() * layer->defaultAspectRatio() );
2437  }
2438  else
2439  {
2440  spinHeight->setValue( layer->size() * layer->fixedAspectRatio() );
2441  }
2442  spinHeight->setEnabled( layer->defaultAspectRatio() > 0.0 );
2443  spinHeight->blockSignals( false );
2444  whileBlocking( mLockAspectRatio )->setLocked( preservedAspectRatio );
2445 }
2446 
2447 void QgsSvgMarkerSymbolLayerWidget::updateAssistantSymbol()
2448 {
2449  for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
2450  {
2451  mAssistantPreviewSymbol->deleteSymbolLayer( i );
2452  }
2453  mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
2455  if ( ddSize )
2456  mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
2457 }
2458 
2459 
2461 {
2462  if ( !layer )
2463  {
2464  return;
2465  }
2466 
2467  if ( layer->layerType() != QLatin1String( "SvgMarker" ) )
2468  return;
2469 
2470  // layer type is correct, we can do the cast
2471  mLayer = static_cast<QgsSvgMarkerSymbolLayer *>( layer );
2472 
2473  // set values
2474  mSvgSelectorWidget->setSvgPath( mLayer->path() );
2475 
2476  spinWidth->blockSignals( true );
2477  spinWidth->setValue( mLayer->size() );
2478  spinWidth->blockSignals( false );
2479  spinAngle->blockSignals( true );
2480  spinAngle->setValue( mLayer->angle() );
2481  spinAngle->blockSignals( false );
2482 
2483  // without blocking signals the value gets changed because of slot setOffset()
2484  spinOffsetX->blockSignals( true );
2485  spinOffsetX->setValue( mLayer->offset().x() );
2486  spinOffsetX->blockSignals( false );
2487  spinOffsetY->blockSignals( true );
2488  spinOffsetY->setValue( mLayer->offset().y() );
2489  spinOffsetY->blockSignals( false );
2490 
2491  mSizeUnitWidget->blockSignals( true );
2492  mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
2493  mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
2494  mSizeUnitWidget->blockSignals( false );
2495  mStrokeWidthUnitWidget->blockSignals( true );
2496  mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
2497  mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
2498  mStrokeWidthUnitWidget->blockSignals( false );
2499  mOffsetUnitWidget->blockSignals( true );
2500  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
2501  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
2502  mOffsetUnitWidget->blockSignals( false );
2503 
2504  //anchor points
2505  mHorizontalAnchorComboBox->blockSignals( true );
2506  mVerticalAnchorComboBox->blockSignals( true );
2507  mHorizontalAnchorComboBox->setCurrentIndex( mLayer->horizontalAnchorPoint() );
2508  mVerticalAnchorComboBox->setCurrentIndex( mLayer->verticalAnchorPoint() );
2509  mHorizontalAnchorComboBox->blockSignals( false );
2510  mVerticalAnchorComboBox->blockSignals( false );
2511 
2512  setGuiForSvg( mLayer, true );
2513 
2523 
2524  registerDataDefinedButton( mSvgSelectorWidget->sourceLineEdit()->propertyOverrideToolButton(), QgsSymbolLayer::PropertyName );
2525 
2526  updateAssistantSymbol();
2527 }
2528 
2530 {
2531  return mLayer;
2532 }
2533 
2535 {
2537  mSvgSelectorWidget->sourceLineEdit()->setMessageBar( context.messageBar() );
2538 }
2539 
2541 {
2542  mLayer->setPath( name );
2543  whileBlocking( mSvgSelectorWidget->sourceLineEdit() )->setSource( name );
2544 
2545  setGuiForSvg( mLayer );
2546  emit changed();
2547 }
2548 
2549 void QgsSvgMarkerSymbolLayerWidget::setWidth()
2550 {
2551  double defaultAspectRatio = mLayer->defaultAspectRatio();
2552  double fixedAspectRatio = 0.0;
2553  spinHeight->blockSignals( true );
2554  if ( defaultAspectRatio <= 0.0 )
2555  {
2556  spinHeight->setValue( spinWidth->value() );
2557  }
2558  else if ( mLockAspectRatio->locked() )
2559  {
2560  spinHeight->setValue( spinWidth->value() * defaultAspectRatio );
2561  }
2562  else
2563  {
2564  fixedAspectRatio = spinHeight->value() / spinWidth->value();
2565  }
2566  spinHeight->blockSignals( false );
2567  mLayer->setSize( spinWidth->value() );
2568  mLayer->setFixedAspectRatio( fixedAspectRatio );
2569  emit changed();
2570 }
2571 
2572 void QgsSvgMarkerSymbolLayerWidget::setHeight()
2573 {
2574  double defaultAspectRatio = mLayer->defaultAspectRatio();
2575  double fixedAspectRatio = 0.0;
2576  spinWidth->blockSignals( true );
2577  if ( defaultAspectRatio <= 0.0 )
2578  {
2579  spinWidth->setValue( spinHeight->value() );
2580  }
2581  else if ( mLockAspectRatio->locked() )
2582  {
2583  spinWidth->setValue( spinHeight->value() / defaultAspectRatio );
2584  }
2585  else
2586  {
2587  fixedAspectRatio = spinHeight->value() / spinWidth->value();
2588  }
2589  spinWidth->blockSignals( false );
2590  mLayer->setSize( spinWidth->value() );
2591  mLayer->setFixedAspectRatio( fixedAspectRatio );
2592  emit changed();
2593 }
2594 
2595 void QgsSvgMarkerSymbolLayerWidget::lockAspectRatioChanged( const bool locked )
2596 {
2597  //spinHeight->setEnabled( !locked );
2598  double defaultAspectRatio = mLayer->defaultAspectRatio();
2599  if ( defaultAspectRatio <= 0.0 )
2600  {
2601  whileBlocking( mLockAspectRatio )->setLocked( true );
2602  }
2603  else if ( locked )
2604  {
2605  mLayer->setFixedAspectRatio( 0.0 );
2606  setWidth();
2607  }
2608  else
2609  {
2610  mLayer->setFixedAspectRatio( spinHeight->value() / spinWidth->value() );
2611  }
2612  //emit changed();
2613 }
2614 
2615 void QgsSvgMarkerSymbolLayerWidget::setAngle()
2616 {
2617  mLayer->setAngle( spinAngle->value() );
2618  emit changed();
2619 }
2620 
2621 void QgsSvgMarkerSymbolLayerWidget::setOffset()
2622 {
2623  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
2624  emit changed();
2625 }
2626 
2627 void QgsSvgMarkerSymbolLayerWidget::svgSourceChanged( const QString &text )
2628 {
2629  mLayer->setPath( text );
2630  setGuiForSvg( mLayer );
2631  emit changed();
2632 }
2633 
2634 void QgsSvgMarkerSymbolLayerWidget::mChangeColorButton_colorChanged( const QColor &color )
2635 {
2636  if ( !mLayer )
2637  {
2638  return;
2639  }
2640 
2641  mLayer->setFillColor( color );
2642  emit changed();
2643 }
2644 
2645 void QgsSvgMarkerSymbolLayerWidget::mChangeStrokeColorButton_colorChanged( const QColor &color )
2646 {
2647  if ( !mLayer )
2648  {
2649  return;
2650  }
2651 
2652  mLayer->setStrokeColor( color );
2653  emit changed();
2654 }
2655 
2656 void QgsSvgMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
2657 {
2658  if ( mLayer )
2659  {
2660  mLayer->setStrokeWidth( d );
2661  emit changed();
2662  }
2663 }
2664 
2665 void QgsSvgMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
2666 {
2667  if ( mLayer )
2668  {
2669  mLayer->setSizeUnit( mSizeUnitWidget->unit() );
2670  mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
2671  emit changed();
2672  }
2673 }
2674 
2675 void QgsSvgMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
2676 {
2677  if ( mLayer )
2678  {
2679  mLayer->setStrokeWidthUnit( mStrokeWidthUnitWidget->unit() );
2680  mLayer->setStrokeWidthMapUnitScale( mStrokeWidthUnitWidget->getMapUnitScale() );
2681  emit changed();
2682  }
2683 }
2684 
2685 void QgsSvgMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
2686 {
2687  if ( mLayer )
2688  {
2689  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
2690  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
2691  emit changed();
2692  }
2693 }
2694 
2695 void QgsSvgMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
2696 {
2697  if ( mLayer )
2698  {
2700  emit changed();
2701  }
2702 }
2703 
2704 void QgsSvgMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
2705 {
2706  if ( mLayer )
2707  {
2709  emit changed();
2710  }
2711 }
2712 
2714 
2716 {
2717  mLayer = nullptr;
2718  setupUi( this );
2719 
2720  mSvgSelectorWidget->sourceLineEdit()->setPropertyOverrideToolButtonVisible( true );
2721 
2722  connect( mTextureWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mTextureWidthSpinBox_valueChanged );
2723  connect( mSvgSelectorWidget->sourceLineEdit(), &QgsSvgSourceLineEdit::sourceChanged, this, &QgsSVGFillSymbolLayerWidget::svgSourceChanged );
2724  connect( mRotationSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mRotationSpinBox_valueChanged );
2725  connect( mChangeColorButton, &QgsColorButton::colorChanged, this, &QgsSVGFillSymbolLayerWidget::mChangeColorButton_colorChanged );
2726  connect( mChangeStrokeColorButton, &QgsColorButton::colorChanged, this, &QgsSVGFillSymbolLayerWidget::mChangeStrokeColorButton_colorChanged );
2727  connect( mStrokeWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
2728  connect( mTextureWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSVGFillSymbolLayerWidget::mTextureWidthUnitWidget_changed );
2729  connect( mSvgStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSVGFillSymbolLayerWidget::mSvgStrokeWidthUnitWidget_changed );
2734 
2735  mRotationSpinBox->setClearValue( 0.0 );
2736 
2737  mChangeColorButton->setColorDialogTitle( tr( "Select Fill Color" ) );
2738  mChangeColorButton->setContext( QStringLiteral( "symbology" ) );
2739  mChangeStrokeColorButton->setColorDialogTitle( tr( "Select Stroke Color" ) );
2740  mChangeStrokeColorButton->setContext( QStringLiteral( "symbology" ) );
2741 
2742  mFilColorDDBtn->registerLinkedWidget( mChangeColorButton );
2743  mStrokeColorDDBtn->registerLinkedWidget( mChangeStrokeColorButton );
2744 
2745  connect( mSvgSelectorWidget, &QgsSvgSelectorWidget::svgSelected, this, &QgsSVGFillSymbolLayerWidget::setFile );
2746 
2747 }
2748 
2750 {
2751  if ( !layer )
2752  {
2753  return;
2754  }
2755 
2756  if ( layer->layerType() != QLatin1String( "SVGFill" ) )
2757  {
2758  return;
2759  }
2760 
2761  mLayer = dynamic_cast<QgsSVGFillSymbolLayer *>( layer );
2762  if ( mLayer )
2763  {
2764  double width = mLayer->patternWidth();
2765  mTextureWidthSpinBox->blockSignals( true );
2766  mTextureWidthSpinBox->setValue( width );
2767  mTextureWidthSpinBox->blockSignals( false );
2768  whileBlocking( mSvgSelectorWidget->sourceLineEdit() )->setSource( mLayer->svgFilePath() );
2769  mRotationSpinBox->blockSignals( true );
2770  mRotationSpinBox->setValue( mLayer->angle() );
2771  mRotationSpinBox->blockSignals( false );
2772  mTextureWidthUnitWidget->blockSignals( true );
2773  mTextureWidthUnitWidget->setUnit( mLayer->patternWidthUnit() );
2774  mTextureWidthUnitWidget->setMapUnitScale( mLayer->patternWidthMapUnitScale() );
2775  mTextureWidthUnitWidget->blockSignals( false );
2776  mSvgStrokeWidthUnitWidget->blockSignals( true );
2777  mSvgStrokeWidthUnitWidget->setUnit( mLayer->svgStrokeWidthUnit() );
2778  mSvgStrokeWidthUnitWidget->setMapUnitScale( mLayer->svgStrokeWidthMapUnitScale() );
2779  mSvgStrokeWidthUnitWidget->blockSignals( false );
2780  mChangeColorButton->blockSignals( true );
2781  mChangeColorButton->setColor( mLayer->svgFillColor() );
2782  mChangeColorButton->blockSignals( false );
2783  mChangeStrokeColorButton->blockSignals( true );
2784  mChangeStrokeColorButton->setColor( mLayer->svgStrokeColor() );
2785  mChangeStrokeColorButton->blockSignals( false );
2786  mStrokeWidthSpinBox->blockSignals( true );
2787  mStrokeWidthSpinBox->setValue( mLayer->svgStrokeWidth() );
2788  mStrokeWidthSpinBox->blockSignals( false );
2789  }
2790  updateParamGui( false );
2791 
2797 
2798  registerDataDefinedButton( mSvgSelectorWidget->sourceLineEdit()->propertyOverrideToolButton(), QgsSymbolLayer::PropertyFile );
2799 }
2800 
2802 {
2803  return mLayer;
2804 }
2805 
2807 {
2809  mSvgSelectorWidget->sourceLineEdit()->setMessageBar( context.messageBar() );
2810 }
2811 
2812 void QgsSVGFillSymbolLayerWidget::mTextureWidthSpinBox_valueChanged( double d )
2813 {
2814  if ( mLayer )
2815  {
2816  mLayer->setPatternWidth( d );
2817  emit changed();
2818  }
2819 }
2820 
2821 void QgsSVGFillSymbolLayerWidget::svgSourceChanged( const QString &text )
2822 {
2823  if ( !mLayer )
2824  {
2825  return;
2826  }
2827 
2828  mLayer->setSvgFilePath( text );
2829  updateParamGui();
2830  emit changed();
2831 }
2832 
2833 void QgsSVGFillSymbolLayerWidget::setFile( const QString &name )
2834 {
2835  mLayer->setSvgFilePath( name );
2836  whileBlocking( mSvgSelectorWidget->sourceLineEdit() )->setSource( name );
2837 
2838  updateParamGui();
2839  emit changed();
2840 }
2841 
2842 
2843 void QgsSVGFillSymbolLayerWidget::mRotationSpinBox_valueChanged( double d )
2844 {
2845  if ( mLayer )
2846  {
2847  mLayer->setAngle( d );
2848  emit changed();
2849  }
2850 }
2851 
2853 {
2854  //activate gui for svg parameters only if supported by the svg file
2855  bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2856  QColor defaultFill, defaultStroke;
2857  double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2858  bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
2859  QgsApplication::svgCache()->containsParams( mSvgSelectorWidget->sourceLineEdit()->source(), hasFillParam, hasDefaultFillColor, defaultFill,
2860  hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity,
2861  hasStrokeParam, hasDefaultStrokeColor, defaultStroke,
2862  hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth,
2863  hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
2864  if ( resetValues )
2865  {
2866  QColor fill = mChangeColorButton->color();
2867  double newOpacity = hasFillOpacityParam ? fill.alphaF() : 1.0;
2868  if ( hasDefaultFillColor )
2869  {
2870  fill = defaultFill;
2871  }
2872  fill.setAlphaF( hasDefaultFillOpacity ? defaultFillOpacity : newOpacity );
2873  mChangeColorButton->setColor( fill );
2874  }
2875  mChangeColorButton->setEnabled( hasFillParam );
2876  mChangeColorButton->setAllowOpacity( hasFillOpacityParam );
2877  if ( resetValues )
2878  {
2879  QColor stroke = mChangeStrokeColorButton->color();
2880  double newOpacity = hasStrokeOpacityParam ? stroke.alphaF() : 1.0;
2881  if ( hasDefaultStrokeColor )
2882  {
2883  stroke = defaultStroke;
2884  }
2885  stroke.setAlphaF( hasDefaultStrokeOpacity ? defaultStrokeOpacity : newOpacity );
2886  mChangeStrokeColorButton->setColor( stroke );
2887  }
2888  mChangeStrokeColorButton->setEnabled( hasStrokeParam );
2889  mChangeStrokeColorButton->setAllowOpacity( hasStrokeOpacityParam );
2890  if ( hasDefaultStrokeWidth && resetValues )
2891  {
2892  mStrokeWidthSpinBox->setValue( defaultStrokeWidth );
2893  }
2894  mStrokeWidthSpinBox->setEnabled( hasStrokeWidthParam );
2895 }
2896 
2897 void QgsSVGFillSymbolLayerWidget::mChangeColorButton_colorChanged( const QColor &color )
2898 {
2899  if ( !mLayer )
2900  {
2901  return;
2902  }
2903 
2904  mLayer->setSvgFillColor( color );
2905  emit changed();
2906 }
2907 
2908 void QgsSVGFillSymbolLayerWidget::mChangeStrokeColorButton_colorChanged( const QColor &color )
2909 {
2910  if ( !mLayer )
2911  {
2912  return;
2913  }
2914 
2915  mLayer->setSvgStrokeColor( color );
2916  emit changed();
2917 }
2918 
2919 void QgsSVGFillSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
2920 {
2921  if ( mLayer )
2922  {
2923  mLayer->setSvgStrokeWidth( d );
2924  emit changed();
2925  }
2926 }
2927 
2928 void QgsSVGFillSymbolLayerWidget::mTextureWidthUnitWidget_changed()
2929 {
2930  if ( mLayer )
2931  {
2932  mLayer->setPatternWidthUnit( mTextureWidthUnitWidget->unit() );
2933  mLayer->setPatternWidthMapUnitScale( mTextureWidthUnitWidget->getMapUnitScale() );
2934  emit changed();
2935  }
2936 }
2937 
2938 void QgsSVGFillSymbolLayerWidget::mSvgStrokeWidthUnitWidget_changed()
2939 {
2940  if ( mLayer )
2941  {
2942  mLayer->setSvgStrokeWidthUnit( mSvgStrokeWidthUnitWidget->unit() );
2943  mLayer->setSvgStrokeWidthMapUnitScale( mSvgStrokeWidthUnitWidget->getMapUnitScale() );
2944  emit changed();
2945  }
2946 }
2947 
2949 
2951  QgsSymbolLayerWidget( parent, vl )
2952 {
2953  setupUi( this );
2954  connect( mAngleSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLinePatternFillSymbolLayerWidget::mAngleSpinBox_valueChanged );
2955  connect( mDistanceSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLinePatternFillSymbolLayerWidget::mDistanceSpinBox_valueChanged );
2956  connect( mOffsetSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLinePatternFillSymbolLayerWidget::mOffsetSpinBox_valueChanged );
2957  connect( mDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsLinePatternFillSymbolLayerWidget::mDistanceUnitWidget_changed );
2958  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsLinePatternFillSymbolLayerWidget::mOffsetUnitWidget_changed );
2963  mOffsetSpinBox->setClearValue( 0 );
2964  mAngleSpinBox->setClearValue( 0 );
2965 }
2966 
2968 {
2969  if ( layer->layerType() != QLatin1String( "LinePatternFill" ) )
2970  {
2971  return;
2972  }
2973 
2974  QgsLinePatternFillSymbolLayer *patternLayer = static_cast<QgsLinePatternFillSymbolLayer *>( layer );
2975  if ( patternLayer )
2976  {
2977  mLayer = patternLayer;
2978  mAngleSpinBox->blockSignals( true );
2979  mAngleSpinBox->setValue( mLayer->lineAngle() );
2980  mAngleSpinBox->blockSignals( false );
2981  mDistanceSpinBox->blockSignals( true );
2982  mDistanceSpinBox->setValue( mLayer->distance() );
2983  mDistanceSpinBox->blockSignals( false );
2984  mOffsetSpinBox->blockSignals( true );
2985  mOffsetSpinBox->setValue( mLayer->offset() );
2986  mOffsetSpinBox->blockSignals( false );
2987 
2988  //units
2989  mDistanceUnitWidget->blockSignals( true );
2990  mDistanceUnitWidget->setUnit( mLayer->distanceUnit() );
2991  mDistanceUnitWidget->setMapUnitScale( mLayer->distanceMapUnitScale() );
2992  mDistanceUnitWidget->blockSignals( false );
2993  mOffsetUnitWidget->blockSignals( true );
2994  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
2995  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
2996  mOffsetUnitWidget->blockSignals( false );
2997  }
2998 
3001 }
3002 
3004 {
3005  return mLayer;
3006 }
3007 
3008 void QgsLinePatternFillSymbolLayerWidget::mAngleSpinBox_valueChanged( double d )
3009 {
3010  if ( mLayer )
3011  {
3012  mLayer->setLineAngle( d );
3013  emit changed();
3014  }
3015 }
3016 
3017 void QgsLinePatternFillSymbolLayerWidget::mDistanceSpinBox_valueChanged( double d )
3018 {
3019  if ( mLayer )
3020  {
3021  mLayer->setDistance( d );
3022  emit changed();
3023  }
3024 }
3025 
3026 void QgsLinePatternFillSymbolLayerWidget::mOffsetSpinBox_valueChanged( double d )
3027 {
3028  if ( mLayer )
3029  {
3030  mLayer->setOffset( d );
3031  emit changed();
3032  }
3033 }
3034 
3035 void QgsLinePatternFillSymbolLayerWidget::mDistanceUnitWidget_changed()
3036 {
3037  if ( mLayer )
3038  {
3039  mLayer->setDistanceUnit( mDistanceUnitWidget->unit() );
3040  mLayer->setDistanceMapUnitScale( mDistanceUnitWidget->getMapUnitScale() );
3041  emit changed();
3042  }
3043 }
3044 
3045 void QgsLinePatternFillSymbolLayerWidget::mOffsetUnitWidget_changed()
3046 {
3047  if ( mLayer )
3048  {
3049  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
3050  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
3051  emit changed();
3052  }
3053 }
3054 
3056 
3058  QgsSymbolLayerWidget( parent, vl )
3059 {
3060  setupUi( this );
3061  connect( mHorizontalDistanceSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceSpinBox_valueChanged );
3062  connect( mVerticalDistanceSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceSpinBox_valueChanged );
3063  connect( mHorizontalDisplacementSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementSpinBox_valueChanged );
3064  connect( mVerticalDisplacementSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementSpinBox_valueChanged );
3065  connect( mHorizontalOffsetSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetSpinBox_valueChanged );
3066  connect( mVerticalOffsetSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetSpinBox_valueChanged );
3067  connect( mHorizontalDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceUnitWidget_changed );
3068  connect( mVerticalDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceUnitWidget_changed );
3069  connect( mHorizontalDisplacementUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementUnitWidget_changed );
3070  connect( mVerticalDisplacementUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementUnitWidget_changed );
3071  connect( mHorizontalOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetUnitWidget_changed );
3072  connect( mVerticalOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetUnitWidget_changed );
3085 }
3086 
3087 
3089 {
3090  if ( !layer || layer->layerType() != QLatin1String( "PointPatternFill" ) )
3091  {
3092  return;
3093  }
3094 
3095  mLayer = static_cast<QgsPointPatternFillSymbolLayer *>( layer );
3096  whileBlocking( mHorizontalDistanceSpinBox )->setValue( mLayer->distanceX() );
3097  whileBlocking( mVerticalDistanceSpinBox )->setValue( mLayer->distanceY() );
3098  whileBlocking( mHorizontalDisplacementSpinBox )->setValue( mLayer->displacementX() );
3099  whileBlocking( mVerticalDisplacementSpinBox )->setValue( mLayer->displacementY() );
3100  whileBlocking( mHorizontalOffsetSpinBox )->setValue( mLayer->offsetX() );
3101  whileBlocking( mVerticalOffsetSpinBox )->setValue( mLayer->offsetY() );
3102 
3103  mHorizontalDistanceUnitWidget->blockSignals( true );
3104  mHorizontalDistanceUnitWidget->setUnit( mLayer->distanceXUnit() );
3105  mHorizontalDistanceUnitWidget->setMapUnitScale( mLayer->distanceXMapUnitScale() );
3106  mHorizontalDistanceUnitWidget->blockSignals( false );
3107  mVerticalDistanceUnitWidget->blockSignals( true );
3108  mVerticalDistanceUnitWidget->setUnit( mLayer->distanceYUnit() );
3109  mVerticalDistanceUnitWidget->setMapUnitScale( mLayer->distanceYMapUnitScale() );
3110  mVerticalDistanceUnitWidget->blockSignals( false );
3111  mHorizontalDisplacementUnitWidget->blockSignals( true );
3112  mHorizontalDisplacementUnitWidget->setUnit( mLayer->displacementXUnit() );
3113  mHorizontalDisplacementUnitWidget->setMapUnitScale( mLayer->displacementXMapUnitScale() );
3114  mHorizontalDisplacementUnitWidget->blockSignals( false );
3115  mVerticalDisplacementUnitWidget->blockSignals( true );
3116  mVerticalDisplacementUnitWidget->setUnit( mLayer->displacementYUnit() );
3117  mVerticalDisplacementUnitWidget->setMapUnitScale( mLayer->displacementYMapUnitScale() );
3118  mVerticalDisplacementUnitWidget->blockSignals( false );
3119  mHorizontalOffsetUnitWidget->blockSignals( true );
3120  mHorizontalOffsetUnitWidget->setUnit( mLayer->offsetXUnit() );
3121  mHorizontalOffsetUnitWidget->setMapUnitScale( mLayer->offsetXMapUnitScale() );
3122  mHorizontalOffsetUnitWidget->blockSignals( false );
3123  mVerticalOffsetUnitWidget->blockSignals( true );
3124  mVerticalOffsetUnitWidget->setUnit( mLayer->offsetYUnit() );
3125  mVerticalOffsetUnitWidget->setMapUnitScale( mLayer->offsetYMapUnitScale() );
3126  mVerticalOffsetUnitWidget->blockSignals( false );
3127 
3128  registerDataDefinedButton( mHorizontalDistanceDDBtn, QgsSymbolLayer::PropertyDistanceX );
3130  registerDataDefinedButton( mHorizontalDisplacementDDBtn, QgsSymbolLayer::PropertyDisplacementX );
3134 }
3135 
3137 {
3138  return mLayer;
3139 }
3140 
3141 void QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceSpinBox_valueChanged( double d )
3142 {
3143  if ( mLayer )
3144  {
3145  mLayer->setDistanceX( d );
3146  emit changed();
3147  }
3148 }
3149 
3150 void QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceSpinBox_valueChanged( double d )
3151 {
3152  if ( mLayer )
3153  {
3154  mLayer->setDistanceY( d );
3155  emit changed();
3156  }
3157 }
3158 
3159 void QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementSpinBox_valueChanged( double d )
3160 {
3161  if ( mLayer )
3162  {
3163  mLayer->setDisplacementX( d );
3164  emit changed();
3165  }
3166 }
3167 
3168 void QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementSpinBox_valueChanged( double d )
3169 {
3170  if ( mLayer )
3171  {
3172  mLayer->setDisplacementY( d );
3173  emit changed();
3174  }
3175 }
3176 
3177 void QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetSpinBox_valueChanged( double d )
3178 {
3179  if ( mLayer )
3180  {
3181  mLayer->setOffsetX( d );
3182  emit changed();
3183  }
3184 }
3185 
3186 void QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetSpinBox_valueChanged( double d )
3187 {
3188  if ( mLayer )
3189  {
3190  mLayer->setOffsetY( d );
3191  emit changed();
3192  }
3193 }
3194 
3195 void QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceUnitWidget_changed()
3196 {
3197  if ( mLayer )
3198  {
3199  mLayer->setDistanceXUnit( mHorizontalDistanceUnitWidget->unit() );
3200  mLayer->setDistanceXMapUnitScale( mHorizontalDistanceUnitWidget->getMapUnitScale() );
3201  emit changed();
3202  }
3203 }
3204 
3205 void QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceUnitWidget_changed()
3206 {
3207  if ( mLayer )
3208  {
3209  mLayer->setDistanceYUnit( mVerticalDistanceUnitWidget->unit() );
3210  mLayer->setDistanceYMapUnitScale( mVerticalDistanceUnitWidget->getMapUnitScale() );
3211  emit changed();
3212  }
3213 }
3214 
3215 void QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementUnitWidget_changed()
3216 {
3217  if ( mLayer )
3218  {
3219  mLayer->setDisplacementXUnit( mHorizontalDisplacementUnitWidget->unit() );
3220  mLayer->setDisplacementXMapUnitScale( mHorizontalDisplacementUnitWidget->getMapUnitScale() );
3221  emit changed();
3222  }
3223 }
3224 
3225 void QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementUnitWidget_changed()
3226 {
3227  if ( mLayer )
3228  {
3229  mLayer->setDisplacementYUnit( mVerticalDisplacementUnitWidget->unit() );
3230  mLayer->setDisplacementYMapUnitScale( mVerticalDisplacementUnitWidget->getMapUnitScale() );
3231  emit changed();
3232  }
3233 }
3234 
3235 void QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetUnitWidget_changed()
3236 {
3237  if ( mLayer )
3238  {
3239  mLayer->setOffsetXUnit( mHorizontalOffsetUnitWidget->unit() );
3240  mLayer->setOffsetXMapUnitScale( mHorizontalOffsetUnitWidget->getMapUnitScale() );
3241  emit changed();
3242  }
3243 }
3244 
3245 void QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetUnitWidget_changed()
3246 {
3247  if ( mLayer )
3248  {
3249  mLayer->setOffsetYUnit( mVerticalOffsetUnitWidget->unit() );
3250  mLayer->setOffsetYMapUnitScale( mVerticalOffsetUnitWidget->getMapUnitScale() );
3251  emit changed();
3252  }
3253 }
3254 
3256 
3258  : QgsSymbolLayerWidget( parent, vl )
3259 {
3260  mLayer = nullptr;
3261 
3262  setupUi( this );
3263  connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
3264  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
3265  connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
3266  connect( mStrokeWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
3267  connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
3268  connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
3275 
3276  widgetChar = new CharacterWidget();
3277  scrollArea->setWidget( widgetChar );
3278  scrollArea->setVerticalOnly( true );
3279 
3280  btnColor->setAllowOpacity( true );
3281  btnColor->setColorDialogTitle( tr( "Select Symbol Fill Color" ) );
3282  btnColor->setContext( QStringLiteral( "symbology" ) );
3283  btnStrokeColor->setAllowOpacity( true );
3284  btnStrokeColor->setColorDialogTitle( tr( "Select Symbol Stroke Color" ) );
3285  btnStrokeColor->setContext( QStringLiteral( "symbology" ) );
3286 
3287  mColorDDBtn->registerLinkedWidget( btnColor );
3288  mStrokeColorDDBtn->registerLinkedWidget( btnStrokeColor );
3289 
3290  spinOffsetX->setClearValue( 0.0 );
3291  spinOffsetY->setClearValue( 0.0 );
3292  spinAngle->setClearValue( 0.0 );
3293 
3294  //make a temporary symbol for the size assistant preview
3295  mAssistantPreviewSymbol.reset( new QgsMarkerSymbol() );
3296 
3297  if ( vectorLayer() )
3298  mSizeDDBtn->setSymbol( mAssistantPreviewSymbol );
3299 
3300  connect( cboFont, &QFontComboBox::currentFontChanged, this, &QgsFontMarkerSymbolLayerWidget::setFontFamily );
3301  connect( mFontStyleComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::mFontStyleComboBox_currentIndexChanged );
3302  connect( spinSize, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setSize );
3303  connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::penJoinStyleChanged );
3306  connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::penJoinStyleChanged );
3307  connect( spinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setAngle );
3308  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setOffset );
3309  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setOffset );
3311  connect( mCharLineEdit, &QLineEdit::textChanged, this, &QgsFontMarkerSymbolLayerWidget::setCharacterFromText );
3312 
3313  connect( this, &QgsSymbolLayerWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::updateAssistantSymbol );
3314 }
3315 
3317 {
3318  if ( layer->layerType() != QLatin1String( "FontMarker" ) )
3319  return;
3320 
3321  // layer type is correct, we can do the cast
3322  mLayer = static_cast<QgsFontMarkerSymbolLayer *>( layer );
3323 
3324  mRefFont.setFamily( mLayer->fontFamily() );
3325  mRefFont.setStyleName( QgsFontUtils::translateNamedStyle( mLayer->fontStyle() ) );
3326 
3327  mFontStyleComboBox->blockSignals( true );
3328  populateFontStyleComboBox();
3329  mFontStyleComboBox->blockSignals( false );
3330 
3331  // set values
3332  whileBlocking( cboFont )->setCurrentFont( mRefFont );
3333  whileBlocking( spinSize )->setValue( mLayer->size() );
3334  whileBlocking( btnColor )->setColor( mLayer->color() );
3335  whileBlocking( btnStrokeColor )->setColor( mLayer->strokeColor() );
3336  whileBlocking( mStrokeWidthSpinBox )->setValue( mLayer->strokeWidth() );
3337  whileBlocking( spinAngle )->setValue( mLayer->angle() );
3338 
3339  widgetChar->blockSignals( true );
3340  widgetChar->setFont( mRefFont );
3341  if ( mLayer->character().length() == 1 )
3342  {
3343  widgetChar->setCharacter( mLayer->character().at( 0 ) );
3344  }
3345  widgetChar->blockSignals( false );
3346  whileBlocking( mCharLineEdit )->setText( mLayer->character() );
3347  mCharPreview->setFont( mRefFont );
3348 
3349  //block
3350  whileBlocking( spinOffsetX )->setValue( mLayer->offset().x() );
3351  whileBlocking( spinOffsetY )->setValue( mLayer->offset().y() );
3352 
3353  mSizeUnitWidget->blockSignals( true );
3354  mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
3355  mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
3356  mSizeUnitWidget->blockSignals( false );
3357 
3358  mStrokeWidthUnitWidget->blockSignals( true );
3359  mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
3360  mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
3361  mStrokeWidthUnitWidget->blockSignals( false );
3362 
3363  mOffsetUnitWidget->blockSignals( true );
3364  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
3365  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
3366  mOffsetUnitWidget->blockSignals( false );
3367 
3368  whileBlocking( cboJoinStyle )->setPenJoinStyle( mLayer->penJoinStyle() );
3369 
3370  //anchor points
3371  whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mLayer->horizontalAnchorPoint() );
3372  whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mLayer->verticalAnchorPoint() );
3373 
3386 
3387  updateAssistantSymbol();
3388 }
3389 
3391 {
3392  return mLayer;
3393 }
3394 
3396 {
3397  if ( mLayer )
3398  {
3399  mLayer->setFontFamily( font.family() );
3400  mRefFont.setFamily( font.family() );
3401  widgetChar->setFont( mRefFont );
3402  mCharPreview->setFont( mRefFont );
3403  populateFontStyleComboBox();
3404  emit changed();
3405  }
3406 }
3407 
3408 void QgsFontMarkerSymbolLayerWidget::setFontStyle( const QString &style )
3409 {
3410  if ( mLayer )
3411  {
3412  QgsFontUtils::updateFontViaStyle( mRefFont, style );
3414  widgetChar->setFont( mRefFont );
3415  mCharPreview->setFont( mRefFont );
3416  emit changed();
3417  }
3418 }
3419 
3420 void QgsFontMarkerSymbolLayerWidget::setColor( const QColor &color )
3421 {
3422  mLayer->setColor( color );
3423  emit changed();
3424 }
3425 
3427 {
3428  mLayer->setStrokeColor( color );
3429  emit changed();
3430 }
3431 
3433 {
3434  mLayer->setSize( size );
3435  //widgetChar->updateSize(size);
3436  emit changed();
3437 }
3438 
3440 {
3441  mLayer->setAngle( angle );
3442  emit changed();
3443 }
3444 
3446 {
3447  mCharPreview->setText( text );
3448 
3449  if ( text.isEmpty() )
3450  return;
3451 
3452  // take the last character of a string for a better experience when users cycle through several characters on their keyboard
3453  QString character = text;
3454  if ( text.contains( QRegularExpression( QStringLiteral( "^0x[0-9a-fA-F]{1,4}$" ) ) ) )
3455  {
3456  bool ok = false;
3457  unsigned int value = text.toUInt( &ok, 0 );
3458  if ( ok )
3459  {
3460  character = QChar( value );
3461  mCharPreview->setText( character );
3462  }
3463  }
3464 
3465  if ( character != mLayer->character() )
3466  {
3467  mLayer->setCharacter( character );
3468  if ( mLayer->character().length() == 1 )
3469  {
3470  whileBlocking( widgetChar )->setCharacter( mLayer->character().at( 0 ) );
3471  }
3472  else
3473  {
3475  }
3476  emit changed();
3477  }
3478 }
3479 
3481 {
3482  if ( mLayer->character().length() > 1 || QGuiApplication::keyboardModifiers() & Qt::ControlModifier )
3483  {
3484  mCharLineEdit->insert( chr );
3485  return;
3486  }
3487 
3488  mLayer->setCharacter( chr );
3489  whileBlocking( mCharLineEdit )->setText( chr );
3490  mCharPreview->setText( chr );
3491  emit changed();
3492 }
3493 
3494 void QgsFontMarkerSymbolLayerWidget::setOffset()
3495 {
3496  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
3497  emit changed();
3498 }
3499 
3500 void QgsFontMarkerSymbolLayerWidget::penJoinStyleChanged()
3501 {
3502  mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
3503  emit changed();
3504 }
3505 
3506 void QgsFontMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
3507 {
3508  if ( mLayer )
3509  {
3510  mLayer->setSizeUnit( mSizeUnitWidget->unit() );
3511  mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
3512  emit changed();
3513  }
3514 }
3515 
3516 void QgsFontMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
3517 {
3518  if ( mLayer )
3519  {
3520  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
3521  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
3522  emit changed();
3523  }
3524 }
3525 
3526 void QgsFontMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
3527 {
3528  if ( mLayer )
3529  {
3530  mLayer->setStrokeWidthUnit( mSizeUnitWidget->unit() );
3531  mLayer->setStrokeWidthMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
3532  emit changed();
3533  }
3534 }
3535 
3536 void QgsFontMarkerSymbolLayerWidget::populateFontStyleComboBox()
3537 {
3538  mFontStyleComboBox->clear();
3539  QStringList styles = mFontDB.styles( mRefFont.family() );
3540  const auto constStyles = styles;
3541  for ( const QString &style : constStyles )
3542  {
3543  mFontStyleComboBox->addItem( style );
3544  }
3545 
3546  QString targetStyle = mFontDB.styleString( mRefFont );
3547  if ( !styles.contains( targetStyle ) )
3548  {
3549  QFont f = QFont( mRefFont.family() );
3550  targetStyle = QFontInfo( f ).styleName();
3551  mRefFont.setStyleName( targetStyle );
3552  }
3553  int curIndx = 0;
3554  int stylIndx = mFontStyleComboBox->findText( targetStyle );
3555  if ( stylIndx > -1 )
3556  {
3557  curIndx = stylIndx;
3558  }
3559 
3560  mFontStyleComboBox->setCurrentIndex( curIndx );
3561 }
3562 
3563 void QgsFontMarkerSymbolLayerWidget::mFontStyleComboBox_currentIndexChanged( int index )
3564 {
3565  Q_UNUSED( index );
3566  setFontStyle( mFontStyleComboBox->currentText() );
3567 }
3568 
3569 void QgsFontMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
3570 {
3571  if ( mLayer )
3572  {
3574  emit changed();
3575  }
3576 }
3577 
3578 void QgsFontMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
3579 {
3580  if ( mLayer )
3581  {
3583  emit changed();
3584  }
3585 }
3586 
3587 void QgsFontMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
3588 {
3589  if ( mLayer )
3590  {
3591  mLayer->setStrokeWidth( d );
3592  emit changed();
3593  }
3594 }
3595 
3596 void QgsFontMarkerSymbolLayerWidget::updateAssistantSymbol()
3597 {
3598  for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
3599  {
3600  mAssistantPreviewSymbol->deleteSymbolLayer( i );
3601  }
3602  mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
3604  if ( ddSize )
3605  mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
3606 }
3607 
3609 
3610 
3612  : QgsSymbolLayerWidget( parent, vl )
3613 {
3614  mLayer = nullptr;
3615 
3616  setupUi( this );
3617  connect( mDrawInsideCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mDrawInsideCheckBox_stateChanged );
3618  connect( mDrawAllPartsCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mDrawAllPartsCheckBox_stateChanged );
3619  connect( mClipPointsCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mClipPointsCheckBox_stateChanged );
3620  connect( mClipOnCurrentPartOnlyCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mClipOnCurrentPartOnlyCheckBox_stateChanged );
3621 }
3622 
3624 {
3625  if ( layer->layerType() != QLatin1String( "CentroidFill" ) )
3626  return;
3627 
3628  // layer type is correct, we can do the cast
3629  mLayer = static_cast<QgsCentroidFillSymbolLayer *>( layer );
3630 
3631  // set values
3632  whileBlocking( mDrawInsideCheckBox )->setChecked( mLayer->pointOnSurface() );
3633  whileBlocking( mDrawAllPartsCheckBox )->setChecked( mLayer->pointOnAllParts() );
3634  whileBlocking( mClipPointsCheckBox )->setChecked( mLayer->clipPoints() );
3635  whileBlocking( mClipOnCurrentPartOnlyCheckBox )->setChecked( mLayer->clipOnCurrentPartOnly() );
3636 }
3637 
3639 {
3640  return mLayer;
3641 }
3642 
3643 void QgsCentroidFillSymbolLayerWidget::mDrawInsideCheckBox_stateChanged( int state )
3644 {
3645  mLayer->setPointOnSurface( state == Qt::Checked );
3646  emit changed();
3647 }
3648 
3649 void QgsCentroidFillSymbolLayerWidget::mDrawAllPartsCheckBox_stateChanged( int state )
3650 {
3651  mLayer->setPointOnAllParts( state == Qt::Checked );
3652  emit changed();
3653 }
3654 
3655 void QgsCentroidFillSymbolLayerWidget::mClipPointsCheckBox_stateChanged( int state )
3656 {
3657  mLayer->setClipPoints( state == Qt::Checked );
3658  emit changed();
3659 }
3660 
3661 void QgsCentroidFillSymbolLayerWidget::mClipOnCurrentPartOnlyCheckBox_stateChanged( int state )
3662 {
3663  mLayer->setClipOnCurrentPartOnly( state == Qt::Checked );
3664  emit changed();
3665 }
3666 
3668 
3670  : QgsSymbolLayerWidget( parent, vl )
3671 {
3672  mLayer = nullptr;
3673 
3674  setupUi( this );
3675 
3676  mImageSourceLineEdit->setLastPathSettingsKey( QStringLiteral( "/UI/lastRasterMarkerImageDir" ) );
3677 
3678  connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsRasterMarkerSymbolLayerWidget::imageSourceChanged );
3679  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
3680  connect( mRotationSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setAngle );
3681  connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
3682  connect( mWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setWidth );
3683  connect( mHeightSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setHeight );
3684  connect( mLockAspectRatio, static_cast < void ( QgsRatioLockButton::* )( bool ) > ( &QgsRatioLockButton::lockChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setLockAspectRatio );
3685 
3690 
3691  mSpinOffsetX->setClearValue( 0.0 );
3692  mSpinOffsetY->setClearValue( 0.0 );
3693  mRotationSpinBox->setClearValue( 0.0 );
3694 
3695  connect( mSpinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setOffset );
3696  connect( mSpinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setOffset );
3697  connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsRasterMarkerSymbolLayerWidget::setOpacity );
3698 
3699  connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
3700  connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
3701 }
3702 
3704 {
3705  if ( !layer )
3706  {
3707  return;
3708  }
3709 
3710  if ( layer->layerType() != QLatin1String( "RasterMarker" ) )
3711  return;
3712 
3713  // layer type is correct, we can do the cast
3714  mLayer = static_cast<QgsRasterMarkerSymbolLayer *>( layer );
3715 
3716  // set values
3717  whileBlocking( mImageSourceLineEdit )->setSource( mLayer->path() );
3718 
3719  whileBlocking( mWidthSpinBox )->setValue( mLayer->size() );
3720  bool preservedAspectRatio = mLayer->preservedAspectRatio();
3721  mHeightSpinBox->blockSignals( true );
3722  if ( preservedAspectRatio )
3723  {
3724  mHeightSpinBox->setValue( mLayer->size() );
3725  }
3726  else
3727  {
3728  mHeightSpinBox->setValue( mLayer->size() * mLayer->fixedAspectRatio() );
3729  }
3730  mHeightSpinBox->setEnabled( mLayer->defaultAspectRatio() > 0.0 );
3731  mHeightSpinBox->blockSignals( false );
3732  whileBlocking( mLockAspectRatio )->setLocked( preservedAspectRatio );
3733 
3734  whileBlocking( mRotationSpinBox )->setValue( mLayer->angle() );
3735  whileBlocking( mOpacityWidget )->setOpacity( mLayer->opacity() );
3736 
3737  whileBlocking( mSpinOffsetX )->setValue( mLayer->offset().x() );
3738  whileBlocking( mSpinOffsetY )->setValue( mLayer->offset().y() );
3739 
3740  mSizeUnitWidget->blockSignals( true );
3741  mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
3742  mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
3743  mSizeUnitWidget->blockSignals( false );
3744  mOffsetUnitWidget->blockSignals( true );
3745  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
3746  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
3747  mOffsetUnitWidget->blockSignals( false );
3748 
3749  //anchor points
3750  whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mLayer->horizontalAnchorPoint() );
3751  whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mLayer->verticalAnchorPoint() );
3752 
3761 
3762  updatePreviewImage();
3763 }
3764 
3766 {
3767  return mLayer;
3768 }
3769 
3771 {
3773  mImageSourceLineEdit->setMessageBar( context.messageBar() );
3774 }
3775 
3776 void QgsRasterMarkerSymbolLayerWidget::imageSourceChanged( const QString &text )
3777 {
3778  mLayer->setPath( text );
3779  updatePreviewImage();
3780  emit changed();
3781 }
3782 
3783 void QgsRasterMarkerSymbolLayerWidget::updatePreviewImage()
3784 {
3785  bool fitsInCache = false;
3786  QImage image = QgsApplication::imageCache()->pathAsImage( mLayer->path(), QSize( 150, 150 ), true, 1.0, fitsInCache );
3787  if ( image.isNull() )
3788  {
3789  mLabelImagePreview->setPixmap( QPixmap() );
3790  return;
3791  }
3792 
3793  QImage previewImage( 150, 150, QImage::Format_ARGB32 );
3794  previewImage.fill( Qt::transparent );
3795  QRect imageRect( ( 150 - image.width() ) / 2.0, ( 150 - image.height() ) / 2.0, image.width(), image.height() );
3796  QPainter p;
3797  p.begin( &previewImage );
3798  //draw a checkerboard background
3799  uchar pixDataRGB[] = { 150, 150, 150, 150,
3800  100, 100, 100, 150,
3801  100, 100, 100, 150,
3802  150, 150, 150, 150
3803  };
3804  QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
3805  QPixmap pix = QPixmap::fromImage( img.scaled( 8, 8 ) );
3806  QBrush checkerBrush;
3807  checkerBrush.setTexture( pix );
3808  p.fillRect( imageRect, checkerBrush );
3809 
3810  if ( mLayer->opacity() < 1.0 )
3811  {
3812  p.setOpacity( mLayer->opacity() );
3813  }
3814 
3815  p.drawImage( imageRect.left(), imageRect.top(), image );
3816  p.end();
3817  mLabelImagePreview->setPixmap( QPixmap::fromImage( previewImage ) );
3818 }
3819 
3820 void QgsRasterMarkerSymbolLayerWidget::setWidth()
3821 {
3822  double defaultAspectRatio = mLayer->defaultAspectRatio();
3823  double fixedAspectRatio = 0.0;
3824  mHeightSpinBox->blockSignals( true );
3825  if ( defaultAspectRatio <= 0.0 )
3826  {
3827  mHeightSpinBox->setValue( mWidthSpinBox->value() );
3828  }
3829  else if ( mLockAspectRatio->locked() )
3830  {
3831  mHeightSpinBox->setValue( mWidthSpinBox->value() * defaultAspectRatio );
3832  }
3833  else
3834  {
3835  fixedAspectRatio = mHeightSpinBox->value() / mWidthSpinBox->value();
3836  }
3837  mHeightSpinBox->blockSignals( false );
3838  mLayer->setSize( mWidthSpinBox->value() );
3839  mLayer->setFixedAspectRatio( fixedAspectRatio );
3840  emit changed();
3841 }
3842 
3843 void QgsRasterMarkerSymbolLayerWidget::setHeight()
3844 {
3845  double defaultAspectRatio = mLayer->defaultAspectRatio();
3846  double fixedAspectRatio = 0.0;
3847  mWidthSpinBox->blockSignals( true );
3848  if ( defaultAspectRatio <= 0.0 )
3849  {
3850  mWidthSpinBox->setValue( mHeightSpinBox->value() );
3851  }
3852  else if ( mLockAspectRatio->locked() )
3853  {
3854  mWidthSpinBox->setValue( mHeightSpinBox->value() / defaultAspectRatio );
3855  }
3856  else
3857  {
3858  fixedAspectRatio = mHeightSpinBox->value() / mWidthSpinBox->value();
3859  }
3860  mWidthSpinBox->blockSignals( false );
3861  mLayer->setSize( mWidthSpinBox->value() );
3862  mLayer->setFixedAspectRatio( fixedAspectRatio );
3863  emit changed();
3864 }
3865 
3866 void QgsRasterMarkerSymbolLayerWidget::setLockAspectRatio( const bool locked )
3867 {
3868  double defaultAspectRatio = mLayer->defaultAspectRatio();
3869  if ( defaultAspectRatio <= 0.0 )
3870  {
3871  whileBlocking( mLockAspectRatio )->setLocked( true );
3872  }
3873  else if ( locked )
3874  {
3875  mLayer->setFixedAspectRatio( 0.0 );
3876  setWidth();
3877  }
3878  else
3879  {
3880  mLayer->setFixedAspectRatio( mHeightSpinBox->value() / mWidthSpinBox->value() );
3881  }
3882 }
3883 
3884 void QgsRasterMarkerSymbolLayerWidget::setAngle()
3885 {
3886  mLayer->setAngle( mRotationSpinBox->value() );
3887  emit changed();
3888 }
3889 
3890 void QgsRasterMarkerSymbolLayerWidget::setOpacity( double value )
3891 {
3892  mLayer->setOpacity( value );
3893  emit changed();
3894  updatePreviewImage();
3895 }
3896 
3897 void QgsRasterMarkerSymbolLayerWidget::setOffset()
3898 {
3899  mLayer->setOffset( QPointF( mSpinOffsetX->value(), mSpinOffsetY->value() ) );
3900  emit changed();
3901 }
3902 
3903 void QgsRasterMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
3904 {
3905  if ( mLayer )
3906  {
3907  mLayer->setSizeUnit( mSizeUnitWidget->unit() );
3908  mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
3909  emit changed();
3910  }
3911 }
3912 
3913 void QgsRasterMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
3914 {
3915  if ( mLayer )
3916  {
3917  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
3918  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
3919  emit changed();
3920  }
3921 }
3922 
3923 void QgsRasterMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
3924 {
3925  if ( mLayer )
3926  {
3928  emit changed();
3929  }
3930 }
3931 
3932 void QgsRasterMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
3933 {
3934  if ( mLayer )
3935  {
3937  emit changed();
3938  }
3939 }
3940 
3942 
3944  : QgsSymbolLayerWidget( parent, vl )
3945 {
3946  mLayer = nullptr;
3947  setupUi( this );
3948 
3949  mImageSourceLineEdit->setLastPathSettingsKey( QStringLiteral( "/UI/lastRasterMarkerImageDir" ) );
3950  connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsRasterFillSymbolLayerWidget::imageSourceChanged );
3951 
3952  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterFillSymbolLayerWidget::mOffsetUnitWidget_changed );
3953  connect( mRotationSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::mRotationSpinBox_valueChanged );
3954  connect( mWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterFillSymbolLayerWidget::mWidthUnitWidget_changed );
3955  connect( mWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::mWidthSpinBox_valueChanged );
3956 
3961 
3962  mSpinOffsetX->setClearValue( 0.0 );
3963  mSpinOffsetY->setClearValue( 0.0 );
3964  mRotationSpinBox->setClearValue( 0.0 );
3965 
3966  connect( cboCoordinateMode, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterFillSymbolLayerWidget::setCoordinateMode );
3967  connect( mSpinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::offsetChanged );
3968  connect( mSpinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::offsetChanged );
3969  connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsRasterFillSymbolLayerWidget::opacityChanged );
3970 }
3971 
3972 
3974 {
3975  if ( !layer )
3976  {
3977  return;
3978  }
3979 
3980  if ( layer->layerType() != QLatin1String( "RasterFill" ) )
3981  {
3982  return;
3983  }
3984 
3985  mLayer = dynamic_cast<QgsRasterFillSymbolLayer *>( layer );
3986  if ( !mLayer )
3987  {
3988  return;
3989  }
3990 
3991  whileBlocking( mImageSourceLineEdit )->setSource( mLayer->imageFilePath() );
3992 
3993  cboCoordinateMode->blockSignals( true );
3994  switch ( mLayer->coordinateMode() )
3995  {
3997  cboCoordinateMode->setCurrentIndex( 1 );
3998  break;
4000  default:
4001  cboCoordinateMode->setCurrentIndex( 0 );
4002  break;
4003  }
4004  cboCoordinateMode->blockSignals( false );
4005  whileBlocking( mOpacityWidget )->setOpacity( mLayer->opacity() );
4006  whileBlocking( mRotationSpinBox )->setValue( mLayer->angle() );
4007 
4008  whileBlocking( mSpinOffsetX )->setValue( mLayer->offset().x() );
4009  whileBlocking( mSpinOffsetY )->setValue( mLayer->offset().y() );
4010  mOffsetUnitWidget->blockSignals( true );
4011  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
4012  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
4013  mOffsetUnitWidget->blockSignals( false );
4014 
4015  whileBlocking( mWidthSpinBox )->setValue( mLayer->width() );
4016  mWidthUnitWidget->blockSignals( true );
4017  mWidthUnitWidget->setUnit( mLayer->widthUnit() );
4018  mWidthUnitWidget->setMapUnitScale( mLayer->widthMapUnitScale() );
4019  mWidthUnitWidget->blockSignals( false );
4020 
4021  updatePreviewImage();
4022 
4028 }
4029 
4031 {
4032  return mLayer;
4033 }
4034 
4035 void QgsRasterFillSymbolLayerWidget::imageSourceChanged( const QString &text )
4036 {
4037  mLayer->setImageFilePath( text );
4038  updatePreviewImage();
4039  emit changed();
4040 }
4041 
4042 void QgsRasterFillSymbolLayerWidget::setCoordinateMode( int index )
4043 {
4044  switch ( index )
4045  {
4046  case 0:
4047  //feature coordinate mode
4049  break;
4050  case 1:
4051  //viewport coordinate mode
4053  break;
4054  }
4055 
4056  emit changed();
4057 }
4058 
4059 void QgsRasterFillSymbolLayerWidget::opacityChanged( double value )
4060 {
4061  if ( !mLayer )
4062  {
4063  return;
4064  }
4065 
4066  mLayer->setOpacity( value );
4067  emit changed();
4068  updatePreviewImage();
4069 }
4070 
4071 void QgsRasterFillSymbolLayerWidget::offsetChanged()
4072 {
4073  mLayer->setOffset( QPointF( mSpinOffsetX->value(), mSpinOffsetY->value() ) );
4074  emit changed();
4075 }
4076 
4077 void QgsRasterFillSymbolLayerWidget::mOffsetUnitWidget_changed()
4078 {
4079  if ( !mLayer )
4080  {
4081  return;
4082  }
4083  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
4084  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
4085  emit changed();
4086 }
4087 
4088 void QgsRasterFillSymbolLayerWidget::mRotationSpinBox_valueChanged( double d )
4089 {
4090  if ( mLayer )
4091  {
4092  mLayer->setAngle( d );
4093  emit changed();
4094  }
4095 }
4096 
4097 void QgsRasterFillSymbolLayerWidget::mWidthUnitWidget_changed()
4098 {
4099  if ( !mLayer )
4100  {
4101  return;
4102  }
4103  mLayer->setWidthUnit( mWidthUnitWidget->unit() );
4104  mLayer->setWidthMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
4105  emit changed();
4106 }
4107 
4108 void QgsRasterFillSymbolLayerWidget::mWidthSpinBox_valueChanged( double d )
4109 {
4110  if ( !mLayer )
4111  {
4112  return;
4113  }
4114  mLayer->setWidth( d );
4115  emit changed();
4116 }
4117 
4118 void QgsRasterFillSymbolLayerWidget::updatePreviewImage()
4119 {
4120  bool fitsInCache = false;
4121  QImage image = QgsApplication::imageCache()->pathAsImage( mLayer->imageFilePath(), QSize( 150, 150 ), true, 1.0, fitsInCache );
4122  if ( image.isNull() )
4123  {
4124  mLabelImagePreview->setPixmap( QPixmap() );
4125  return;
4126  }
4127 
4128  QImage previewImage( 150, 150, QImage::Format_ARGB32 );
4129  previewImage.fill( Qt::transparent );
4130  QRect imageRect( ( 150 - image.width() ) / 2.0, ( 150 - image.height() ) / 2.0, image.width(), image.height() );
4131  QPainter p;
4132  p.begin( &previewImage );
4133  //draw a checkerboard background
4134  uchar pixDataRGB[] = { 150, 150, 150, 150,
4135  100, 100, 100, 150,
4136  100, 100, 100, 150,
4137  150, 150, 150, 150
4138  };
4139  QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
4140  QPixmap pix = QPixmap::fromImage( img.scaled( 8, 8 ) );
4141  QBrush checkerBrush;
4142  checkerBrush.setTexture( pix );
4143  p.fillRect( imageRect, checkerBrush );
4144 
4145  if ( mLayer->opacity() < 1.0 )
4146  {
4147  p.setOpacity( mLayer->opacity() );
4148  }
4149 
4150  p.drawImage( imageRect.left(), imageRect.top(), image );
4151  p.end();
4152  mLabelImagePreview->setPixmap( QPixmap::fromImage( previewImage ) );
4153 }
4154 
4155 
4157  : QgsSymbolLayerWidget( parent, vl )
4158 
4159 {
4160  setupUi( this );
4161  modificationExpressionSelector->setMultiLine( true );
4162  modificationExpressionSelector->setLayer( const_cast<QgsVectorLayer *>( vl ) );
4163  modificationExpressionSelector->registerExpressionContextGenerator( this );
4164  cbxGeometryType->addItem( QgsLayerItem::iconPolygon(), tr( "Polygon / MultiPolygon" ), QgsSymbol::Fill );
4165  cbxGeometryType->addItem( QgsLayerItem::iconLine(), tr( "LineString / MultiLineString" ), QgsSymbol::Line );
4166  cbxGeometryType->addItem( QgsLayerItem::iconPoint(), tr( "Point / MultiPoint" ), QgsSymbol::Marker );
4167  connect( modificationExpressionSelector, &QgsExpressionLineEdit::expressionChanged, this, &QgsGeometryGeneratorSymbolLayerWidget::updateExpression );
4168  connect( cbxGeometryType, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGeometryGeneratorSymbolLayerWidget::updateSymbolType );
4169 }
4170 
4172 {
4173  mLayer = static_cast<QgsGeometryGeneratorSymbolLayer *>( l );
4174  modificationExpressionSelector->setExpression( mLayer->geometryExpression() );
4175  cbxGeometryType->setCurrentIndex( cbxGeometryType->findData( mLayer->symbolType() ) );
4176 }
4177 
4179 {
4180  return mLayer;
4181 }
4182 
4183 void QgsGeometryGeneratorSymbolLayerWidget::updateExpression( const QString &string )
4184 {
4185  mLayer->setGeometryExpression( string );
4186 
4187  emit changed();
4188 }
4189 
4190 void QgsGeometryGeneratorSymbolLayerWidget::updateSymbolType()
4191 {
4192  mLayer->setSymbolType( static_cast<QgsSymbol::SymbolType>( cbxGeometryType->currentData().toInt() ) );
4193 
4194  emit symbolChanged();
4195 }
4196 
4197 //
4198 // QgsRandomMarkerFillSymbolLayerWidget
4199 //
4200 
4201 
4203  QgsSymbolLayerWidget( parent, vl )
4204 {
4205  setupUi( this );
4206 
4207  mCountMethodComboBox->addItem( tr( "Absolute Count" ), QgsRandomMarkerFillSymbolLayer::AbsoluteCount );
4208  mCountMethodComboBox->addItem( tr( "Density-based Count" ), QgsRandomMarkerFillSymbolLayer::DensityBasedCount );
4209 
4210  mPointCountSpinBox->setShowClearButton( true );
4211  mPointCountSpinBox->setClearValue( 100 );
4212  mSeedSpinBox->setShowClearButton( true );
4213  mSeedSpinBox->setClearValue( 0 );
4214 
4215  connect( mCountMethodComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRandomMarkerFillSymbolLayerWidget::countMethodChanged );
4216  connect( mPointCountSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsRandomMarkerFillSymbolLayerWidget::countChanged );
4217  connect( mDensityAreaSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRandomMarkerFillSymbolLayerWidget::densityAreaChanged );
4218  connect( mSeedSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsRandomMarkerFillSymbolLayerWidget::seedChanged );
4219  connect( mClipPointsCheckBox, &QCheckBox::toggled, this, [ = ]( bool checked )
4220  {
4221  if ( mLayer )
4222  {
4223  mLayer->setClipPoints( checked );
4224  emit changed();
4225  }
4226  } );
4227 
4230 
4231  connect( mDensityAreaUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRandomMarkerFillSymbolLayerWidget::densityAreaUnitChanged );
4232 }
4233 
4235 {
4236  if ( !layer || layer->layerType() != QLatin1String( "RandomMarkerFill" ) )
4237  {
4238  return;
4239  }
4240 
4241  mLayer = static_cast<QgsRandomMarkerFillSymbolLayer *>( layer );
4242  whileBlocking( mPointCountSpinBox )->setValue( mLayer->pointCount() );
4243  whileBlocking( mSeedSpinBox )->setValue( mLayer->seed() );
4244  whileBlocking( mClipPointsCheckBox )->setChecked( mLayer->clipPoints() );
4245 
4246  bool showDensityBasedCountWidgets = false;
4247  switch ( mLayer->countMethod() )
4248  {
4250  showDensityBasedCountWidgets = true;
4251  break;
4253  break;
4254  }
4255  mDensityAreaLabel->setVisible( showDensityBasedCountWidgets );
4256  mDensityAreaSpinBox->setVisible( showDensityBasedCountWidgets );
4257  mDensityAreaUnitWidget->setVisible( showDensityBasedCountWidgets );
4258  mDensityAreaDdbtn->setVisible( showDensityBasedCountWidgets );
4259 
4260  whileBlocking( mCountMethodComboBox )->setCurrentIndex( mCountMethodComboBox->findData( mLayer->countMethod() ) );
4261  whileBlocking( mDensityAreaSpinBox )->setValue( mLayer->densityArea() );
4262  mDensityAreaUnitWidget->blockSignals( true );
4263  mDensityAreaUnitWidget->setUnit( mLayer->densityAreaUnit() );
4264  mDensityAreaUnitWidget->setMapUnitScale( mLayer->densityAreaUnitScale() );
4265  mDensityAreaUnitWidget->blockSignals( false );
4266 
4271 }
4272 
4274 {
4275  return mLayer;
4276 }
4277 
4278 void QgsRandomMarkerFillSymbolLayerWidget::countMethodChanged( int )
4279 {
4280 
4281  bool showDensityBasedCountWidgets = false;
4282  switch ( static_cast< QgsRandomMarkerFillSymbolLayer::CountMethod >( mCountMethodComboBox->currentData().toInt() ) )
4283  {
4285  showDensityBasedCountWidgets = true;
4286  break;
4288  break;
4289  }
4290  mDensityAreaLabel->setVisible( showDensityBasedCountWidgets );
4291  mDensityAreaSpinBox->setVisible( showDensityBasedCountWidgets );
4292  mDensityAreaUnitWidget->setVisible( showDensityBasedCountWidgets );
4293  mDensityAreaDdbtn->setVisible( showDensityBasedCountWidgets );
4294 
4295  if ( mLayer )
4296  {
4297  mLayer->setCountMethod( static_cast< QgsRandomMarkerFillSymbolLayer::CountMethod >( mCountMethodComboBox->currentData().toInt() ) );
4298  emit changed();
4299  }
4300 }
4301 
4302 void QgsRandomMarkerFillSymbolLayerWidget::countChanged( int d )
4303 {
4304  if ( mLayer )
4305  {
4306  mLayer->setPointCount( d );
4307  emit changed();
4308  }
4309 }
4310 
4311 void QgsRandomMarkerFillSymbolLayerWidget::densityAreaChanged( double d )
4312 {
4313  if ( mLayer )
4314  {
4315  mLayer->setDensityArea( d );
4316  emit changed();
4317  }
4318 }
4319 
4320 void QgsRandomMarkerFillSymbolLayerWidget::densityAreaUnitChanged()
4321 {
4322  if ( mLayer )
4323  {
4324  mLayer->setDensityAreaUnit( mDensityAreaUnitWidget->unit() );
4325  mLayer->setDensityAreaUnitScale( mDensityAreaUnitWidget->getMapUnitScale() );
4326  emit changed();
4327  }
4328 }
4329 
4330 void QgsRandomMarkerFillSymbolLayerWidget::seedChanged( int d )
4331 {
4332  if ( mLayer )
4333  {
4334  mLayer->setSeed( d );
4335  emit changed();
4336  }
4337 }
void setOffset(QPointF offset)
Sets the marker&#39;s offset, which is the horizontal and vertical displacement which the rendered marker...
QColor color2() const
Returns the color used for the endpoint of the shapeburst fill.
const QgsVectorLayer * vectorLayer() const
Returns the vector layer associated with the widget.
void setSvgStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the pattern&#39;s stroke.
static const QString EXPR_ORIGINAL_VALUE
Inbuilt variable name for value original value variable.
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
void setOffsetAlongLine(double offsetAlongLine)
Sets the the offset along the line for the symbol placement.
double hashLength() const
Returns the length of hash symbols.
static QgsExpressionContextScope * updateSymbolScope(const QgsSymbol *symbol, QgsExpressionContextScope *symbolScope=nullptr)
Updates a symbol scope related to a QgsSymbol to an expression context.
static QgsSvgCache * svgCache()
Returns the application&#39;s SVG cache, used for caching SVG images and handling parameter replacement w...
QgsUnitTypes::RenderUnit customDashPatternUnit() const
Returns the units for lengths used in the custom dash pattern.
static const QString EXPR_CLUSTER_COLOR
Inbuilt variable name for cluster color variable.
Place symbols on the first vertex in the line.
Meters value as Map units.
Definition: qgsunittypes.h:175
void setDistance(double d)
Sets the distance between lines in the fill pattern.
Single variable definition for use within a QgsExpressionContextScope.
RenderRingFilter ringFilter() const
Returns the line symbol layer&#39;s ring filter, which controls which rings are rendered when the line sy...
QList< QgsExpressionContextScope * > globalProjectAtlasMapLayerScopes(const QgsMapLayer *layer) const
Returns list of scopes: global, project, atlas, map, layer.
void symbolChanged()
Should be emitted whenever the sub symbol changed on this symbol layer configuration.
Gradient reference point 1 is centroid.
const QgsMapUnitScale & displacementYMapUnitScale() const
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the fill&#39;s offset.
const QgsMapUnitScale & offsetXMapUnitScale() const
Returns the unit scale for the horizontal offset for rows in the pattern.
QgsMarkerLineSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsMarkerLineSymbolLayerWidget.
void setColorStroke(const QColor &color)
static QIcon symbolLayerPreviewIcon(const QgsSymbolLayer *layer, QgsUnitTypes::RenderUnit u, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale())
Draws a symbol layer preview to an icon.
void setOffsetUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the symbol&#39;s offset.
void setMapUnitScale(const QgsMapUnitScale &scale) override
void setSymbolLayer(QgsSymbolLayer *layer) override
double fixedAspectRatio() const
Returns the marker aspect ratio between width and height to be used in rendering, if the value set is...
void setColorFill(const QColor &color)
void setPointCount(int count)
Sets the count of random points to render in the fill.
void setPenJoinStyle(Qt::PenJoinStyle style)
Sets the marker&#39;s stroke join style (e.g., miter, bevel, etc).
QgsSymbolLayer * symbolLayer() override
QgsGradientFillSymbolLayer * mLayer
bool clipPoints() const
Returns true if point markers should be clipped to the polygon boundary.
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the stroke width map unit scale.
void setColorRamp(QgsColorRamp *ramp)
Sets the color ramp used for the gradient fill.
QgsRasterMarkerSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsRasterMarkerSymbolLayerWidget.
QString svgFilePath() const
Returns the path to the SVG file used to render the fill.
void setPatternWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the width of the SVG images in the pattern.
QColor strokeColor() const override
Gets stroke color.
double defaultAspectRatio() const
Returns the default marker aspect ratio between width and height, 0 if not yet calculated.
QVector< qreal > dashDotVector() const
Returns the dash pattern as a list of numbers.
void setSymbolLayer(QgsSymbolLayer *layer) override
bool dockMode()
Returns the dock mode state.
void setPlacement(Placement placement)
Sets the placement of the symbols.
void setSymbolLayer(QgsSymbolLayer *layer) override
Gradient reference point 1 x.
void setOffsetUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the fill&#39;s offset.
static const QString EXPR_GEOMETRY_POINT_COUNT
Inbuilt variable name for point count variable.
QgsUnitTypes::RenderUnit distanceUnit() const
Returns the units for the distance between lines in the fill pattern.
QgsSymbolLayer * symbolLayer() override
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
void setSvgFillColor(const QColor &c)
Sets the fill color used for rendering the SVG content.
void setPatternWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the pattern&#39;s width.
QString fontFamily() const
Returns the font family name for the associated font which will be used to render the point...
static QPixmap symbolPreviewPixmap(const QgsSymbol *symbol, QSize size, int padding=0, QgsRenderContext *customContext=nullptr, bool selected=false, const QgsExpressionContext *expressionContext=nullptr, const QgsLegendPatchShape *shape=nullptr)
Returns a pixmap preview for a color ramp.
void setUseCustomDashPattern(bool b)
Sets whether the line uses a custom dash pattern.
void setSymbolLayer(QgsSymbolLayer *layer) override
const QgsMapUnitScale & displacementXMapUnitScale() const
static const double UI_SCALE_FACTOR
UI scaling factor.
Definition: qgis.h:183
bool exists(const QgsPropertyDefinition &definition) const
Returns true if the property is stored in the layer already, false otherwise.
QString imageFilePath() const
The path to the raster image used for the fill.
QPointF offset() const
Returns the offset for the shapeburst fill.
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit u)
Sets the unit for the width of the marker&#39;s stroke.
void setMapUnitScale(const QgsMapUnitScale &scale) override
void setSymbolLayer(QgsSymbolLayer *layer) override
void setStrokeStyle(Qt::PenStyle strokeStyle)
Sets the marker&#39;s stroke style (e.g., solid, dashed, etc)
Simple marker symbol layer, consisting of a rendered shape with solid fill color and an stroke...
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units used for the offset of the shapeburst fill.
virtual void setWidth(double width)
Sets the width of the line symbol layer.
GradientCoordinateMode coordinateMode() const
Coordinate mode for gradient. Controls how the gradient stops are positioned.
void colorRampChanged()
Emitted whenever a new color ramp is set for the button.
const QgsMapUnitScale & offsetMapUnitScale() const
Returns the map unit scale for the line&#39;s offset.
QgsFontMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
void setReferencePoint1IsCentroid(bool isCentroid)
Sets the starting point of the gradient to be the feature centroid.
Qt::PenJoinStyle penJoinStyle() const
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units for the line pattern&#39;s offset.
GradientSpread gradientSpread() const
Gradient spread mode. Controls how the gradient behaves outside of the predefined stops...
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units for the fill&#39;s offset.
A symbol fill consisting of repeated parallel lines.
QgsSimpleFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsSimpleFillSymbolLayerWidget.
const QgsMapUnitScale & sizeMapUnitScale() const
Returns the map unit scale for the symbol&#39;s size.
QString geometryExpression() const
Gets the expression to generate this geometry.
void lockChanged(bool locked)
Emitted whenever the lock state changes.
void containsParams(const QString &path, bool &hasFillParam, QColor &defaultFillColor, bool &hasStrokeParam, QColor &defaultStrokeColor, bool &hasStrokeWidthParam, double &defaultStrokeWidth, bool blocking=false) const
Tests if an svg file contains parameters for fill, stroke color, stroke width.
double angle() const
void setOffsetYMapUnitScale(const QgsMapUnitScale &scale)
Sets the unit scale for the vertical offset for rows in the pattern.
QgsLinePatternFillSymbolLayer * mLayer
void setColorRamp(QgsColorRamp *ramp)
Sets the color ramp used to draw the shapeburst fill.
QgsUnitTypes::RenderUnit widthUnit() const
Returns the units for the image&#39;s width.
void setDisplacementYUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the vertical displacement between rows in the pattern.
static QgsImageCache * imageCache()
Returns the application&#39;s image cache, used for caching resampled versions of raster images...
QgsGradientFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsGradientFillSymbolLayerWidget.
A simple line symbol layer, which renders lines using a line in a variety of styles (e...
double averageAngleLength() const
Returns the length of line over which the line&#39;s direction is averaged when calculating individual sy...
void setOffset(QPointF offset)
Sets the offset for the shapeburst fill.
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
QgsUnitTypes::RenderUnit patternWidthUnit() const
Returns the units for the width of the SVG images in the pattern.
Render both exterior and interior rings.
QgsSymbolLayer * symbolLayer() override
void setAngle(double angle)
Abstract base class for color ramps.
Definition: qgscolorramp.h:31
void sourceChanged(const QString &source)
Emitted whenever the file source is changed in the widget.
QString fontStyle() const
Returns the font style for the associated font which will be used to render the point.
void setOffsetY(double offset)
Sets the vertical offset values for points in the pattern.
void setSymbolLayer(QgsSymbolLayer *layer) override
void setUseWholeShape(bool useWholeShape)
Sets whether the shapeburst fill should be drawn using the entire shape.
A widget for displaying characters available in a preset font, and allowing users to select an indivi...
void setStrokeColor(const QColor &color) override
Sets the marker&#39;s stroke color.
Whether markers should be clipped to polygon boundaries.
void setCharacter(QChar character)
Sets the currently selected character in the widget.
void setSymbolLayer(QgsSymbolLayer *layer) override
const QgsMapUnitScale & hashLengthMapUnitScale() const
Returns the map unit scale for the hash length.
void setDistanceUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the maximum distance to shade inside of the shape from the polygon&#39;s boundary...
void setColor(const QColor &color)
const QgsMapUnitScale & strokeWidthMapUnitScale() const
ShapeburstColorType colorType() const
Returns the color mode used for the shapeburst fill.
QgsUnitTypes::RenderUnit averageAngleUnit() const
Returns the unit for the length over which the line&#39;s direction is averaged when calculating individu...
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsUnitTypes::RenderUnit offsetYUnit() const
Returns the units for the vertical offset for rows in the pattern.
Q_INVOKABLE QgsWkbTypes::GeometryType geometryType() const
Returns point, line or polygon.
void setStrokeColor(const QColor &c) override
Set stroke color.
void setStrokeWidth(double w)
Sets the width of the marker&#39;s stroke.
void setContext(const QgsSymbolWidgetContext &context) override
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
QgsSymbolLayer * symbolLayer() override
void setDistanceUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the distance between lines in the fill pattern.
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
static QIcon iconLine()
Definition: qgsdataitem.cpp:79
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the symbol&#39;s offset.
void setStrokeWidth(double width)
Set&#39;s the marker&#39;s stroke width.
VerticalAnchorPoint verticalAnchorPoint() const
Returns the vertical anchor point for positioning the symbol.
A widget to enter a custom dash space pattern for lines.
void setDashPatternOffset(double offset)
Sets the dash pattern offset, which dictates how far along the dash pattern the pattern should start ...
static QIcon iconPoint()
Definition: qgsdataitem.cpp:74
void setUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit type used for the dash space pattern (used to update interface labels) ...
bool useWholeShape() const
Returns whether the shapeburst fill is set to cover the entire shape.
void setOffsetUnit(const QgsUnitTypes::RenderUnit unit)
Sets the units for the fill&#39;s offset.
void setDistanceXMapUnitScale(const QgsMapUnitScale &scale)
Base class for any widget that can be shown as a inline panel.
void setDistanceMapUnitScale(const QgsMapUnitScale &scale)
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units for the symbol&#39;s offset.
void setDensityAreaUnitScale(const QgsMapUnitScale &scale)
Sets the map scale for the density area.
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units for the line&#39;s offset.
Line symbol.
Definition: qgssymbol.h:89
QColor strokeColor() const override
Returns the marker&#39;s stroke color.
A fill symbol layer which places markers at random locations within polygons.
QgsCentroidFillSymbolLayer * mLayer
QColor color2() const
Color for endpoint of gradient, only used if the gradient color type is set to SimpleTwoColor.
Percentage of another measurement (e.g., canvas size, feature size)
Definition: qgsunittypes.h:171
Place symbols on every vertex in the line.
void setReferencePoint2IsCentroid(bool isCentroid)
Sets the end point of the gradient to be the feature centroid.
const QgsMapUnitScale & averageAngleMapUnitScale() const
Returns the map unit scale for the length over which the line&#39;s direction is averaged when calculatin...
QgsUnitTypes::RenderUnit intervalUnit() const
Returns the units for the interval between symbols.
QgsSVGFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsSVGFillSymbolLayerWidget.
static QString translateNamedStyle(const QString &namedStyle)
Returns the localized named style of a font, if such a translation is available.
double interval() const
Returns the interval between individual symbols.
const QgsMapUnitScale & svgStrokeWidthMapUnitScale() const
Returns the map unit scale for the pattern&#39;s stroke.
static QString encodeShape(QgsSimpleMarkerSymbolLayerBase::Shape shape)
Encodes a shape to its string representation.
void setPointOnAllParts(bool pointOnAllParts)
Sets whether a point is drawn for all parts or only on the biggest part of multi-part features...
Qt::PenJoinStyle penJoinStyle() const
Returns the stroke join style.
void setCharacterFromText(const QString &text)
Set the font marker character from a text string.
void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
Tiling is based on complete map viewport.
QList< QgsUnitTypes::RenderUnit > RenderUnitList
List of render units.
Definition: qgsunittypes.h:239
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
Definition: MathUtils.cpp:786
void setInterval(double interval)
Sets the interval between individual symbols.
virtual double width() const
Returns the estimated width for the line symbol layer.
A marker symbol type, for rendering Point and MultiPoint geometries.
Definition: qgssymbol.h:985
Name, eg shape name for simple markers.
bool clipOnCurrentPartOnly() const
Returns true if point markers should be clipped to the current part boundary only.
void setStrokeWidth(double strokeWidth)
void setPatternWidth(double width)
Sets the width to render the SVG content as within the fill (i.e.
void setWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the line&#39;s width.
A line symbol type, for rendering LineString and MultiLineString geometries.
Definition: qgssymbol.h:1185
Gradient reference point 2 y.
static QList< QgsSimpleMarkerSymbolLayerBase::Shape > availableShapes()
Returns a list of all available shape types.
double lineAngle() const
Returns the angle for the parallel lines used to fill the symbol.
QgsShapeburstFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsShapeburstFillSymbolLayerWidget.
QgsUnitTypes::RenderUnit densityAreaUnit() const
Returns the units for the density area.
QString path() const
Returns the marker SVG path.
void setSymbolLayer(QgsSymbolLayer *layer) override
QColor strokeColor() const override
Gets stroke color.
void setGradientType(GradientType gradientType)
Place symbols at every virtual curve point in the line (used when rendering curved geometry types onl...
void clearCharacter()
Clears the currently selected character in the widget.
void setPenJoinStyle(Qt::PenJoinStyle style)
Sets the stroke join style.
double strokeWidth() const
Returns the width of the marker&#39;s stroke.
const QgsMapUnitScale & offsetMapUnitScale() const
Returns the map unit scale for the pattern&#39;s line offset.
void setPath(const QString &path)
Set the marker SVG path.
void setCustomDashPatternUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for lengths used in the custom dash pattern.
void setOffsetUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the line pattern&#39;s offset.
void setCoordinateMode(FillCoordinateMode mode)
Set the coordinate mode for fill.
virtual void setColor(const QColor &color)
The fill color.
double offsetY() const
Returns the vertical offset values for points in the pattern.
const QgsMapUnitScale & offsetYMapUnitScale() const
Returns the unit scale for the vertical offset between rows in the pattern.
Place symbols at the center of every line segment.
void setOffset(QPointF offset)
Sets an offset by which polygons will be translated during rendering.
void setBlurRadius(int blurRadius)
Sets the blur radius, which controls the amount of blurring applied to the fill.
void setSymbolLayer(QgsSymbolLayer *layer) override
void setAverageAngleUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the length over which the line&#39;s direction is averaged when calculating individual ...
void setSymbolLayer(QgsSymbolLayer *layer) override
void createAuxiliaryField()
Emitted when creating a new auxiliary field.
QgsSymbolLayer * symbolLayer() override
QgsUnitTypes::RenderUnit strokeWidthUnit() const
Returns the stroke width unit.
HorizontalAnchorPoint horizontalAnchorPoint() const
Returns the horizontal anchor point for positioning the symbol.
void setIgnoreRings(bool ignoreRings)
Sets whether the shapeburst fill should ignore polygon rings when calculating the buffered shading...
double offset() const
Returns the offset distance for lines within the fill, which is the distance to offset the parallel l...
void setClipPoints(bool clipPoints)
Sets whether point markers should be clipped to the polygon boundary.
A dialog to create a new auxiliary layer.
void setField(const QString &field)
Sets the field name the property references.
void setLineAngle(double a)
Sets the angle for the parallel lines used to fill the symbol.
const QgsMapUnitScale & distanceMapUnitScale() const
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the stroke width.
void setImageFilePath(const QString &imagePath)
Sets the path to the raster image used for the fill.
CountMethod countMethod() const
Returns the count method used to randomly fill the polygon.
Raster marker symbol layer class.
void setGuiForSvg(const QgsSvgMarkerSymbolLayer *layer, bool skipDefaultColors=false)
Updates the GUI to reflect the SVG marker symbol layer.
A class for filling symbols with a repeated raster image.
bool tweakDashPatternOnCorners() const
Returns true if dash patterns tweaks should be applied on sharp corners, to ensure that a double-leng...
void setOffsetAlongLineMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale used for calculating the offset in map units along line for symbols...
void changed()
Should be emitted whenever configuration changes happened on this symbol layer configuration.
A cross platform button subclass used to represent a locked / unlocked ratio state.
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
A dialog to enter a custom dash space pattern for lines.
A button for controlling property overrides which may apply to a widget.
void setIntervalUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the interval between symbols.
void setStrokeColor(const QColor &color) override
Set stroke color.
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the fill&#39;s offset.
QgsSymbolLayer * symbolLayer() override
QgsMarkerLineSymbolLayer * mLayer
void setColor2(const QColor &color2)
Sets the color for the endpoint of the shapeburst fill.
QgsRasterMarkerSymbolLayer * mLayer
double angle() const
Returns the rotation angle for the marker, in degrees clockwise from north.
QgsSimpleLineSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsSimpleLineSymbolLayerWidget.
void setColor(const QColor &color) override
The fill color.
QgsSimpleFillSymbolLayer * mLayer
QPointF offset()
Returns the offset by which polygons will be translated during rendering.
void setWidth(const double width)
Sets the width for scaling the image used in the fill.
void setCountMethod(CountMethod method)
Sets the count method used to randomly fill the polygon.
QImage pathAsImage(const QString &path, const QSize size, const bool keepAspectRatio, const double opacity, bool &fitsInCache, bool blocking=false, bool *isMissing=nullptr)
Returns the specified path rendered as an image.
double offsetX() const
Returns the horizontal offset values for points in the pattern.
static QIcon iconPolygon()
Definition: qgsdataitem.cpp:84
QgsUnitTypes::RenderUnit displacementYUnit() const
Returns the units for the vertical displacement between rows in the pattern.
double opacity() const
Returns the marker opacity.
QgsUnitTypes::RenderUnit widthUnit() const
Returns the units for the line&#39;s width.
void setFixedAspectRatio(double ratio)
Set the marker aspect ratio between width and height to be used in rendering, if the value set is low...
void setReferencePoint1(QPointF referencePoint)
Starting point of gradient fill, in the range [0,0] - [1,1].
bool clipPoints() const
Returns true if point markers should be clipped to the polygon boundary.
static QgsPanelWidget * findParentPanel(QWidget *widget)
Traces through the parents of a widget to find if it is contained within a QgsPanelWidget widget...
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map scale for the width of the marker&#39;s stroke.
void setDashPatternOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the dash pattern offset.
QVector< qreal > customDashVector() const
Returns the custom dash vector, which is the pattern of alternating drawn/skipped lengths used while ...
Contains settings which reflect the context in which a symbol (or renderer) widget is shown...
void setToProperty(const QgsProperty &property)
Sets the widget to reflect the current state of a QgsProperty.
QgsProperty toProperty() const
Returns a QgsProperty object encapsulating the current state of the widget.
void svgSelected(const QString &path)
QgsCentroidFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsCentroidFillSymbolLayerWidget.
void setSvgStrokeWidth(double w)
Sets the stroke width used for rendering the SVG content.
void setTweakDashPatternOnCorners(bool enabled)
Sets whether dash patterns tweaks should be applied on sharp corners, to ensure that a double-length ...
QgsRandomMarkerFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsRandomMarkerFillSymbolLayerWidget.
const QgsMapUnitScale & strokeWidthMapUnitScale() const
Returns the stroke width map unit scale.
void setDensityArea(double area)
Sets the density area used to count the number of points to randomly fill the polygon.
void resizeEvent(QResizeEvent *event) override
void setHashLengthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the hash length.
void registerExpressionContextGenerator(QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
double size() const
Returns the symbol size.
void opacityChanged(double opacity)
Emitted when the opacity is changed in the widget, where opacity ranges from 0.0 (transparent) to 1...
void setOffsetXUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the horizontal offset between rows in the pattern.
bool preservedAspectRatio() const
Returns the preserved aspect ratio value, true if fixed aspect ratio has been lower or equal to 0...
void setDashPatternOffsetUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the dash pattern offset.
Render the interior rings only.
virtual QgsSymbolLayer * symbolLayer()=0
void setSymbolLayer(QgsSymbolLayer *layer) override
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
double densityArea() const
Returns the density area used to count the number of points to randomly fill the polygon.
const QgsMapUnitScale & strokeWidthMapUnitScale() const
Returns the map scale for the width of the marker&#39;s stroke.
void setWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the image&#39;s width.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer&#39;s property collection, used for data defined overrides...
void setHorizontalAnchorPoint(HorizontalAnchorPoint h)
Sets the horizontal anchor point for positioning the symbol.
Line symbol layer type which draws repeating line sections along a line feature.
const QgsMapUnitScale & offsetMapUnitScale() const
Returns the map unit scale for the fill&#39;s offset.
void setSizeMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the symbol&#39;s size.
const QgsMapUnitScale & offsetMapUnitScale() const
Returns the map unit scale for the fill&#39;s offset.
QgsSvgMarkerSymbolLayer * mLayer
QgsSymbolWidgetContext context() const
Returns the context in which the symbol widget is shown, e.g., the associated map canvas and expressi...
QgsShapeburstFillSymbolLayer * mLayer
void setStrokeStyle(Qt::PenStyle strokeStyle)
virtual QColor color() const
The fill color.
QgsSymbolLayer * symbolLayer() override
void setDistanceYMapUnitScale(const QgsMapUnitScale &scale)
static const QString EXPR_SYMBOL_COLOR
Inbuilt variable name for symbol color variable.