QGIS API Documentation  3.24.2-Tisler (13c1a02865)
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 "qgslinesymbollayer.h"
20 #include "qgsmarkersymbollayer.h"
21 #include "qgsfillsymbollayer.h"
23 #include "qgssymbolslistwidget.h"
25 
26 #include "characterwidget.h"
27 #include "qgsdashspacedialog.h"
29 #include "qgssvgcache.h"
30 #include "qgssymbollayerutils.h"
31 #include "qgscolorramp.h"
32 #include "qgscolorrampbutton.h"
33 #include "qgsfontutils.h"
35 #include "qgsproperty.h"
36 #include "qgsstyle.h" //for symbol selector dialog
37 #include "qgsmapcanvas.h"
38 #include "qgsapplication.h"
39 #include "qgsvectorlayer.h"
40 #include "qgssvgselectorwidget.h"
41 #include "qgslogger.h"
42 #include "qgssettings.h"
45 #include "qgsauxiliarystorage.h"
46 #include "qgsimagecache.h"
47 #include "qgslinesymbol.h"
48 #include "qgsmarkersymbol.h"
49 #include "qgsfillsymbol.h"
50 #include "qgsiconutils.h"
51 
52 #include <QAbstractButton>
53 #include <QButtonGroup>
54 #include <QColorDialog>
55 #include <QCursor>
56 #include <QDir>
57 #include <QFileDialog>
58 #include <QPainter>
59 #include <QStandardItemModel>
60 #include <QSvgRenderer>
61 #include <QMessageBox>
62 #include <QMenu>
63 #include <QAction>
64 #include <QInputDialog>
65 #include <QBuffer>
66 #include <QRegularExpression>
67 
69 {
70  if ( auto *lExpressionContext = mContext.expressionContext() )
71  return *lExpressionContext;
72 
74 
76  if ( const QgsSymbolLayer *symbolLayer = const_cast< QgsSymbolLayerWidget * >( this )->symbolLayer() )
77  {
78  //cheat a bit - set the symbol color variable to match the symbol layer's color (when we should really be using the *symbols*
79  //color, but that's not accessible here). 99% of the time these will be the same anyway
81  }
82  expContext << symbolScope;
88  expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "symbol_layer_count" ), 1, true ) );
89  expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "symbol_layer_index" ), 1, true ) );
90  expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "symbol_marker_row" ), 1, true ) );
91  expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "symbol_marker_column" ), 1, true ) );
92 
93  // additional scopes
94  const auto constAdditionalExpressionContextScopes = mContext.additionalExpressionContextScopes();
95  for ( const QgsExpressionContextScope &scope : constAdditionalExpressionContextScopes )
96  {
97  expContext.appendScope( new QgsExpressionContextScope( scope ) );
98  }
99 
100  //TODO - show actual value
101  expContext.setOriginalValueVariable( QVariant() );
102 
103  QStringList highlights;
109  << QStringLiteral( "symbol_layer_count" ) << QStringLiteral( "symbol_layer_index" );
110 
111 
112  if ( expContext.hasVariable( QStringLiteral( "zoom_level" ) ) )
113  {
114  highlights << QStringLiteral( "zoom_level" );
115  }
116  if ( expContext.hasVariable( QStringLiteral( "vector_tile_zoom" ) ) )
117  {
118  highlights << QStringLiteral( "vector_tile_zoom" );
119  }
120 
121  expContext.setHighlightedVariables( highlights );
122 
123  return expContext;
124 }
125 
127 {
128  mContext = context;
129  const auto unitSelectionWidgets = findChildren<QgsUnitSelectionWidget *>();
130  for ( QgsUnitSelectionWidget *unitWidget : unitSelectionWidgets )
131  {
132  unitWidget->setMapCanvas( mContext.mapCanvas() );
133  }
134 }
135 
137 {
138  return mContext;
139 }
140 
142 {
143  button->init( key, symbolLayer()->dataDefinedProperties(), QgsSymbolLayer::propertyDefinitions(), mVectorLayer, true );
145  connect( button, &QgsPropertyOverrideButton::createAuxiliaryField, this, &QgsSymbolLayerWidget::createAuxiliaryField );
146 
147  button->registerExpressionContextGenerator( this );
148 }
149 
150 void QgsSymbolLayerWidget::createAuxiliaryField()
151 {
152  // try to create an auxiliary layer if not yet created
153  if ( !mVectorLayer->auxiliaryLayer() )
154  {
155  QgsNewAuxiliaryLayerDialog dlg( mVectorLayer, this );
156  dlg.exec();
157  }
158 
159  // return if still not exists
160  if ( !mVectorLayer->auxiliaryLayer() )
161  return;
162 
163  QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
164  const QgsSymbolLayer::Property key = static_cast< QgsSymbolLayer::Property >( button->propertyKey() );
166 
167  // create property in auxiliary storage if necessary
168  if ( !mVectorLayer->auxiliaryLayer()->exists( def ) )
169  {
170  QgsNewAuxiliaryFieldDialog dlg( def, mVectorLayer, true, this );
171  if ( dlg.exec() == QDialog::Accepted )
172  def = dlg.propertyDefinition();
173  }
174 
175  // return if still not exist
176  if ( !mVectorLayer->auxiliaryLayer()->exists( def ) )
177  return;
178 
179  // update property with join field name from auxiliary storage
180  QgsProperty property = button->toProperty();
181  property.setField( QgsAuxiliaryLayer::nameFromProperty( def, true ) );
182  property.setActive( true );
183  button->updateFieldLists();
184  button->setToProperty( property );
185  symbolLayer()->setDataDefinedProperty( key, button->toProperty() );
186 
187  emit changed();
188 }
189 
191 {
192  QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
193  const QgsSymbolLayer::Property key = static_cast< QgsSymbolLayer::Property >( button->propertyKey() );
194  symbolLayer()->setDataDefinedProperty( key, button->toProperty() );
195  emit changed();
196 }
197 
199  : QgsSymbolLayerWidget( parent, vl )
200 {
201  mLayer = nullptr;
202 
203  setupUi( this );
204  connect( mCustomCheckBox, &QCheckBox::stateChanged, this, &QgsSimpleLineSymbolLayerWidget::mCustomCheckBox_stateChanged );
205  connect( mChangePatternButton, &QPushButton::clicked, this, &QgsSimpleLineSymbolLayerWidget::mChangePatternButton_clicked );
206  connect( mPenWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::mPenWidthUnitWidget_changed );
207  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::mOffsetUnitWidget_changed );
208  connect( mDashPatternUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::mDashPatternUnitWidget_changed );
209  connect( mDrawInsideCheckBox, &QCheckBox::stateChanged, this, &QgsSimpleLineSymbolLayerWidget::mDrawInsideCheckBox_stateChanged );
210  connect( mPatternOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::patternOffsetUnitChanged );
211  connect( mCheckAlignDash, &QCheckBox::toggled, this, [ = ]
212  {
213  mCheckDashCorners->setEnabled( mCheckAlignDash->isChecked() );
214  if ( !mCheckAlignDash->isChecked() )
215  mCheckDashCorners->setChecked( false );
216 
217  if ( mLayer )
218  {
219  mLayer->setAlignDashPattern( mCheckAlignDash->isChecked() );
220  emit changed();
221  }
222  } );
223  connect( mCheckDashCorners, &QCheckBox::toggled, this, [ = ]
224  {
225  if ( mLayer )
226  {
227  mLayer->setTweakDashPatternOnCorners( mCheckDashCorners->isChecked() );
228  emit changed();
229  }
230  } );
231 
244 
245  btnChangeColor->setAllowOpacity( true );
246  btnChangeColor->setColorDialogTitle( tr( "Select Line Color" ) );
247  btnChangeColor->setContext( QStringLiteral( "symbology" ) );
248 
249  mColorDDBtn->registerLinkedWidget( btnChangeColor );
250 
251  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconAllRings.svg" ) ), tr( "All Rings" ), QgsLineSymbolLayer::AllRings );
252  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconExteriorRing.svg" ) ), tr( "Exterior Ring Only" ), QgsLineSymbolLayer::ExteriorRingOnly );
253  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconInteriorRings.svg" ) ), tr( "Interior Rings Only" ), QgsLineSymbolLayer::InteriorRingsOnly );
254  connect( mRingFilterComboBox, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]( int )
255  {
256  if ( mLayer )
257  {
258  mLayer->setRingFilter( static_cast< QgsLineSymbolLayer::RenderRingFilter >( mRingFilterComboBox->currentData().toInt() ) );
259  emit changed();
260  }
261  } );
262 
263  spinOffset->setClearValue( 0.0 );
264  spinPatternOffset->setClearValue( 0.0 );
265 
266  mTrimStartDistanceSpin->setClearValue( 0.0 );
267  mTrimDistanceEndSpin->setClearValue( 0.0 );
268 
269  //make a temporary symbol for the size assistant preview
270  mAssistantPreviewSymbol.reset( new QgsLineSymbol() );
271 
272  if ( vectorLayer() )
273  mPenWidthDDBtn->setSymbol( mAssistantPreviewSymbol );
274 
275  connect( spinWidth, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleLineSymbolLayerWidget::penWidthChanged );
276  connect( btnChangeColor, &QgsColorButton::colorChanged, this, &QgsSimpleLineSymbolLayerWidget::colorChanged );
277  connect( cboPenStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleLineSymbolLayerWidget::penStyleChanged );
278  connect( spinOffset, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleLineSymbolLayerWidget::offsetChanged );
279  connect( cboCapStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleLineSymbolLayerWidget::penStyleChanged );
280  connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleLineSymbolLayerWidget::penStyleChanged );
281  connect( spinPatternOffset, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleLineSymbolLayerWidget::patternOffsetChanged );
282 
283  connect( mTrimStartDistanceSpin, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value )
284  {
285  if ( !mLayer )
286  return;
287 
288  mLayer->setTrimDistanceStart( value );
289  emit changed();
290  } );
291  connect( mTrimDistanceStartUnitWidget, &QgsUnitSelectionWidget::changed, this, [ = ]
292  {
293  if ( !mLayer )
294  return;
295 
296  mLayer->setTrimDistanceStartUnit( mTrimDistanceStartUnitWidget->unit() );
297  mLayer->setTrimDistanceStartMapUnitScale( mTrimDistanceStartUnitWidget->getMapUnitScale() );
298  emit changed();
299  } );
300  connect( mTrimDistanceEndSpin, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value )
301  {
302  if ( !mLayer )
303  return;
304 
305  mLayer->setTrimDistanceEnd( value );
306  emit changed();
307  } );
308  connect( mTrimDistanceEndUnitWidget, &QgsUnitSelectionWidget::changed, this, [ = ]
309  {
310  if ( !mLayer )
311  return;
312 
313  mLayer->setTrimDistanceEndUnit( mTrimDistanceEndUnitWidget->unit() );
314  mLayer->setTrimDistanceEndMapUnitScale( mTrimDistanceEndUnitWidget->getMapUnitScale() );
315  emit changed();
316  } );
317 
318 
320 
321  connect( this, &QgsSymbolLayerWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::updateAssistantSymbol );
322 }
323 
325 
326 void QgsSimpleLineSymbolLayerWidget::updateAssistantSymbol()
327 {
328  for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
329  {
330  mAssistantPreviewSymbol->deleteSymbolLayer( i );
331  }
332  mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
334  if ( ddWidth )
335  mAssistantPreviewSymbol->setDataDefinedWidth( ddWidth );
336 }
337 
338 
340 {
341  if ( !layer || layer->layerType() != QLatin1String( "SimpleLine" ) )
342  return;
343 
344  // layer type is correct, we can do the cast
345  mLayer = static_cast<QgsSimpleLineSymbolLayer *>( layer );
346 
347  // set units
348  mPenWidthUnitWidget->blockSignals( true );
349  mPenWidthUnitWidget->setUnit( mLayer->widthUnit() );
350  mPenWidthUnitWidget->setMapUnitScale( mLayer->widthMapUnitScale() );
351  mPenWidthUnitWidget->blockSignals( false );
352  mOffsetUnitWidget->blockSignals( true );
353  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
354  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
355  mOffsetUnitWidget->blockSignals( false );
356  mDashPatternUnitWidget->blockSignals( true );
357  mDashPatternUnitWidget->setUnit( mLayer->customDashPatternUnit() );
358  mDashPatternUnitWidget->setMapUnitScale( mLayer->customDashPatternMapUnitScale() );
359  mDashPatternUnitWidget->blockSignals( false );
360 
361  whileBlocking( mPatternOffsetUnitWidget )->setUnit( mLayer->dashPatternOffsetUnit() );
362  whileBlocking( mPatternOffsetUnitWidget )->setMapUnitScale( mLayer->dashPatternOffsetMapUnitScale() );
363  whileBlocking( mTrimDistanceStartUnitWidget )->setUnit( mLayer->trimDistanceStartUnit() );
364  whileBlocking( mTrimDistanceStartUnitWidget )->setMapUnitScale( mLayer->trimDistanceStartMapUnitScale() );
365  whileBlocking( mTrimDistanceEndUnitWidget )->setUnit( mLayer->trimDistanceEndUnit() );
366  whileBlocking( mTrimDistanceEndUnitWidget )->setMapUnitScale( mLayer->trimDistanceEndMapUnitScale() );
367 
368  // set values
369  spinWidth->blockSignals( true );
370  spinWidth->setValue( mLayer->width() );
371  spinWidth->blockSignals( false );
372  btnChangeColor->blockSignals( true );
373  btnChangeColor->setColor( mLayer->color() );
374  btnChangeColor->blockSignals( false );
375  spinOffset->blockSignals( true );
376  spinOffset->setValue( mLayer->offset() );
377  spinOffset->blockSignals( false );
378  cboPenStyle->blockSignals( true );
379  cboJoinStyle->blockSignals( true );
380  cboCapStyle->blockSignals( true );
381  cboPenStyle->setPenStyle( mLayer->penStyle() );
382  cboJoinStyle->setPenJoinStyle( mLayer->penJoinStyle() );
383  cboCapStyle->setPenCapStyle( mLayer->penCapStyle() );
384  cboPenStyle->blockSignals( false );
385  cboJoinStyle->blockSignals( false );
386  cboCapStyle->blockSignals( false );
387  whileBlocking( spinPatternOffset )->setValue( mLayer->dashPatternOffset() );
388  whileBlocking( mTrimStartDistanceSpin )->setValue( mLayer->trimDistanceStart() );
389  whileBlocking( mTrimDistanceEndSpin )->setValue( mLayer->trimDistanceEnd() );
390 
391  //use a custom dash pattern?
392  const bool useCustomDashPattern = mLayer->useCustomDashPattern();
393  mChangePatternButton->setEnabled( useCustomDashPattern );
394  label_3->setEnabled( !useCustomDashPattern );
395  cboPenStyle->setEnabled( !useCustomDashPattern );
396  mCustomCheckBox->blockSignals( true );
397  mCustomCheckBox->setCheckState( useCustomDashPattern ? Qt::Checked : Qt::Unchecked );
398  mCustomCheckBox->blockSignals( false );
399 
400  //make sure height of custom dash button looks good under different platforms
401  const QSize size = mChangePatternButton->minimumSizeHint();
402  const int fontHeight = static_cast< int >( Qgis::UI_SCALE_FACTOR * fontMetrics().height() * 1.4 );
403  mChangePatternButton->setMinimumSize( QSize( size.width(), std::max( size.height(), fontHeight ) ) );
404 
405  //draw inside polygon?
406  const bool drawInsidePolygon = mLayer->drawInsidePolygon();
407  whileBlocking( mDrawInsideCheckBox )->setCheckState( drawInsidePolygon ? Qt::Checked : Qt::Unchecked );
408 
409  whileBlocking( mRingFilterComboBox )->setCurrentIndex( mRingFilterComboBox->findData( mLayer->ringFilter() ) );
410 
411  whileBlocking( mCheckAlignDash )->setChecked( mLayer->alignDashPattern() );
412  mCheckDashCorners->setEnabled( mLayer->alignDashPattern() );
413  whileBlocking( mCheckDashCorners )->setChecked( mLayer->tweakDashPatternOnCorners() && mLayer->alignDashPattern() );
414 
416 
427 
428  updateAssistantSymbol();
429 }
430 
432 {
433  return mLayer;
434 }
435 
437 {
439 
440  switch ( context.symbolType() )
441  {
444  //these settings only have an effect when the symbol layers is part of a fill symbol
445  mDrawInsideCheckBox->hide();
446  mRingFilterComboBox->hide();
447  mRingsLabel->hide();
448  break;
449 
452  break;
453  }
454 }
455 
456 void QgsSimpleLineSymbolLayerWidget::penWidthChanged()
457 {
458  mLayer->setWidth( spinWidth->value() );
460  emit changed();
461 }
462 
463 void QgsSimpleLineSymbolLayerWidget::colorChanged( const QColor &color )
464 {
465  mLayer->setColor( color );
466  emit changed();
467 }
468 
469 void QgsSimpleLineSymbolLayerWidget::penStyleChanged()
470 {
471  mLayer->setPenStyle( cboPenStyle->penStyle() );
472  mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
473  mLayer->setPenCapStyle( cboCapStyle->penCapStyle() );
475  emit changed();
476 }
477 
478 void QgsSimpleLineSymbolLayerWidget::offsetChanged()
479 {
480  mLayer->setOffset( spinOffset->value() );
482  emit changed();
483 }
484 
485 void QgsSimpleLineSymbolLayerWidget::patternOffsetChanged()
486 {
487  mLayer->setDashPatternOffset( spinPatternOffset->value() );
489  emit changed();
490 }
491 
492 void QgsSimpleLineSymbolLayerWidget::mCustomCheckBox_stateChanged( int state )
493 {
494  const bool checked = ( state == Qt::Checked );
495  mChangePatternButton->setEnabled( checked );
496  label_3->setEnabled( !checked );
497  cboPenStyle->setEnabled( !checked );
498 
499  mLayer->setUseCustomDashPattern( checked );
500  emit changed();
501 }
502 
503 void QgsSimpleLineSymbolLayerWidget::mChangePatternButton_clicked()
504 {
506  if ( panel && panel->dockMode() )
507  {
509  widget->setPanelTitle( tr( "Custom Dash Pattern" ) );
510  widget->setUnit( mDashPatternUnitWidget->unit() );
511  connect( widget, &QgsPanelWidget::widgetChanged, this, [ this, widget ]()
512  {
515  } );
517  panel->openPanel( widget );
518  return;
519  }
520 
522  d.setUnit( mDashPatternUnitWidget->unit() );
523  if ( d.exec() == QDialog::Accepted )
524  {
525  mLayer->setCustomDashVector( d.dashDotVector() );
527  emit changed();
528  }
529 }
530 
531 void QgsSimpleLineSymbolLayerWidget::mPenWidthUnitWidget_changed()
532 {
533  if ( mLayer )
534  {
535  mLayer->setWidthUnit( mPenWidthUnitWidget->unit() );
536  mLayer->setWidthMapUnitScale( mPenWidthUnitWidget->getMapUnitScale() );
538  emit changed();
539  }
540 }
541 
542 void QgsSimpleLineSymbolLayerWidget::mOffsetUnitWidget_changed()
543 {
544  if ( mLayer )
545  {
546  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
547  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
548  emit changed();
549  }
550 }
551 
552 void QgsSimpleLineSymbolLayerWidget::mDashPatternUnitWidget_changed()
553 {
554  if ( mLayer )
555  {
556  mLayer->setCustomDashPatternUnit( mDashPatternUnitWidget->unit() );
557  mLayer->setCustomDashPatternMapUnitScale( mDashPatternUnitWidget->getMapUnitScale() );
559  emit changed();
560  }
561 }
562 
563 void QgsSimpleLineSymbolLayerWidget::mDrawInsideCheckBox_stateChanged( int state )
564 {
565  const bool checked = ( state == Qt::Checked );
566  mLayer->setDrawInsidePolygon( checked );
567  emit changed();
568 }
569 
570 void QgsSimpleLineSymbolLayerWidget::patternOffsetUnitChanged()
571 {
572  if ( mLayer )
573  {
574  mLayer->setDashPatternOffsetUnit( mPatternOffsetUnitWidget->unit() );
575  mLayer->setDashPatternOffsetMapUnitScale( mPatternOffsetUnitWidget->getMapUnitScale() );
577  emit changed();
578  }
579 }
580 
582 {
583  if ( !mLayer )
584  {
585  return;
586  }
587  std::unique_ptr< QgsSimpleLineSymbolLayer > layerCopy( mLayer->clone() );
588  if ( !layerCopy )
589  {
590  return;
591  }
592  const QColor color = qApp->palette().color( QPalette::WindowText );
593  layerCopy->setColor( color );
594  // reset offset, we don't want to show that in the preview
595  layerCopy->setOffset( 0 );
596  layerCopy->setUseCustomDashPattern( true );
597 
598  QSize currentIconSize;
599  //icon size is button size with a small margin
600 #ifdef Q_OS_WIN
601  currentIconSize = QSize( mChangePatternButton->width() - 10, mChangePatternButton->height() - 6 );
602 #else
603  currentIconSize = QSize( mChangePatternButton->width() - 10, mChangePatternButton->height() - 12 );
604 #endif
605 
606  if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 )
607  {
608  return;
609  }
610 
611  //create an icon pixmap
612  const std::unique_ptr< QgsLineSymbol > previewSymbol = std::make_unique< QgsLineSymbol >( QgsSymbolLayerList() << layerCopy.release() );
613  const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( previewSymbol.get(), currentIconSize );
614  mChangePatternButton->setIconSize( currentIconSize );
615  mChangePatternButton->setIcon( icon );
616 
617  // set tooltip
618  // create very large preview image
619  const int width = static_cast< int >( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 23 );
620  const int height = static_cast< int >( width / 1.61803398875 ); // golden ratio
621 
622  const QPixmap pm = QgsSymbolLayerUtils::symbolPreviewPixmap( previewSymbol.get(), QSize( width, height ), height / 20 );
623  QByteArray data;
624  QBuffer buffer( &data );
625  pm.save( &buffer, "PNG", 100 );
626  mChangePatternButton->setToolTip( QStringLiteral( "<img src='data:image/png;base64, %3'>" ).arg( QString( data.toBase64() ) ) );
627 }
628 
630 {
631  QgsSymbolLayerWidget::resizeEvent( event );
632  // redraw custom dash pattern icon -- the button size has changed
634 }
635 
636 
638 
639 
641  : QgsSymbolLayerWidget( parent, vl )
642 {
643  mLayer = nullptr;
644 
645  setupUi( this );
646  connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
647  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
648  connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
649  connect( mStrokeStyleComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mStrokeStyleComboBox_currentIndexChanged );
650  connect( mStrokeWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
651  connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
652  connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
659 
660  btnChangeColorFill->setAllowOpacity( true );
661  btnChangeColorFill->setColorDialogTitle( tr( "Select Fill Color" ) );
662  btnChangeColorFill->setContext( QStringLiteral( "symbology" ) );
663  btnChangeColorFill->setShowNoColor( true );
664  btnChangeColorFill->setNoColorString( tr( "Transparent Fill" ) );
665  btnChangeColorStroke->setAllowOpacity( true );
666  btnChangeColorStroke->setColorDialogTitle( tr( "Select Stroke Color" ) );
667  btnChangeColorStroke->setContext( QStringLiteral( "symbology" ) );
668  btnChangeColorStroke->setShowNoColor( true );
669  btnChangeColorStroke->setNoColorString( tr( "Transparent Stroke" ) );
670 
671  mFillColorDDBtn->registerLinkedWidget( btnChangeColorFill );
672  mStrokeColorDDBtn->registerLinkedWidget( btnChangeColorStroke );
673 
674  spinOffsetX->setClearValue( 0.0 );
675  spinOffsetY->setClearValue( 0.0 );
676  spinAngle->setClearValue( 0.0 );
677 
678  //make a temporary symbol for the size assistant preview
679  mAssistantPreviewSymbol.reset( new QgsMarkerSymbol() );
680 
681  if ( vectorLayer() )
682  mSizeDDBtn->setSymbol( mAssistantPreviewSymbol );
683 
684  int size = lstNames->iconSize().width();
685 
686  size = std::max( 30, static_cast< int >( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 3 ) ) );
687 
688  lstNames->setGridSize( QSize( size * 1.2, size * 1.2 ) );
689  lstNames->setIconSize( QSize( size, size ) );
690 
691  const double markerSize = size * 0.8;
693  for ( const Qgis::MarkerShape shape : shapes )
694  {
695  QgsSimpleMarkerSymbolLayer *lyr = new QgsSimpleMarkerSymbolLayer( shape, markerSize );
697  lyr->setColor( QColor( 200, 200, 200 ) );
698  lyr->setStrokeColor( QColor( 0, 0, 0 ) );
699  const QIcon icon = QgsSymbolLayerUtils::symbolLayerPreviewIcon( lyr, QgsUnitTypes::RenderPixels, QSize( size, size ) );
700  QListWidgetItem *item = new QListWidgetItem( icon, QString(), lstNames );
701  item->setData( Qt::UserRole, static_cast< int >( shape ) );
702  item->setToolTip( QgsSimpleMarkerSymbolLayerBase::encodeShape( shape ) );
703  delete lyr;
704  }
705  // show at least 3 rows
706  lstNames->setMinimumHeight( lstNames->gridSize().height() * 3.1 );
707 
708  connect( lstNames, &QListWidget::currentRowChanged, this, &QgsSimpleMarkerSymbolLayerWidget::setShape );
709  connect( btnChangeColorStroke, &QgsColorButton::colorChanged, this, &QgsSimpleMarkerSymbolLayerWidget::setColorStroke );
711  connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::penJoinStyleChanged );
712  connect( cboCapStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::penCapStyleChanged );
713  connect( spinSize, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setSize );
714  connect( spinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setAngle );
715  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setOffset );
716  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setOffset );
717  connect( this, &QgsSymbolLayerWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::updateAssistantSymbol );
718 }
719 
721 
723 {
724  if ( layer->layerType() != QLatin1String( "SimpleMarker" ) )
725  return;
726 
727  // layer type is correct, we can do the cast
728  mLayer = static_cast<QgsSimpleMarkerSymbolLayer *>( layer );
729 
730  // set values
731  const Qgis::MarkerShape shape = mLayer->shape();
732  for ( int i = 0; i < lstNames->count(); ++i )
733  {
734  if ( static_cast< Qgis::MarkerShape >( lstNames->item( i )->data( Qt::UserRole ).toInt() ) == shape )
735  {
736  lstNames->setCurrentRow( i );
737  break;
738  }
739  }
740  btnChangeColorStroke->blockSignals( true );
741  btnChangeColorStroke->setColor( mLayer->strokeColor() );
742  btnChangeColorStroke->blockSignals( false );
743  btnChangeColorFill->blockSignals( true );
744  btnChangeColorFill->setColor( mLayer->fillColor() );
745  btnChangeColorFill->setEnabled( QgsSimpleMarkerSymbolLayerBase::shapeIsFilled( mLayer->shape() ) );
746  btnChangeColorFill->blockSignals( false );
747  spinSize->blockSignals( true );
748  spinSize->setValue( mLayer->size() );
749  spinSize->blockSignals( false );
750  spinAngle->blockSignals( true );
751  spinAngle->setValue( mLayer->angle() );
752  spinAngle->blockSignals( false );
753  mStrokeStyleComboBox->blockSignals( true );
754  mStrokeStyleComboBox->setPenStyle( mLayer->strokeStyle() );
755  mStrokeStyleComboBox->blockSignals( false );
756  mStrokeWidthSpinBox->blockSignals( true );
757  mStrokeWidthSpinBox->setValue( mLayer->strokeWidth() );
758  mStrokeWidthSpinBox->blockSignals( false );
759  cboJoinStyle->blockSignals( true );
760  cboJoinStyle->setPenJoinStyle( mLayer->penJoinStyle() );
761  cboJoinStyle->blockSignals( false );
762  cboCapStyle->blockSignals( true );
763  cboCapStyle->setPenCapStyle( mLayer->penCapStyle() );
764  cboCapStyle->blockSignals( false );
765 
766  // without blocking signals the value gets changed because of slot setOffset()
767  spinOffsetX->blockSignals( true );
768  spinOffsetX->setValue( mLayer->offset().x() );
769  spinOffsetX->blockSignals( false );
770  spinOffsetY->blockSignals( true );
771  spinOffsetY->setValue( mLayer->offset().y() );
772  spinOffsetY->blockSignals( false );
773 
774  mSizeUnitWidget->blockSignals( true );
775  mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
776  mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
777  mSizeUnitWidget->blockSignals( false );
778  mOffsetUnitWidget->blockSignals( true );
779  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
780  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
781  mOffsetUnitWidget->blockSignals( false );
782  mStrokeWidthUnitWidget->blockSignals( true );
783  mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
784  mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
785  mStrokeWidthUnitWidget->blockSignals( false );
786 
787  //anchor points
788  mHorizontalAnchorComboBox->blockSignals( true );
789  mVerticalAnchorComboBox->blockSignals( true );
790  mHorizontalAnchorComboBox->setCurrentIndex( mLayer->horizontalAnchorPoint() );
791  mVerticalAnchorComboBox->setCurrentIndex( mLayer->verticalAnchorPoint() );
792  mHorizontalAnchorComboBox->blockSignals( false );
793  mVerticalAnchorComboBox->blockSignals( false );
794 
807 
808  updateAssistantSymbol();
809 }
810 
812 {
813  return mLayer;
814 }
815 
816 void QgsSimpleMarkerSymbolLayerWidget::setShape()
817 {
818  mLayer->setShape( static_cast< Qgis::MarkerShape >( lstNames->currentItem()->data( Qt::UserRole ).toInt() ) );
819  btnChangeColorFill->setEnabled( QgsSimpleMarkerSymbolLayerBase::shapeIsFilled( mLayer->shape() ) );
820  emit changed();
821 }
822 
824 {
825  mLayer->setStrokeColor( color );
826  emit changed();
827 }
828 
830 {
831  mLayer->setColor( color );
832  emit changed();
833 }
834 
835 void QgsSimpleMarkerSymbolLayerWidget::penJoinStyleChanged()
836 {
837  mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
838  emit changed();
839 }
840 
841 void QgsSimpleMarkerSymbolLayerWidget::penCapStyleChanged()
842 {
843  mLayer->setPenCapStyle( cboCapStyle->penCapStyle() );
844  emit changed();
845 }
846 
847 void QgsSimpleMarkerSymbolLayerWidget::setSize()
848 {
849  mLayer->setSize( spinSize->value() );
850  emit changed();
851 }
852 
853 void QgsSimpleMarkerSymbolLayerWidget::setAngle()
854 {
855  mLayer->setAngle( spinAngle->value() );
856  emit changed();
857 }
858 
859 void QgsSimpleMarkerSymbolLayerWidget::setOffset()
860 {
861  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
862  emit changed();
863 }
864 
865 void QgsSimpleMarkerSymbolLayerWidget::mStrokeStyleComboBox_currentIndexChanged( int index )
866 {
867  Q_UNUSED( index )
868 
869  if ( mLayer )
870  {
871  mLayer->setStrokeStyle( mStrokeStyleComboBox->penStyle() );
872  emit changed();
873  }
874 }
875 
876 void QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
877 {
878  if ( mLayer )
879  {
880  mLayer->setStrokeWidth( d );
881  emit changed();
882  }
883 }
884 
885 void QgsSimpleMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
886 {
887  if ( mLayer )
888  {
889  mLayer->setSizeUnit( mSizeUnitWidget->unit() );
890  mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
891  emit changed();
892  }
893 }
894 
895 void QgsSimpleMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
896 {
897  if ( mLayer )
898  {
899  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
900  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
901  emit changed();
902  }
903 }
904 
905 void QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
906 {
907  if ( mLayer )
908  {
909  mLayer->setStrokeWidthUnit( mStrokeWidthUnitWidget->unit() );
910  mLayer->setStrokeWidthMapUnitScale( mStrokeWidthUnitWidget->getMapUnitScale() );
911  emit changed();
912  }
913 }
914 
915 void QgsSimpleMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
916 {
917  if ( mLayer )
918  {
920  emit changed();
921  }
922 }
923 
924 void QgsSimpleMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
925 {
926  if ( mLayer )
927  {
929  emit changed();
930  }
931 }
932 
933 void QgsSimpleMarkerSymbolLayerWidget::updateAssistantSymbol()
934 {
935  for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
936  {
937  mAssistantPreviewSymbol->deleteSymbolLayer( i );
938  }
939  mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
941  if ( ddSize )
942  mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
943 }
944 
945 
947 
949  : QgsSymbolLayerWidget( parent, vl )
950 {
951  mLayer = nullptr;
952 
953  setupUi( this );
954  connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleFillSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
955  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleFillSymbolLayerWidget::mOffsetUnitWidget_changed );
960 
961  btnChangeColor->setAllowOpacity( true );
962  btnChangeColor->setColorDialogTitle( tr( "Select Fill Color" ) );
963  btnChangeColor->setContext( QStringLiteral( "symbology" ) );
964  btnChangeColor->setShowNoColor( true );
965  btnChangeColor->setNoColorString( tr( "Transparent Fill" ) );
966  btnChangeStrokeColor->setAllowOpacity( true );
967  btnChangeStrokeColor->setColorDialogTitle( tr( "Select Stroke Color" ) );
968  btnChangeStrokeColor->setContext( QStringLiteral( "symbology" ) );
969  btnChangeStrokeColor->setShowNoColor( true );
970  btnChangeStrokeColor->setNoColorString( tr( "Transparent Stroke" ) );
971 
972  spinOffsetX->setClearValue( 0.0 );
973  spinOffsetY->setClearValue( 0.0 );
974 
976  connect( cboFillStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleFillSymbolLayerWidget::setBrushStyle );
977  connect( btnChangeStrokeColor, &QgsColorButton::colorChanged, this, &QgsSimpleFillSymbolLayerWidget::setStrokeColor );
978  connect( spinStrokeWidth, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleFillSymbolLayerWidget::strokeWidthChanged );
979  connect( cboStrokeStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleFillSymbolLayerWidget::strokeStyleChanged );
980  connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleFillSymbolLayerWidget::strokeStyleChanged );
981  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleFillSymbolLayerWidget::offsetChanged );
982  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleFillSymbolLayerWidget::offsetChanged );
983 
984  mFillColorDDBtn->registerLinkedWidget( btnChangeColor );
985  mStrokeColorDDBtn->registerLinkedWidget( btnChangeStrokeColor );
986 }
987 
989 {
990  if ( layer->layerType() != QLatin1String( "SimpleFill" ) )
991  return;
992 
993  // layer type is correct, we can do the cast
994  mLayer = static_cast<QgsSimpleFillSymbolLayer *>( layer );
995 
996  // set values
997  btnChangeColor->blockSignals( true );
998  btnChangeColor->setColor( mLayer->color() );
999  btnChangeColor->blockSignals( false );
1000  cboFillStyle->blockSignals( true );
1001  cboFillStyle->setBrushStyle( mLayer->brushStyle() );
1002  cboFillStyle->blockSignals( false );
1003  btnChangeStrokeColor->blockSignals( true );
1004  btnChangeStrokeColor->setColor( mLayer->strokeColor() );
1005  btnChangeStrokeColor->blockSignals( false );
1006  cboStrokeStyle->blockSignals( true );
1007  cboStrokeStyle->setPenStyle( mLayer->strokeStyle() );
1008  cboStrokeStyle->blockSignals( false );
1009  spinStrokeWidth->blockSignals( true );
1010  spinStrokeWidth->setValue( mLayer->strokeWidth() );
1011  spinStrokeWidth->blockSignals( false );
1012  cboJoinStyle->blockSignals( true );
1013  cboJoinStyle->setPenJoinStyle( mLayer->penJoinStyle() );
1014  cboJoinStyle->blockSignals( false );
1015  spinOffsetX->blockSignals( true );
1016  spinOffsetX->setValue( mLayer->offset().x() );
1017  spinOffsetX->blockSignals( false );
1018  spinOffsetY->blockSignals( true );
1019  spinOffsetY->setValue( mLayer->offset().y() );
1020  spinOffsetY->blockSignals( false );
1021 
1022  mStrokeWidthUnitWidget->blockSignals( true );
1023  mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
1024  mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
1025  mStrokeWidthUnitWidget->blockSignals( false );
1026  mOffsetUnitWidget->blockSignals( true );
1027  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1028  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1029  mOffsetUnitWidget->blockSignals( false );
1030 
1038 }
1039 
1041 {
1042  return mLayer;
1043 }
1044 
1045 void QgsSimpleFillSymbolLayerWidget::setColor( const QColor &color )
1046 {
1047  mLayer->setColor( color );
1048  emit changed();
1049 }
1050 
1052 {
1053  mLayer->setStrokeColor( color );
1054  emit changed();
1055 }
1056 
1057 void QgsSimpleFillSymbolLayerWidget::setBrushStyle()
1058 {
1059  mLayer->setBrushStyle( cboFillStyle->brushStyle() );
1060  emit changed();
1061 }
1062 
1063 void QgsSimpleFillSymbolLayerWidget::strokeWidthChanged()
1064 {
1065  mLayer->setStrokeWidth( spinStrokeWidth->value() );
1066  emit changed();
1067 }
1068 
1069 void QgsSimpleFillSymbolLayerWidget::strokeStyleChanged()
1070 {
1071  mLayer->setStrokeStyle( cboStrokeStyle->penStyle() );
1072  mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
1073  emit changed();
1074 }
1075 
1076 void QgsSimpleFillSymbolLayerWidget::offsetChanged()
1077 {
1078  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1079  emit changed();
1080 }
1081 
1082 void QgsSimpleFillSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
1083 {
1084  if ( mLayer )
1085  {
1086  mLayer->setStrokeWidthUnit( mStrokeWidthUnitWidget->unit() );
1087  mLayer->setStrokeWidthMapUnitScale( mStrokeWidthUnitWidget->getMapUnitScale() );
1088  emit changed();
1089  }
1090 }
1091 
1092 void QgsSimpleFillSymbolLayerWidget::mOffsetUnitWidget_changed()
1093 {
1094  if ( mLayer )
1095  {
1096  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1097  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1098  emit changed();
1099  }
1100 }
1101 
1103 
1105  : QgsSymbolLayerWidget( parent, vl )
1106 {
1107  mLayer = nullptr;
1108 
1109  setupUi( this );
1110  connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFilledMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
1111  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFilledMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
1112  connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFilledMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
1113  connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFilledMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
1118 
1119  spinOffsetX->setClearValue( 0.0 );
1120  spinOffsetY->setClearValue( 0.0 );
1121  spinAngle->setClearValue( 0.0 );
1122 
1123  //make a temporary symbol for the size assistant preview
1124  mAssistantPreviewSymbol.reset( new QgsMarkerSymbol() );
1125 
1126  if ( vectorLayer() )
1127  mSizeDDBtn->setSymbol( mAssistantPreviewSymbol );
1128 
1129  int size = lstNames->iconSize().width();
1130  size = std::max( 30, static_cast< int >( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 3 ) ) );
1131  lstNames->setGridSize( QSize( size * 1.2, size * 1.2 ) );
1132  lstNames->setIconSize( QSize( size, size ) );
1133 
1134  const double markerSize = size * 0.8;
1136  for ( const Qgis::MarkerShape shape : shapes )
1137  {
1138  QgsSimpleMarkerSymbolLayer *lyr = new QgsSimpleMarkerSymbolLayer( shape, markerSize );
1140  lyr->setColor( QColor( 200, 200, 200 ) );
1141  lyr->setStrokeColor( QColor( 0, 0, 0 ) );
1142  const QIcon icon = QgsSymbolLayerUtils::symbolLayerPreviewIcon( lyr, QgsUnitTypes::RenderPixels, QSize( size, size ) );
1143  QListWidgetItem *item = new QListWidgetItem( icon, QString(), lstNames );
1144  item->setData( Qt::UserRole, static_cast< int >( shape ) );
1145  item->setToolTip( QgsSimpleMarkerSymbolLayerBase::encodeShape( shape ) );
1146  delete lyr;
1147  }
1148  // show at least 3 rows
1149  lstNames->setMinimumHeight( lstNames->gridSize().height() * 3.1 );
1150 
1151  connect( lstNames, &QListWidget::currentRowChanged, this, &QgsFilledMarkerSymbolLayerWidget::setShape );
1152  connect( spinSize, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setSize );
1153  connect( spinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setAngle );
1154  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setOffset );
1155  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setOffset );
1156  connect( this, &QgsSymbolLayerWidget::changed, this, &QgsFilledMarkerSymbolLayerWidget::updateAssistantSymbol );
1157 }
1158 
1160 
1162 {
1163  if ( layer->layerType() != QLatin1String( "FilledMarker" ) )
1164  return;
1165 
1166  // layer type is correct, we can do the cast
1167  mLayer = static_cast<QgsFilledMarkerSymbolLayer *>( layer );
1168 
1169  // set values
1170  const Qgis::MarkerShape shape = mLayer->shape();
1171  for ( int i = 0; i < lstNames->count(); ++i )
1172  {
1173  if ( static_cast< Qgis::MarkerShape >( lstNames->item( i )->data( Qt::UserRole ).toInt() ) == shape )
1174  {
1175  lstNames->setCurrentRow( i );
1176  break;
1177  }
1178  }
1179  whileBlocking( spinSize )->setValue( mLayer->size() );
1180  whileBlocking( spinAngle )->setValue( mLayer->angle() );
1181  whileBlocking( spinOffsetX )->setValue( mLayer->offset().x() );
1182  whileBlocking( spinOffsetY )->setValue( mLayer->offset().y() );
1183 
1184  mSizeUnitWidget->blockSignals( true );
1185  mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
1186  mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
1187  mSizeUnitWidget->blockSignals( false );
1188  mOffsetUnitWidget->blockSignals( true );
1189  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1190  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1191  mOffsetUnitWidget->blockSignals( false );
1192 
1193  //anchor points
1194  whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mLayer->horizontalAnchorPoint() );
1195  whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mLayer->verticalAnchorPoint() );
1196 
1203 
1204  updateAssistantSymbol();
1205 }
1206 
1208 {
1209  return mLayer;
1210 }
1211 
1212 void QgsFilledMarkerSymbolLayerWidget::setShape()
1213 {
1214  mLayer->setShape( static_cast< Qgis::MarkerShape >( lstNames->currentItem()->data( Qt::UserRole ).toInt() ) );
1215  emit changed();
1216 }
1217 
1218 void QgsFilledMarkerSymbolLayerWidget::setSize()
1219 {
1220  mLayer->setSize( spinSize->value() );
1221  emit changed();
1222 }
1223 
1224 void QgsFilledMarkerSymbolLayerWidget::setAngle()
1225 {
1226  mLayer->setAngle( spinAngle->value() );
1227  emit changed();
1228 }
1229 
1230 void QgsFilledMarkerSymbolLayerWidget::setOffset()
1231 {
1232  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1233  emit changed();
1234 }
1235 
1236 void QgsFilledMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
1237 {
1238  if ( mLayer )
1239  {
1240  mLayer->setSizeUnit( mSizeUnitWidget->unit() );
1241  mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
1242  emit changed();
1243  }
1244 }
1245 
1246 void QgsFilledMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
1247 {
1248  if ( mLayer )
1249  {
1250  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1251  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1252  emit changed();
1253  }
1254 }
1255 
1256 void QgsFilledMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
1257 {
1258  if ( mLayer )
1259  {
1261  emit changed();
1262  }
1263 }
1264 
1265 void QgsFilledMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
1266 {
1267  if ( mLayer )
1268  {
1270  emit changed();
1271  }
1272 }
1273 
1274 void QgsFilledMarkerSymbolLayerWidget::updateAssistantSymbol()
1275 {
1276  for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
1277  {
1278  mAssistantPreviewSymbol->deleteSymbolLayer( i );
1279  }
1280  mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
1282  if ( ddSize )
1283  mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
1284 }
1285 
1286 
1288 
1290  : QgsSymbolLayerWidget( parent, vl )
1291 {
1292  mLayer = nullptr;
1293 
1294  setupUi( this );
1295  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsGradientFillSymbolLayerWidget::mOffsetUnitWidget_changed );
1296  connect( mSpinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::mSpinAngle_valueChanged );
1299 
1300  btnColorRamp->setShowGradientOnly( true );
1301 
1302  btnChangeColor->setAllowOpacity( true );
1303  btnChangeColor->setColorDialogTitle( tr( "Select Gradient Color" ) );
1304  btnChangeColor->setContext( QStringLiteral( "symbology" ) );
1305  btnChangeColor->setShowNoColor( true );
1306  btnChangeColor->setNoColorString( tr( "Transparent" ) );
1307  btnChangeColor2->setAllowOpacity( true );
1308  btnChangeColor2->setColorDialogTitle( tr( "Select Gradient Color" ) );
1309  btnChangeColor2->setContext( QStringLiteral( "symbology" ) );
1310  btnChangeColor2->setShowNoColor( true );
1311  btnChangeColor2->setNoColorString( tr( "Transparent" ) );
1312 
1313  mStartColorDDBtn->registerLinkedWidget( btnChangeColor );
1314  mEndColorDDBtn->registerLinkedWidget( btnChangeColor2 );
1315 
1316  spinOffsetX->setClearValue( 0.0 );
1317  spinOffsetY->setClearValue( 0.0 );
1318  mSpinAngle->setClearValue( 0.0 );
1319 
1323  connect( cboGradientType, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGradientFillSymbolLayerWidget::setGradientType );
1324  connect( cboCoordinateMode, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGradientFillSymbolLayerWidget::setCoordinateMode );
1325  connect( cboGradientSpread, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGradientFillSymbolLayerWidget::setGradientSpread );
1326  connect( radioTwoColor, &QAbstractButton::toggled, this, &QgsGradientFillSymbolLayerWidget::colorModeChanged );
1327  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::offsetChanged );
1328  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::offsetChanged );
1329  connect( spinRefPoint1X, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1330  connect( spinRefPoint1Y, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1331  connect( checkRefPoint1Centroid, &QAbstractButton::toggled, this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1332  connect( spinRefPoint2X, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1333  connect( spinRefPoint2Y, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1334  connect( checkRefPoint2Centroid, &QAbstractButton::toggled, this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1335 }
1336 
1338 {
1339  if ( layer->layerType() != QLatin1String( "GradientFill" ) )
1340  return;
1341 
1342  // layer type is correct, we can do the cast
1343  mLayer = static_cast<QgsGradientFillSymbolLayer *>( layer );
1344 
1345  // set values
1346  btnChangeColor->blockSignals( true );
1347  btnChangeColor->setColor( mLayer->color() );
1348  btnChangeColor->blockSignals( false );
1349  btnChangeColor2->blockSignals( true );
1350  btnChangeColor2->setColor( mLayer->color2() );
1351  btnChangeColor2->blockSignals( false );
1352 
1354  {
1355  radioTwoColor->setChecked( true );
1356  btnColorRamp->setEnabled( false );
1357  }
1358  else
1359  {
1360  radioColorRamp->setChecked( true );
1361  btnChangeColor->setEnabled( false );
1362  btnChangeColor2->setEnabled( false );
1363  }
1364 
1365  // set source color ramp
1366  if ( mLayer->colorRamp() )
1367  {
1368  btnColorRamp->blockSignals( true );
1369  btnColorRamp->setColorRamp( mLayer->colorRamp() );
1370  btnColorRamp->blockSignals( false );
1371  }
1372 
1373  cboGradientType->blockSignals( true );
1374  switch ( mLayer->gradientType() )
1375  {
1377  cboGradientType->setCurrentIndex( 0 );
1378  break;
1380  cboGradientType->setCurrentIndex( 1 );
1381  break;
1383  cboGradientType->setCurrentIndex( 2 );
1384  break;
1385  }
1386  cboGradientType->blockSignals( false );
1387 
1388  cboCoordinateMode->blockSignals( true );
1389  switch ( mLayer->coordinateMode() )
1390  {
1392  cboCoordinateMode->setCurrentIndex( 1 );
1393  checkRefPoint1Centroid->setEnabled( false );
1394  checkRefPoint2Centroid->setEnabled( false );
1395  break;
1397  default:
1398  cboCoordinateMode->setCurrentIndex( 0 );
1399  break;
1400  }
1401  cboCoordinateMode->blockSignals( false );
1402 
1403  cboGradientSpread->blockSignals( true );
1404  switch ( mLayer->gradientSpread() )
1405  {
1407  cboGradientSpread->setCurrentIndex( 0 );
1408  break;
1410  cboGradientSpread->setCurrentIndex( 1 );
1411  break;
1413  cboGradientSpread->setCurrentIndex( 2 );
1414  break;
1415  }
1416  cboGradientSpread->blockSignals( false );
1417 
1418  spinRefPoint1X->blockSignals( true );
1419  spinRefPoint1X->setValue( mLayer->referencePoint1().x() );
1420  spinRefPoint1X->blockSignals( false );
1421  spinRefPoint1Y->blockSignals( true );
1422  spinRefPoint1Y->setValue( mLayer->referencePoint1().y() );
1423  spinRefPoint1Y->blockSignals( false );
1424  checkRefPoint1Centroid->blockSignals( true );
1425  checkRefPoint1Centroid->setChecked( mLayer->referencePoint1IsCentroid() );
1427  {
1428  spinRefPoint1X->setEnabled( false );
1429  spinRefPoint1Y->setEnabled( false );
1430  }
1431  checkRefPoint1Centroid->blockSignals( false );
1432  spinRefPoint2X->blockSignals( true );
1433  spinRefPoint2X->setValue( mLayer->referencePoint2().x() );
1434  spinRefPoint2X->blockSignals( false );
1435  spinRefPoint2Y->blockSignals( true );
1436  spinRefPoint2Y->setValue( mLayer->referencePoint2().y() );
1437  spinRefPoint2Y->blockSignals( false );
1438  checkRefPoint2Centroid->blockSignals( true );
1439  checkRefPoint2Centroid->setChecked( mLayer->referencePoint2IsCentroid() );
1441  {
1442  spinRefPoint2X->setEnabled( false );
1443  spinRefPoint2Y->setEnabled( false );
1444  }
1445  checkRefPoint2Centroid->blockSignals( false );
1446 
1447  spinOffsetX->blockSignals( true );
1448  spinOffsetX->setValue( mLayer->offset().x() );
1449  spinOffsetX->blockSignals( false );
1450  spinOffsetY->blockSignals( true );
1451  spinOffsetY->setValue( mLayer->offset().y() );
1452  spinOffsetY->blockSignals( false );
1453  mSpinAngle->blockSignals( true );
1454  mSpinAngle->setValue( mLayer->angle() );
1455  mSpinAngle->blockSignals( false );
1456 
1457  mOffsetUnitWidget->blockSignals( true );
1458  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1459  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1460  mOffsetUnitWidget->blockSignals( false );
1461 
1475 }
1476 
1478 {
1479  return mLayer;
1480 }
1481 
1483 {
1484  mLayer->setColor( color );
1485  emit changed();
1486 }
1487 
1489 {
1490  mLayer->setColor2( color );
1491  emit changed();
1492 }
1493 
1494 void QgsGradientFillSymbolLayerWidget::colorModeChanged()
1495 {
1496  if ( radioTwoColor->isChecked() )
1497  {
1499  }
1500  else
1501  {
1503  }
1504  emit changed();
1505 }
1506 
1508 {
1509  if ( btnColorRamp->isNull() )
1510  return;
1511 
1512  mLayer->setColorRamp( btnColorRamp->colorRamp()->clone() );
1513  emit changed();
1514 }
1515 
1517 {
1518  switch ( index )
1519  {
1520  case 0:
1522  //set sensible default reference points
1523  spinRefPoint1X->setValue( 0.5 );
1524  spinRefPoint1Y->setValue( 0 );
1525  spinRefPoint2X->setValue( 0.5 );
1526  spinRefPoint2Y->setValue( 1 );
1527  break;
1528  case 1:
1530  //set sensible default reference points
1531  spinRefPoint1X->setValue( 0 );
1532  spinRefPoint1Y->setValue( 0 );
1533  spinRefPoint2X->setValue( 1 );
1534  spinRefPoint2Y->setValue( 1 );
1535  break;
1536  case 2:
1538  spinRefPoint1X->setValue( 0.5 );
1539  spinRefPoint1Y->setValue( 0.5 );
1540  spinRefPoint2X->setValue( 1 );
1541  spinRefPoint2Y->setValue( 1 );
1542  break;
1543  }
1544  emit changed();
1545 }
1546 
1548 {
1549 
1550  switch ( index )
1551  {
1552  case 0:
1553  //feature coordinate mode
1555  //allow choice of centroid reference positions
1556  checkRefPoint1Centroid->setEnabled( true );
1557  checkRefPoint2Centroid->setEnabled( true );
1558  break;
1559  case 1:
1560  //viewport coordinate mode
1562  //disable choice of centroid reference positions
1563  checkRefPoint1Centroid->setChecked( Qt::Unchecked );
1564  checkRefPoint1Centroid->setEnabled( false );
1565  checkRefPoint2Centroid->setChecked( Qt::Unchecked );
1566  checkRefPoint2Centroid->setEnabled( false );
1567  break;
1568  }
1569 
1570  emit changed();
1571 }
1572 
1574 {
1575  switch ( index )
1576  {
1577  case 0:
1579  break;
1580  case 1:
1582  break;
1583  case 2:
1585  break;
1586  }
1587 
1588  emit changed();
1589 }
1590 
1591 void QgsGradientFillSymbolLayerWidget::offsetChanged()
1592 {
1593  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1594  emit changed();
1595 }
1596 
1597 void QgsGradientFillSymbolLayerWidget::referencePointChanged()
1598 {
1599  mLayer->setReferencePoint1( QPointF( spinRefPoint1X->value(), spinRefPoint1Y->value() ) );
1600  mLayer->setReferencePoint1IsCentroid( checkRefPoint1Centroid->isChecked() );
1601  mLayer->setReferencePoint2( QPointF( spinRefPoint2X->value(), spinRefPoint2Y->value() ) );
1602  mLayer->setReferencePoint2IsCentroid( checkRefPoint2Centroid->isChecked() );
1603  emit changed();
1604 }
1605 
1606 void QgsGradientFillSymbolLayerWidget::mSpinAngle_valueChanged( double value )
1607 {
1608  mLayer->setAngle( value );
1609  emit changed();
1610 }
1611 
1612 void QgsGradientFillSymbolLayerWidget::mOffsetUnitWidget_changed()
1613 {
1614  if ( mLayer )
1615  {
1616  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1617  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1618  emit changed();
1619  }
1620 }
1621 
1623 
1625  : QgsSymbolLayerWidget( parent, vl )
1626 {
1627  mLayer = nullptr;
1628 
1629  setupUi( this );
1630  connect( mSpinBlurRadius, qOverload< int >( &QSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::mSpinBlurRadius_valueChanged );
1631  connect( mSpinMaxDistance, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::mSpinMaxDistance_valueChanged );
1632  connect( mDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsShapeburstFillSymbolLayerWidget::mDistanceUnitWidget_changed );
1633  connect( mRadioUseWholeShape, &QRadioButton::toggled, this, &QgsShapeburstFillSymbolLayerWidget::mRadioUseWholeShape_toggled );
1634  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsShapeburstFillSymbolLayerWidget::mOffsetUnitWidget_changed );
1635  connect( mIgnoreRingsCheckBox, &QCheckBox::stateChanged, this, &QgsShapeburstFillSymbolLayerWidget::mIgnoreRingsCheckBox_stateChanged );
1640 
1641  QButtonGroup *group1 = new QButtonGroup( this );
1642  group1->addButton( radioColorRamp );
1643  group1->addButton( radioTwoColor );
1644  QButtonGroup *group2 = new QButtonGroup( this );
1645  group2->addButton( mRadioUseMaxDistance );
1646  group2->addButton( mRadioUseWholeShape );
1647  btnChangeColor->setAllowOpacity( true );
1648  btnChangeColor->setColorDialogTitle( tr( "Select Gradient Color" ) );
1649  btnChangeColor->setContext( QStringLiteral( "symbology" ) );
1650  btnChangeColor->setShowNoColor( true );
1651  btnChangeColor->setNoColorString( tr( "Transparent" ) );
1652  btnChangeColor2->setAllowOpacity( true );
1653  btnChangeColor2->setColorDialogTitle( tr( "Select Gradient Color" ) );
1654  btnChangeColor2->setContext( QStringLiteral( "symbology" ) );
1655  btnChangeColor2->setShowNoColor( true );
1656  btnChangeColor2->setNoColorString( tr( "Transparent" ) );
1657 
1658  mStartColorDDBtn->registerLinkedWidget( btnChangeColor );
1659  mEndColorDDBtn->registerLinkedWidget( btnChangeColor2 );
1660 
1661  spinOffsetX->setClearValue( 0.0 );
1662  spinOffsetY->setClearValue( 0.0 );
1663  mSpinMaxDistance->setClearValue( 5.0 );
1664 
1665  btnColorRamp->setShowGradientOnly( true );
1666 
1667  connect( btnColorRamp, &QgsColorRampButton::colorRampChanged, this, &QgsShapeburstFillSymbolLayerWidget::applyColorRamp );
1668 
1671  connect( radioTwoColor, &QAbstractButton::toggled, this, &QgsShapeburstFillSymbolLayerWidget::colorModeChanged );
1672  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::offsetChanged );
1673  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::offsetChanged );
1674 
1675  connect( mBlurSlider, &QAbstractSlider::valueChanged, mSpinBlurRadius, &QSpinBox::setValue );
1676  connect( mSpinBlurRadius, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), mBlurSlider, &QAbstractSlider::setValue );
1677 }
1678 
1680 {
1681  if ( layer->layerType() != QLatin1String( "ShapeburstFill" ) )
1682  return;
1683 
1684  // layer type is correct, we can do the cast
1685  mLayer = static_cast<QgsShapeburstFillSymbolLayer *>( layer );
1686 
1687  // set values
1688  btnChangeColor->blockSignals( true );
1689  btnChangeColor->setColor( mLayer->color() );
1690  btnChangeColor->blockSignals( false );
1691  btnChangeColor2->blockSignals( true );
1692  btnChangeColor2->setColor( mLayer->color2() );
1693  btnChangeColor2->blockSignals( false );
1694 
1696  {
1697  radioTwoColor->setChecked( true );
1698  btnColorRamp->setEnabled( false );
1699  }
1700  else
1701  {
1702  radioColorRamp->setChecked( true );
1703  btnChangeColor->setEnabled( false );
1704  btnChangeColor2->setEnabled( false );
1705  }
1706 
1707  mSpinBlurRadius->blockSignals( true );
1708  mBlurSlider->blockSignals( true );
1709  mSpinBlurRadius->setValue( mLayer->blurRadius() );
1710  mBlurSlider->setValue( mLayer->blurRadius() );
1711  mSpinBlurRadius->blockSignals( false );
1712  mBlurSlider->blockSignals( false );
1713 
1714  mSpinMaxDistance->blockSignals( true );
1715  mSpinMaxDistance->setValue( mLayer->maxDistance() );
1716  mSpinMaxDistance->blockSignals( false );
1717 
1718  mRadioUseWholeShape->blockSignals( true );
1719  mRadioUseMaxDistance->blockSignals( true );
1720  if ( mLayer->useWholeShape() )
1721  {
1722  mRadioUseWholeShape->setChecked( true );
1723  mSpinMaxDistance->setEnabled( false );
1724  mDistanceUnitWidget->setEnabled( false );
1725  }
1726  else
1727  {
1728  mRadioUseMaxDistance->setChecked( true );
1729  mSpinMaxDistance->setEnabled( true );
1730  mDistanceUnitWidget->setEnabled( true );
1731  }
1732  mRadioUseWholeShape->blockSignals( false );
1733  mRadioUseMaxDistance->blockSignals( false );
1734 
1735  mDistanceUnitWidget->blockSignals( true );
1736  mDistanceUnitWidget->setUnit( mLayer->distanceUnit() );
1737  mDistanceUnitWidget->setMapUnitScale( mLayer->distanceMapUnitScale() );
1738  mDistanceUnitWidget->blockSignals( false );
1739 
1740  mIgnoreRingsCheckBox->blockSignals( true );
1741  mIgnoreRingsCheckBox->setCheckState( mLayer->ignoreRings() ? Qt::Checked : Qt::Unchecked );
1742  mIgnoreRingsCheckBox->blockSignals( false );
1743 
1744  // set source color ramp
1745  if ( mLayer->colorRamp() )
1746  {
1747  btnColorRamp->blockSignals( true );
1748  btnColorRamp->setColorRamp( mLayer->colorRamp() );
1749  btnColorRamp->blockSignals( false );
1750  }
1751 
1752  spinOffsetX->blockSignals( true );
1753  spinOffsetX->setValue( mLayer->offset().x() );
1754  spinOffsetX->blockSignals( false );
1755  spinOffsetY->blockSignals( true );
1756  spinOffsetY->setValue( mLayer->offset().y() );
1757  spinOffsetY->blockSignals( false );
1758  mOffsetUnitWidget->blockSignals( true );
1759  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1760  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1761  mOffsetUnitWidget->blockSignals( false );
1762 
1770 }
1771 
1773 {
1774  return mLayer;
1775 }
1776 
1778 {
1779  if ( mLayer )
1780  {
1781  mLayer->setColor( color );
1782  emit changed();
1783  }
1784 }
1785 
1787 {
1788  if ( mLayer )
1789  {
1790  mLayer->setColor2( color );
1791  emit changed();
1792  }
1793 }
1794 
1795 void QgsShapeburstFillSymbolLayerWidget::colorModeChanged()
1796 {
1797  if ( !mLayer )
1798  {
1799  return;
1800  }
1801 
1802  if ( radioTwoColor->isChecked() )
1803  {
1805  }
1806  else
1807  {
1809  }
1810  emit changed();
1811 }
1812 
1813 void QgsShapeburstFillSymbolLayerWidget::mSpinBlurRadius_valueChanged( int value )
1814 {
1815  if ( mLayer )
1816  {
1817  mLayer->setBlurRadius( value );
1818  emit changed();
1819  }
1820 }
1821 
1822 void QgsShapeburstFillSymbolLayerWidget::mSpinMaxDistance_valueChanged( double value )
1823 {
1824  if ( mLayer )
1825  {
1826  mLayer->setMaxDistance( value );
1827  emit changed();
1828  }
1829 }
1830 
1831 void QgsShapeburstFillSymbolLayerWidget::mDistanceUnitWidget_changed()
1832 {
1833  if ( mLayer )
1834  {
1835  mLayer->setDistanceUnit( mDistanceUnitWidget->unit() );
1836  mLayer->setDistanceMapUnitScale( mDistanceUnitWidget->getMapUnitScale() );
1837  emit changed();
1838  }
1839 }
1840 
1841 void QgsShapeburstFillSymbolLayerWidget::mRadioUseWholeShape_toggled( bool value )
1842 {
1843  if ( mLayer )
1844  {
1845  mLayer->setUseWholeShape( value );
1846  mDistanceUnitWidget->setEnabled( !value );
1847  emit changed();
1848  }
1849 }
1850 
1851 void QgsShapeburstFillSymbolLayerWidget::applyColorRamp()
1852 {
1853  QgsColorRamp *ramp = btnColorRamp->colorRamp();
1854  if ( !ramp )
1855  return;
1856 
1857  mLayer->setColorRamp( ramp );
1858  emit changed();
1859 }
1860 
1861 void QgsShapeburstFillSymbolLayerWidget::offsetChanged()
1862 {
1863  if ( mLayer )
1864  {
1865  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1866  emit changed();
1867  }
1868 }
1869 
1870 void QgsShapeburstFillSymbolLayerWidget::mOffsetUnitWidget_changed()
1871 {
1872  if ( mLayer )
1873  {
1874  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1875  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1876  emit changed();
1877  }
1878 }
1879 
1880 
1881 void QgsShapeburstFillSymbolLayerWidget::mIgnoreRingsCheckBox_stateChanged( int state )
1882 {
1883  const bool checked = ( state == Qt::Checked );
1884  mLayer->setIgnoreRings( checked );
1885  emit changed();
1886 }
1887 
1889 
1891  : QgsSymbolLayerWidget( parent, vl )
1892 {
1893  mLayer = nullptr;
1894 
1895  setupUi( this );
1896  connect( mIntervalUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsMarkerLineSymbolLayerWidget::mIntervalUnitWidget_changed );
1897  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsMarkerLineSymbolLayerWidget::mOffsetUnitWidget_changed );
1898  connect( mOffsetAlongLineUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsMarkerLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed );
1899  connect( mAverageAngleUnit, &QgsUnitSelectionWidget::changed, this, &QgsMarkerLineSymbolLayerWidget::averageAngleUnitChanged );
1908 
1909  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconAllRings.svg" ) ), tr( "All Rings" ), QgsLineSymbolLayer::AllRings );
1910  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconExteriorRing.svg" ) ), tr( "Exterior Ring Only" ), QgsLineSymbolLayer::ExteriorRingOnly );
1911  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconInteriorRings.svg" ) ), tr( "Interior Rings Only" ), QgsLineSymbolLayer::InteriorRingsOnly );
1912  connect( mRingFilterComboBox, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]( int )
1913  {
1914  if ( mLayer )
1915  {
1916  mLayer->setRingFilter( static_cast< QgsLineSymbolLayer::RenderRingFilter >( mRingFilterComboBox->currentData().toInt() ) );
1917  emit changed();
1918  }
1919  } );
1920 
1921  spinOffset->setClearValue( 0.0 );
1922 
1923  mSpinAverageAngleLength->setClearValue( 4.0 );
1924 
1925  connect( spinInterval, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsMarkerLineSymbolLayerWidget::setInterval );
1926  connect( mSpinOffsetAlongLine, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsMarkerLineSymbolLayerWidget::setOffsetAlongLine );
1927  connect( chkRotateMarker, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setRotate );
1928  connect( spinOffset, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsMarkerLineSymbolLayerWidget::setOffset );
1929  connect( mSpinAverageAngleLength, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsMarkerLineSymbolLayerWidget::setAverageAngle );
1930  connect( mCheckInterval, &QCheckBox::toggled, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1931  connect( mCheckVertex, &QCheckBox::toggled, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1932  connect( mCheckVertexLast, &QCheckBox::toggled, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1933  connect( mCheckVertexFirst, &QCheckBox::toggled, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1934  connect( mCheckCentralPoint, &QCheckBox::toggled, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1935  connect( mCheckCurvePoint, &QCheckBox::toggled, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1936  connect( mCheckSegmentCentralPoint, &QCheckBox::toggled, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1937  connect( mCheckPlaceOnEveryPart, &QCheckBox::toggled, this, [ = ]
1938  {
1939  if ( mLayer )
1940  {
1941  mLayer->setPlaceOnEveryPart( mCheckPlaceOnEveryPart->isChecked() );
1942  emit changed();
1943  }
1944  } );
1945 }
1946 
1948 {
1949  if ( layer->layerType() != QLatin1String( "MarkerLine" ) )
1950  return;
1951 
1952  // layer type is correct, we can do the cast
1953  mLayer = static_cast<QgsMarkerLineSymbolLayer *>( layer );
1954 
1955  // set values
1956  spinInterval->blockSignals( true );
1957  spinInterval->setValue( mLayer->interval() );
1958  spinInterval->blockSignals( false );
1959  mSpinOffsetAlongLine->blockSignals( true );
1960  mSpinOffsetAlongLine->setValue( mLayer->offsetAlongLine() );
1961  mSpinOffsetAlongLine->blockSignals( false );
1962  chkRotateMarker->blockSignals( true );
1963  chkRotateMarker->setChecked( mLayer->rotateSymbols() );
1964  chkRotateMarker->blockSignals( false );
1965  spinOffset->blockSignals( true );
1966  spinOffset->setValue( mLayer->offset() );
1967  spinOffset->blockSignals( false );
1968 
1969  whileBlocking( mCheckInterval )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::Interval );
1972  whileBlocking( mCheckVertexFirst )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::FirstVertex
1974  whileBlocking( mCheckVertexLast )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::LastVertex
1976  whileBlocking( mCheckCentralPoint )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::CentralPoint );
1977  whileBlocking( mCheckCurvePoint )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::CurvePoint );
1978  whileBlocking( mCheckSegmentCentralPoint )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::SegmentCenter );
1979  whileBlocking( mCheckPlaceOnEveryPart )->setChecked( mLayer->placeOnEveryPart() );
1980 
1981  // set units
1982  mIntervalUnitWidget->blockSignals( true );
1983  mIntervalUnitWidget->setUnit( mLayer->intervalUnit() );
1984  mIntervalUnitWidget->setMapUnitScale( mLayer->intervalMapUnitScale() );
1985  mIntervalUnitWidget->blockSignals( false );
1986  mOffsetUnitWidget->blockSignals( true );
1987  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1988  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1989  mOffsetUnitWidget->blockSignals( false );
1990  mOffsetAlongLineUnitWidget->blockSignals( true );
1991  mOffsetAlongLineUnitWidget->setUnit( mLayer->offsetAlongLineUnit() );
1992  mOffsetAlongLineUnitWidget->setMapUnitScale( mLayer->offsetAlongLineMapUnitScale() );
1993  mOffsetAlongLineUnitWidget->blockSignals( false );
1994 
1995  whileBlocking( mAverageAngleUnit )->setUnit( mLayer->averageAngleUnit() );
1996  whileBlocking( mAverageAngleUnit )->setMapUnitScale( mLayer->averageAngleMapUnitScale() );
1997  whileBlocking( mSpinAverageAngleLength )->setValue( mLayer->averageAngleLength() );
1998 
1999  whileBlocking( mRingFilterComboBox )->setCurrentIndex( mRingFilterComboBox->findData( mLayer->ringFilter() ) );
2000 
2001  setPlacement(); // update gui
2002 
2008 }
2009 
2011 {
2012  return mLayer;
2013 }
2014 
2016 {
2018 
2019  switch ( context.symbolType() )
2020  {
2023  //these settings only have an effect when the symbol layers is part of a fill symbol
2024  mRingFilterComboBox->hide();
2025  mRingsLabel->hide();
2026  break;
2027 
2030  break;
2031  }
2032 }
2033 
2035 {
2036  mLayer->setInterval( val );
2037  emit changed();
2038 }
2039 
2041 {
2042  mLayer->setOffsetAlongLine( val );
2043  emit changed();
2044 }
2045 
2046 void QgsMarkerLineSymbolLayerWidget::setRotate()
2047 {
2048  mSpinAverageAngleLength->setEnabled( chkRotateMarker->isChecked() && ( mCheckInterval->isChecked() || mCheckCentralPoint->isChecked() ) );
2049  mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
2050 
2051  mLayer->setRotateSymbols( chkRotateMarker->isChecked() );
2052  emit changed();
2053 }
2054 
2055 void QgsMarkerLineSymbolLayerWidget::setOffset()
2056 {
2057  mLayer->setOffset( spinOffset->value() );
2058  emit changed();
2059 }
2060 
2061 void QgsMarkerLineSymbolLayerWidget::setPlacement()
2062 {
2063  const bool interval = mCheckInterval->isChecked();
2064  spinInterval->setEnabled( interval );
2065  mSpinOffsetAlongLine->setEnabled( mCheckInterval->isChecked() || mCheckVertexLast->isChecked() || mCheckVertexFirst->isChecked() );
2066  mOffsetAlongLineUnitWidget->setEnabled( mSpinOffsetAlongLine->isEnabled() );
2067  mSpinAverageAngleLength->setEnabled( chkRotateMarker->isChecked() && ( mCheckInterval->isChecked() || mCheckCentralPoint->isChecked() ) );
2068  mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
2069 
2070  Qgis::MarkerLinePlacements placements;
2071  if ( mCheckInterval->isChecked() )
2073  if ( mCheckVertex->isChecked() )
2075  if ( mCheckVertexLast->isChecked() )
2077  if ( mCheckVertexFirst->isChecked() )
2079  if ( mCheckCurvePoint->isChecked() )
2081  if ( mCheckSegmentCentralPoint->isChecked() )
2083  if ( mCheckCentralPoint->isChecked() )
2085  mLayer->setPlacements( placements );
2086 
2087  emit changed();
2088 }
2089 
2090 void QgsMarkerLineSymbolLayerWidget::mIntervalUnitWidget_changed()
2091 {
2092  if ( mLayer )
2093  {
2094  mLayer->setIntervalUnit( mIntervalUnitWidget->unit() );
2095  mLayer->setIntervalMapUnitScale( mIntervalUnitWidget->getMapUnitScale() );
2096  emit changed();
2097  }
2098 }
2099 
2100 void QgsMarkerLineSymbolLayerWidget::mOffsetUnitWidget_changed()
2101 {
2102  if ( mLayer )
2103  {
2104  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
2105  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
2106  emit changed();
2107  }
2108 }
2109 
2110 void QgsMarkerLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed()
2111 {
2112  if ( mLayer )
2113  {
2114  mLayer->setOffsetAlongLineUnit( mOffsetAlongLineUnitWidget->unit() );
2115  mLayer->setOffsetAlongLineMapUnitScale( mOffsetAlongLineUnitWidget->getMapUnitScale() );
2116  }
2117  emit changed();
2118 }
2119 
2120 void QgsMarkerLineSymbolLayerWidget::averageAngleUnitChanged()
2121 {
2122  if ( mLayer )
2123  {
2124  mLayer->setAverageAngleUnit( mAverageAngleUnit->unit() );
2125  mLayer->setAverageAngleMapUnitScale( mAverageAngleUnit->getMapUnitScale() );
2126  }
2127  emit changed();
2128 }
2129 
2130 void QgsMarkerLineSymbolLayerWidget::setAverageAngle( double val )
2131 {
2132  if ( mLayer )
2133  {
2134  mLayer->setAverageAngleLength( val );
2135  emit changed();
2136  }
2137 }
2138 
2139 
2141 
2143  : QgsSymbolLayerWidget( parent, vl )
2144 {
2145  mLayer = nullptr;
2146 
2147  setupUi( this );
2148  connect( mIntervalUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::mIntervalUnitWidget_changed );
2149  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::mOffsetUnitWidget_changed );
2150  connect( mOffsetAlongLineUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed );
2151  connect( mAverageAngleUnit, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::averageAngleUnitChanged );
2152  connect( mHashLengthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::hashLengthUnitWidgetChanged );
2163 
2164  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconAllRings.svg" ) ), tr( "All Rings" ), QgsLineSymbolLayer::AllRings );
2165  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconExteriorRing.svg" ) ), tr( "Exterior Ring Only" ), QgsLineSymbolLayer::ExteriorRingOnly );
2166  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconInteriorRings.svg" ) ), tr( "Interior Rings Only" ), QgsLineSymbolLayer::InteriorRingsOnly );
2167  connect( mRingFilterComboBox, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]( int )
2168  {
2169  if ( mLayer )
2170  {
2171  mLayer->setRingFilter( static_cast< QgsLineSymbolLayer::RenderRingFilter >( mRingFilterComboBox->currentData().toInt() ) );
2172  emit changed();
2173  }
2174  } );
2175 
2176  spinOffset->setClearValue( 0.0 );
2177 
2178  mHashRotationSpinBox->setClearValue( 0 );
2179  mSpinAverageAngleLength->setClearValue( 4.0 );
2180 
2181  connect( spinInterval, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setInterval );
2182  connect( mSpinOffsetAlongLine, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setOffsetAlongLine );
2183  connect( mSpinHashLength, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setHashLength );
2184  connect( mHashRotationSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setHashAngle );
2185  connect( chkRotateMarker, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setRotate );
2186  connect( spinOffset, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setOffset );
2187  connect( mSpinAverageAngleLength, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setAverageAngle );
2188 
2189  connect( mCheckInterval, &QCheckBox::toggled, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2190  connect( mCheckVertex, &QCheckBox::toggled, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2191  connect( mCheckVertexLast, &QCheckBox::toggled, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2192  connect( mCheckVertexFirst, &QCheckBox::toggled, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2193  connect( mCheckCentralPoint, &QCheckBox::toggled, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2194  connect( mCheckCurvePoint, &QCheckBox::toggled, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2195  connect( mCheckSegmentCentralPoint, &QCheckBox::toggled, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2196 
2197  connect( mCheckPlaceOnEveryPart, &QCheckBox::toggled, this, [ = ]
2198  {
2199  if ( mLayer )
2200  {
2201  mLayer->setPlaceOnEveryPart( mCheckPlaceOnEveryPart->isChecked() );
2202  emit changed();
2203  }
2204  } );
2205 }
2206 
2208 {
2209  if ( layer->layerType() != QLatin1String( "HashLine" ) )
2210  return;
2211 
2212  // layer type is correct, we can do the cast
2213  mLayer = static_cast<QgsHashedLineSymbolLayer *>( layer );
2214 
2215  // set values
2216  spinInterval->blockSignals( true );
2217  spinInterval->setValue( mLayer->interval() );
2218  spinInterval->blockSignals( false );
2219  mSpinOffsetAlongLine->blockSignals( true );
2220  mSpinOffsetAlongLine->setValue( mLayer->offsetAlongLine() );
2221  mSpinOffsetAlongLine->blockSignals( false );
2222  whileBlocking( mSpinHashLength )->setValue( mLayer->hashLength() );
2223  whileBlocking( mHashRotationSpinBox )->setValue( mLayer->hashAngle() );
2224  chkRotateMarker->blockSignals( true );
2225  chkRotateMarker->setChecked( mLayer->rotateSymbols() );
2226  chkRotateMarker->blockSignals( false );
2227  spinOffset->blockSignals( true );
2228  spinOffset->setValue( mLayer->offset() );
2229  spinOffset->blockSignals( false );
2230 
2231  whileBlocking( mCheckInterval )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::Interval );
2232  whileBlocking( mCheckVertex )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::InnerVertices
2234  whileBlocking( mCheckVertexFirst )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::FirstVertex
2236  whileBlocking( mCheckVertexLast )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::LastVertex
2238  whileBlocking( mCheckCentralPoint )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::CentralPoint );
2239  whileBlocking( mCheckCurvePoint )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::CurvePoint );
2240  whileBlocking( mCheckSegmentCentralPoint )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::SegmentCenter );
2241  whileBlocking( mCheckPlaceOnEveryPart )->setChecked( mLayer->placeOnEveryPart() );
2242 
2243  // set units
2244  mIntervalUnitWidget->blockSignals( true );
2245  mIntervalUnitWidget->setUnit( mLayer->intervalUnit() );
2246  mIntervalUnitWidget->setMapUnitScale( mLayer->intervalMapUnitScale() );
2247  mIntervalUnitWidget->blockSignals( false );
2248  mOffsetUnitWidget->blockSignals( true );
2249  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
2250  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
2251  mOffsetUnitWidget->blockSignals( false );
2252  mOffsetAlongLineUnitWidget->blockSignals( true );
2253  mOffsetAlongLineUnitWidget->setUnit( mLayer->offsetAlongLineUnit() );
2254  mOffsetAlongLineUnitWidget->setMapUnitScale( mLayer->offsetAlongLineMapUnitScale() );
2255  mOffsetAlongLineUnitWidget->blockSignals( false );
2256  whileBlocking( mAverageAngleUnit )->setUnit( mLayer->averageAngleUnit() );
2257  whileBlocking( mAverageAngleUnit )->setMapUnitScale( mLayer->averageAngleMapUnitScale() );
2258  whileBlocking( mSpinAverageAngleLength )->setValue( mLayer->averageAngleLength() );
2259  whileBlocking( mHashLengthUnitWidget )->setUnit( mLayer->hashLengthUnit() );
2260  whileBlocking( mHashLengthUnitWidget )->setMapUnitScale( mLayer->hashLengthMapUnitScale() );
2261 
2262  whileBlocking( mRingFilterComboBox )->setCurrentIndex( mRingFilterComboBox->findData( mLayer->ringFilter() ) );
2263 
2264  setPlacement(); // update gui
2265 
2273 }
2274 
2276 {
2277  return mLayer;
2278 }
2279 
2281 {
2283 
2284  switch ( context.symbolType() )
2285  {
2288  //these settings only have an effect when the symbol layers is part of a fill symbol
2289  mRingFilterComboBox->hide();
2290  mRingsLabel->hide();
2291  break;
2292 
2295  break;
2296  }
2297 }
2298 
2299 void QgsHashedLineSymbolLayerWidget::setInterval( double val )
2300 {
2301  mLayer->setInterval( val );
2302  emit changed();
2303 }
2304 
2305 void QgsHashedLineSymbolLayerWidget::setOffsetAlongLine( double val )
2306 {
2307  mLayer->setOffsetAlongLine( val );
2308  emit changed();
2309 }
2310 
2311 void QgsHashedLineSymbolLayerWidget::setHashLength( double val )
2312 {
2313  mLayer->setHashLength( val );
2314  emit changed();
2315 }
2316 
2317 void QgsHashedLineSymbolLayerWidget::setHashAngle( double val )
2318 {
2319  mLayer->setHashAngle( val );
2320  emit changed();
2321 }
2322 
2323 void QgsHashedLineSymbolLayerWidget::setRotate()
2324 {
2325  mSpinAverageAngleLength->setEnabled( chkRotateMarker->isChecked() && ( mCheckInterval->isChecked() || mCheckCentralPoint->isChecked() ) );
2326  mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
2327 
2328  mLayer->setRotateSymbols( chkRotateMarker->isChecked() );
2329  emit changed();
2330 }
2331 
2332 void QgsHashedLineSymbolLayerWidget::setOffset()
2333 {
2334  mLayer->setOffset( spinOffset->value() );
2335  emit changed();
2336 }
2337 
2338 void QgsHashedLineSymbolLayerWidget::setPlacement()
2339 {
2340  const bool interval = mCheckInterval->isChecked();
2341  spinInterval->setEnabled( interval );
2342  mSpinOffsetAlongLine->setEnabled( mCheckInterval->isChecked() || mCheckVertexLast->isChecked() || mCheckVertexFirst->isChecked() );
2343  mOffsetAlongLineUnitWidget->setEnabled( mSpinOffsetAlongLine->isEnabled() );
2344  mSpinAverageAngleLength->setEnabled( chkRotateMarker->isChecked() && ( mCheckInterval->isChecked() || mCheckCentralPoint->isChecked() ) );
2345  mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
2346 
2347  Qgis::MarkerLinePlacements placements;
2348  if ( mCheckInterval->isChecked() )
2350  if ( mCheckVertex->isChecked() )
2352  if ( mCheckVertexLast->isChecked() )
2354  if ( mCheckVertexFirst->isChecked() )
2356  if ( mCheckCurvePoint->isChecked() )
2358  if ( mCheckSegmentCentralPoint->isChecked() )
2360  if ( mCheckCentralPoint->isChecked() )
2362  mLayer->setPlacements( placements );
2363 
2364  emit changed();
2365 }
2366 
2367 void QgsHashedLineSymbolLayerWidget::mIntervalUnitWidget_changed()
2368 {
2369  if ( mLayer )
2370  {
2371  mLayer->setIntervalUnit( mIntervalUnitWidget->unit() );
2372  mLayer->setIntervalMapUnitScale( mIntervalUnitWidget->getMapUnitScale() );
2373  emit changed();
2374  }
2375 }
2376 
2377 void QgsHashedLineSymbolLayerWidget::mOffsetUnitWidget_changed()
2378 {
2379  if ( mLayer )
2380  {
2381  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
2382  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
2383  emit changed();
2384  }
2385 }
2386 
2387 void QgsHashedLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed()
2388 {
2389  if ( mLayer )
2390  {
2391  mLayer->setOffsetAlongLineUnit( mOffsetAlongLineUnitWidget->unit() );
2392  mLayer->setOffsetAlongLineMapUnitScale( mOffsetAlongLineUnitWidget->getMapUnitScale() );
2393  }
2394  emit changed();
2395 }
2396 
2397 void QgsHashedLineSymbolLayerWidget::hashLengthUnitWidgetChanged()
2398 {
2399  if ( mLayer )
2400  {
2401  mLayer->setHashLengthUnit( mHashLengthUnitWidget->unit() );
2402  mLayer->setHashLengthMapUnitScale( mHashLengthUnitWidget->getMapUnitScale() );
2403  }
2404  emit changed();
2405 }
2406 
2407 void QgsHashedLineSymbolLayerWidget::averageAngleUnitChanged()
2408 {
2409  if ( mLayer )
2410  {
2411  mLayer->setAverageAngleUnit( mAverageAngleUnit->unit() );
2412  mLayer->setAverageAngleMapUnitScale( mAverageAngleUnit->getMapUnitScale() );
2413  }
2414  emit changed();
2415 }
2416 
2417 void QgsHashedLineSymbolLayerWidget::setAverageAngle( double val )
2418 {
2419  if ( mLayer )
2420  {
2421  mLayer->setAverageAngleLength( val );
2422  emit changed();
2423  }
2424 }
2425 
2427 
2428 
2430  : QgsSymbolLayerWidget( parent, vl )
2431 {
2432  mLayer = nullptr;
2433 
2434  setupUi( this );
2435 
2436  mSvgSelectorWidget->setAllowParameters( true );
2437  mSvgSelectorWidget->sourceLineEdit()->setPropertyOverrideToolButtonVisible( true );
2438  mSvgSelectorWidget->sourceLineEdit()->setLastPathSettingsKey( QStringLiteral( "/UI/lastSVGMarkerDir" ) );
2439  mSvgSelectorWidget->initParametersModel( this, vl );
2440 
2441  connect( mSvgSelectorWidget->sourceLineEdit(), &QgsSvgSourceLineEdit::sourceChanged, this, &QgsSvgMarkerSymbolLayerWidget::svgSourceChanged );
2442  connect( mChangeColorButton, &QgsColorButton::colorChanged, this, &QgsSvgMarkerSymbolLayerWidget::mChangeColorButton_colorChanged );
2443  connect( mChangeStrokeColorButton, &QgsColorButton::colorChanged, this, &QgsSvgMarkerSymbolLayerWidget::mChangeStrokeColorButton_colorChanged );
2444  connect( mStrokeWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
2445  connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
2446  connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
2447  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
2448  connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSvgMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
2449  connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSvgMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
2456  mChangeColorButton->setAllowOpacity( true );
2457  mChangeColorButton->setColorDialogTitle( tr( "Select Fill color" ) );
2458  mChangeColorButton->setContext( QStringLiteral( "symbology" ) );
2459  mChangeStrokeColorButton->setAllowOpacity( true );
2460  mChangeStrokeColorButton->setColorDialogTitle( tr( "Select Stroke Color" ) );
2461  mChangeStrokeColorButton->setContext( QStringLiteral( "symbology" ) );
2462 
2463  mFillColorDDBtn->registerLinkedWidget( mChangeColorButton );
2464  mStrokeColorDDBtn->registerLinkedWidget( mChangeStrokeColorButton );
2465 
2466  spinOffsetX->setClearValue( 0.0 );
2467  spinOffsetY->setClearValue( 0.0 );
2468  spinAngle->setClearValue( 0.0 );
2469 
2470  connect( spinWidth, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setWidth );
2471  connect( spinHeight, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setHeight );
2472  connect( mLockAspectRatio, static_cast < void ( QgsRatioLockButton::* )( bool ) > ( &QgsRatioLockButton::lockChanged ), this, &QgsSvgMarkerSymbolLayerWidget::lockAspectRatioChanged );
2473  connect( spinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setAngle );
2474  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setOffset );
2475  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setOffset );
2476  connect( this, &QgsSymbolLayerWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::updateAssistantSymbol );
2477 
2478  connect( mSvgSelectorWidget, &QgsSvgSelectorWidget::svgSelected, this, &QgsSvgMarkerSymbolLayerWidget::setSvgPath );
2480 
2481  //make a temporary symbol for the size assistant preview
2482  mAssistantPreviewSymbol.reset( new QgsMarkerSymbol() );
2483 
2484  if ( vectorLayer() )
2485  {
2486  mWidthDDBtn->setSymbol( mAssistantPreviewSymbol );
2487  mHeightDDBtn->setSymbol( mAssistantPreviewSymbol );
2488  }
2489 }
2490 
2492 
2493 #include <QTime>
2494 #include <QAbstractListModel>
2495 #include <QPixmapCache>
2496 #include <QStyle>
2497 
2498 
2499 
2500 
2501 void QgsSvgMarkerSymbolLayerWidget::setGuiForSvg( const QgsSvgMarkerSymbolLayer *layer, bool skipDefaultColors )
2502 {
2503  if ( !layer )
2504  {
2505  return;
2506  }
2507 
2508  //activate gui for svg parameters only if supported by the svg file
2509  bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2510  QColor defaultFill, defaultStroke;
2511  double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2512  bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
2513  QgsApplication::svgCache()->containsParams( layer->path(), hasFillParam, hasDefaultFillColor, defaultFill,
2514  hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity,
2515  hasStrokeParam, hasDefaultStrokeColor, defaultStroke,
2516  hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth,
2517  hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
2518  mChangeColorButton->setEnabled( hasFillParam );
2519  mChangeColorButton->setAllowOpacity( hasFillOpacityParam );
2520  mChangeStrokeColorButton->setEnabled( hasStrokeParam );
2521  mChangeStrokeColorButton->setAllowOpacity( hasStrokeOpacityParam );
2522  mStrokeWidthSpinBox->setEnabled( hasStrokeWidthParam );
2523 
2524  if ( hasFillParam )
2525  {
2526  QColor fill = layer->fillColor();
2527  const double existingOpacity = hasFillOpacityParam ? fill.alphaF() : 1.0;
2528  if ( hasDefaultFillColor && !skipDefaultColors )
2529  {
2530  fill = defaultFill;
2531  }
2532  fill.setAlphaF( hasDefaultFillOpacity ? defaultFillOpacity : existingOpacity );
2533  mChangeColorButton->setColor( fill );
2534  }
2535  if ( hasStrokeParam )
2536  {
2537  QColor stroke = layer->strokeColor();
2538  const double existingOpacity = hasStrokeOpacityParam ? stroke.alphaF() : 1.0;
2539  if ( hasDefaultStrokeColor && !skipDefaultColors )
2540  {
2541  stroke = defaultStroke;
2542  }
2543  stroke.setAlphaF( hasDefaultStrokeOpacity ? defaultStrokeOpacity : existingOpacity );
2544  mChangeStrokeColorButton->setColor( stroke );
2545  }
2546 
2547  whileBlocking( mSvgSelectorWidget->sourceLineEdit() )->setSource( layer->path() );
2548 
2549  mStrokeWidthSpinBox->blockSignals( true );
2550  mStrokeWidthSpinBox->setValue( hasDefaultStrokeWidth ? defaultStrokeWidth : layer->strokeWidth() );
2551  mStrokeWidthSpinBox->blockSignals( false );
2552 
2553  const bool preservedAspectRatio = layer->preservedAspectRatio();
2554  spinHeight->blockSignals( true );
2555  if ( preservedAspectRatio )
2556  {
2557  spinHeight->setValue( layer->size() * layer->defaultAspectRatio() );
2558  }
2559  else
2560  {
2561  spinHeight->setValue( layer->size() * layer->fixedAspectRatio() );
2562  }
2563  spinHeight->setEnabled( layer->defaultAspectRatio() > 0.0 );
2564  spinHeight->blockSignals( false );
2565  whileBlocking( mLockAspectRatio )->setLocked( preservedAspectRatio );
2566 }
2567 
2568 void QgsSvgMarkerSymbolLayerWidget::updateAssistantSymbol()
2569 {
2570  for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
2571  {
2572  mAssistantPreviewSymbol->deleteSymbolLayer( i );
2573  }
2574  mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
2576  if ( ddSize )
2577  mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
2578 }
2579 
2580 
2582 {
2583  if ( !layer )
2584  {
2585  return;
2586  }
2587 
2588  if ( layer->layerType() != QLatin1String( "SvgMarker" ) )
2589  return;
2590 
2591  // layer type is correct, we can do the cast
2592  mLayer = static_cast<QgsSvgMarkerSymbolLayer *>( layer );
2593 
2594  // set values
2595  mSvgSelectorWidget->setSvgPath( mLayer->path() );
2596  mSvgSelectorWidget->setSvgParameters( mLayer->parameters() );
2597 
2598  spinWidth->blockSignals( true );
2599  spinWidth->setValue( mLayer->size() );
2600  spinWidth->blockSignals( false );
2601  spinAngle->blockSignals( true );
2602  spinAngle->setValue( mLayer->angle() );
2603  spinAngle->blockSignals( false );
2604 
2605  // without blocking signals the value gets changed because of slot setOffset()
2606  spinOffsetX->blockSignals( true );
2607  spinOffsetX->setValue( mLayer->offset().x() );
2608  spinOffsetX->blockSignals( false );
2609  spinOffsetY->blockSignals( true );
2610  spinOffsetY->setValue( mLayer->offset().y() );
2611  spinOffsetY->blockSignals( false );
2612 
2613  mSizeUnitWidget->blockSignals( true );
2614  mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
2615  mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
2616  mSizeUnitWidget->blockSignals( false );
2617  mStrokeWidthUnitWidget->blockSignals( true );
2618  mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
2619  mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
2620  mStrokeWidthUnitWidget->blockSignals( false );
2621  mOffsetUnitWidget->blockSignals( true );
2622  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
2623  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
2624  mOffsetUnitWidget->blockSignals( false );
2625 
2626  //anchor points
2627  mHorizontalAnchorComboBox->blockSignals( true );
2628  mVerticalAnchorComboBox->blockSignals( true );
2629  mHorizontalAnchorComboBox->setCurrentIndex( mLayer->horizontalAnchorPoint() );
2630  mVerticalAnchorComboBox->setCurrentIndex( mLayer->verticalAnchorPoint() );
2631  mHorizontalAnchorComboBox->blockSignals( false );
2632  mVerticalAnchorComboBox->blockSignals( false );
2633 
2634  setGuiForSvg( mLayer, true );
2635 
2645 
2646  registerDataDefinedButton( mSvgSelectorWidget->sourceLineEdit()->propertyOverrideToolButton(), QgsSymbolLayer::PropertyName );
2647 
2648  updateAssistantSymbol();
2649 }
2650 
2652 {
2653  return mLayer;
2654 }
2655 
2657 {
2659  mSvgSelectorWidget->sourceLineEdit()->setMessageBar( context.messageBar() );
2660 }
2661 
2663 {
2664  mLayer->setPath( name );
2665  whileBlocking( mSvgSelectorWidget->sourceLineEdit() )->setSource( name );
2666 
2667  setGuiForSvg( mLayer );
2668  emit changed();
2669 }
2670 
2671 void QgsSvgMarkerSymbolLayerWidget::setSvgParameters( const QMap<QString, QgsProperty> &parameters )
2672 {
2673  mLayer->setParameters( parameters );
2674  whileBlocking( mSvgSelectorWidget )->setSvgParameters( parameters );
2675 
2676  setGuiForSvg( mLayer );
2677  emit changed();
2678 }
2679 
2680 void QgsSvgMarkerSymbolLayerWidget::setWidth()
2681 {
2682  const double defaultAspectRatio = mLayer->defaultAspectRatio();
2683  double fixedAspectRatio = 0.0;
2684  spinHeight->blockSignals( true );
2685  if ( defaultAspectRatio <= 0.0 )
2686  {
2687  spinHeight->setValue( spinWidth->value() );
2688  }
2689  else if ( mLockAspectRatio->locked() )
2690  {
2691  spinHeight->setValue( spinWidth->value() * defaultAspectRatio );
2692  }
2693  else
2694  {
2695  fixedAspectRatio = spinHeight->value() / spinWidth->value();
2696  }
2697  spinHeight->blockSignals( false );
2698  mLayer->setSize( spinWidth->value() );
2699  mLayer->setFixedAspectRatio( fixedAspectRatio );
2700  emit changed();
2701 }
2702 
2703 void QgsSvgMarkerSymbolLayerWidget::setHeight()
2704 {
2705  const double defaultAspectRatio = mLayer->defaultAspectRatio();
2706  double fixedAspectRatio = 0.0;
2707  spinWidth->blockSignals( true );
2708  if ( defaultAspectRatio <= 0.0 )
2709  {
2710  spinWidth->setValue( spinHeight->value() );
2711  }
2712  else if ( mLockAspectRatio->locked() )
2713  {
2714  spinWidth->setValue( spinHeight->value() / defaultAspectRatio );
2715  }
2716  else
2717  {
2718  fixedAspectRatio = spinHeight->value() / spinWidth->value();
2719  }
2720  spinWidth->blockSignals( false );
2721  mLayer->setSize( spinWidth->value() );
2722  mLayer->setFixedAspectRatio( fixedAspectRatio );
2723  emit changed();
2724 }
2725 
2726 void QgsSvgMarkerSymbolLayerWidget::lockAspectRatioChanged( const bool locked )
2727 {
2728  //spinHeight->setEnabled( !locked );
2729  const double defaultAspectRatio = mLayer->defaultAspectRatio();
2730  if ( defaultAspectRatio <= 0.0 )
2731  {
2732  whileBlocking( mLockAspectRatio )->setLocked( true );
2733  }
2734  else if ( locked )
2735  {
2736  mLayer->setFixedAspectRatio( 0.0 );
2737  setWidth();
2738  }
2739  else
2740  {
2741  mLayer->setFixedAspectRatio( spinHeight->value() / spinWidth->value() );
2742  }
2743  //emit changed();
2744 }
2745 
2746 void QgsSvgMarkerSymbolLayerWidget::setAngle()
2747 {
2748  mLayer->setAngle( spinAngle->value() );
2749  emit changed();
2750 }
2751 
2752 void QgsSvgMarkerSymbolLayerWidget::setOffset()
2753 {
2754  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
2755  emit changed();
2756 }
2757 
2758 void QgsSvgMarkerSymbolLayerWidget::svgSourceChanged( const QString &text )
2759 {
2760  mLayer->setPath( text );
2761  setGuiForSvg( mLayer );
2762  emit changed();
2763 }
2764 
2765 void QgsSvgMarkerSymbolLayerWidget::mChangeColorButton_colorChanged( const QColor &color )
2766 {
2767  if ( !mLayer )
2768  {
2769  return;
2770  }
2771 
2772  mLayer->setFillColor( color );
2773  emit changed();
2774 }
2775 
2776 void QgsSvgMarkerSymbolLayerWidget::mChangeStrokeColorButton_colorChanged( const QColor &color )
2777 {
2778  if ( !mLayer )
2779  {
2780  return;
2781  }
2782 
2783  mLayer->setStrokeColor( color );
2784  emit changed();
2785 }
2786 
2787 void QgsSvgMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
2788 {
2789  if ( mLayer )
2790  {
2791  mLayer->setStrokeWidth( d );
2792  emit changed();
2793  }
2794 }
2795 
2796 void QgsSvgMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
2797 {
2798  if ( mLayer )
2799  {
2800  mLayer->setSizeUnit( mSizeUnitWidget->unit() );
2801  mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
2802  emit changed();
2803  }
2804 }
2805 
2806 void QgsSvgMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
2807 {
2808  if ( mLayer )
2809  {
2810  mLayer->setStrokeWidthUnit( mStrokeWidthUnitWidget->unit() );
2811  mLayer->setStrokeWidthMapUnitScale( mStrokeWidthUnitWidget->getMapUnitScale() );
2812  emit changed();
2813  }
2814 }
2815 
2816 void QgsSvgMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
2817 {
2818  if ( mLayer )
2819  {
2820  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
2821  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
2822  emit changed();
2823  }
2824 }
2825 
2826 void QgsSvgMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
2827 {
2828  if ( mLayer )
2829  {
2831  emit changed();
2832  }
2833 }
2834 
2835 void QgsSvgMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
2836 {
2837  if ( mLayer )
2838  {
2840  emit changed();
2841  }
2842 }
2843 
2845 
2847 {
2848  mLayer = nullptr;
2849  setupUi( this );
2850 
2851  mSvgSelectorWidget->setAllowParameters( true );
2852  mSvgSelectorWidget->sourceLineEdit()->setPropertyOverrideToolButtonVisible( true );
2853 
2854  connect( mTextureWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mTextureWidthSpinBox_valueChanged );
2855  connect( mSvgSelectorWidget->sourceLineEdit(), &QgsSvgSourceLineEdit::sourceChanged, this, &QgsSVGFillSymbolLayerWidget::svgSourceChanged );
2856  connect( mRotationSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mRotationSpinBox_valueChanged );
2857  connect( mChangeColorButton, &QgsColorButton::colorChanged, this, &QgsSVGFillSymbolLayerWidget::mChangeColorButton_colorChanged );
2858  connect( mChangeStrokeColorButton, &QgsColorButton::colorChanged, this, &QgsSVGFillSymbolLayerWidget::mChangeStrokeColorButton_colorChanged );
2859  connect( mStrokeWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
2860  connect( mTextureWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSVGFillSymbolLayerWidget::mTextureWidthUnitWidget_changed );
2861  connect( mSvgStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSVGFillSymbolLayerWidget::mSvgStrokeWidthUnitWidget_changed );
2866 
2867  mRotationSpinBox->setClearValue( 0.0 );
2868 
2869  mChangeColorButton->setColorDialogTitle( tr( "Select Fill Color" ) );
2870  mChangeColorButton->setContext( QStringLiteral( "symbology" ) );
2871  mChangeStrokeColorButton->setColorDialogTitle( tr( "Select Stroke Color" ) );
2872  mChangeStrokeColorButton->setContext( QStringLiteral( "symbology" ) );
2873 
2874  mFilColorDDBtn->registerLinkedWidget( mChangeColorButton );
2875  mStrokeColorDDBtn->registerLinkedWidget( mChangeStrokeColorButton );
2876 
2877  connect( mSvgSelectorWidget, &QgsSvgSelectorWidget::svgSelected, this, &QgsSVGFillSymbolLayerWidget::setFile );
2878  connect( mSvgSelectorWidget, &QgsSvgSelectorWidget::svgParametersChanged, this, &QgsSVGFillSymbolLayerWidget::setSvgParameters );
2879 }
2880 
2882 {
2883  if ( !layer )
2884  {
2885  return;
2886  }
2887 
2888  if ( layer->layerType() != QLatin1String( "SVGFill" ) )
2889  {
2890  return;
2891  }
2892 
2893  mLayer = dynamic_cast<QgsSVGFillSymbolLayer *>( layer );
2894  if ( mLayer )
2895  {
2896  const double width = mLayer->patternWidth();
2897  mTextureWidthSpinBox->blockSignals( true );
2898  mTextureWidthSpinBox->setValue( width );
2899  mTextureWidthSpinBox->blockSignals( false );
2900  whileBlocking( mSvgSelectorWidget->sourceLineEdit() )->setSource( mLayer->svgFilePath() );
2901  mRotationSpinBox->blockSignals( true );
2902  mRotationSpinBox->setValue( mLayer->angle() );
2903  mRotationSpinBox->blockSignals( false );
2904  mTextureWidthUnitWidget->blockSignals( true );
2905  mTextureWidthUnitWidget->setUnit( mLayer->patternWidthUnit() );
2906  mTextureWidthUnitWidget->setMapUnitScale( mLayer->patternWidthMapUnitScale() );
2907  mTextureWidthUnitWidget->blockSignals( false );
2908  mSvgStrokeWidthUnitWidget->blockSignals( true );
2909  mSvgStrokeWidthUnitWidget->setUnit( mLayer->svgStrokeWidthUnit() );
2910  mSvgStrokeWidthUnitWidget->setMapUnitScale( mLayer->svgStrokeWidthMapUnitScale() );
2911  mSvgStrokeWidthUnitWidget->blockSignals( false );
2912  mChangeColorButton->blockSignals( true );
2913  mChangeColorButton->setColor( mLayer->svgFillColor() );
2914  mChangeColorButton->blockSignals( false );
2915  mChangeStrokeColorButton->blockSignals( true );
2916  mChangeStrokeColorButton->setColor( mLayer->svgStrokeColor() );
2917  mChangeStrokeColorButton->blockSignals( false );
2918  mStrokeWidthSpinBox->blockSignals( true );
2919  mStrokeWidthSpinBox->setValue( mLayer->svgStrokeWidth() );
2920  mStrokeWidthSpinBox->blockSignals( false );
2921  }
2922  updateParamGui( false );
2923 
2929 
2930  registerDataDefinedButton( mSvgSelectorWidget->sourceLineEdit()->propertyOverrideToolButton(), QgsSymbolLayer::PropertyFile );
2931 }
2932 
2934 {
2935  return mLayer;
2936 }
2937 
2939 {
2941  mSvgSelectorWidget->sourceLineEdit()->setMessageBar( context.messageBar() );
2942 }
2943 
2944 void QgsSVGFillSymbolLayerWidget::mTextureWidthSpinBox_valueChanged( double d )
2945 {
2946  if ( mLayer )
2947  {
2948  mLayer->setPatternWidth( d );
2949  emit changed();
2950  }
2951 }
2952 
2953 void QgsSVGFillSymbolLayerWidget::svgSourceChanged( const QString &text )
2954 {
2955  if ( !mLayer )
2956  {
2957  return;
2958  }
2959 
2960  mLayer->setSvgFilePath( text );
2961  updateParamGui();
2962  emit changed();
2963 }
2964 
2965 void QgsSVGFillSymbolLayerWidget::setFile( const QString &name )
2966 {
2967  mLayer->setSvgFilePath( name );
2968  whileBlocking( mSvgSelectorWidget->sourceLineEdit() )->setSource( name );
2969 
2970  updateParamGui();
2971  emit changed();
2972 }
2973 
2974 void QgsSVGFillSymbolLayerWidget::setSvgParameters( const QMap<QString, QgsProperty> &parameters )
2975 {
2976  mLayer->setParameters( parameters );
2977  whileBlocking( mSvgSelectorWidget )->setSvgParameters( parameters );
2978 
2979  updateParamGui();
2980  emit changed();
2981 }
2982 
2983 
2984 void QgsSVGFillSymbolLayerWidget::mRotationSpinBox_valueChanged( double d )
2985 {
2986  if ( mLayer )
2987  {
2988  mLayer->setAngle( d );
2989  emit changed();
2990  }
2991 }
2992 
2994 {
2995  //activate gui for svg parameters only if supported by the svg file
2996  bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2997  QColor defaultFill, defaultStroke;
2998  double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2999  bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
3000  QgsApplication::svgCache()->containsParams( mSvgSelectorWidget->sourceLineEdit()->source(), hasFillParam, hasDefaultFillColor, defaultFill,
3001  hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity,
3002  hasStrokeParam, hasDefaultStrokeColor, defaultStroke,
3003  hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth,
3004  hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
3005  if ( resetValues )
3006  {
3007  QColor fill = mChangeColorButton->color();
3008  const double newOpacity = hasFillOpacityParam ? fill.alphaF() : 1.0;
3009  if ( hasDefaultFillColor )
3010  {
3011  fill = defaultFill;
3012  }
3013  fill.setAlphaF( hasDefaultFillOpacity ? defaultFillOpacity : newOpacity );
3014  mChangeColorButton->setColor( fill );
3015  }
3016  mChangeColorButton->setEnabled( hasFillParam );
3017  mChangeColorButton->setAllowOpacity( hasFillOpacityParam );
3018  if ( resetValues )
3019  {
3020  QColor stroke = mChangeStrokeColorButton->color();
3021  const double newOpacity = hasStrokeOpacityParam ? stroke.alphaF() : 1.0;
3022  if ( hasDefaultStrokeColor )
3023  {
3024  stroke = defaultStroke;
3025  }
3026  stroke.setAlphaF( hasDefaultStrokeOpacity ? defaultStrokeOpacity : newOpacity );
3027  mChangeStrokeColorButton->setColor( stroke );
3028  }
3029  mChangeStrokeColorButton->setEnabled( hasStrokeParam );
3030  mChangeStrokeColorButton->setAllowOpacity( hasStrokeOpacityParam );
3031  if ( hasDefaultStrokeWidth && resetValues )
3032  {
3033  mStrokeWidthSpinBox->setValue( defaultStrokeWidth );
3034  }
3035  mStrokeWidthSpinBox->setEnabled( hasStrokeWidthParam );
3036 }
3037 
3038 void QgsSVGFillSymbolLayerWidget::mChangeColorButton_colorChanged( const QColor &color )
3039 {
3040  if ( !mLayer )
3041  {
3042  return;
3043  }
3044 
3045  mLayer->setSvgFillColor( color );
3046  emit changed();
3047 }
3048 
3049 void QgsSVGFillSymbolLayerWidget::mChangeStrokeColorButton_colorChanged( const QColor &color )
3050 {
3051  if ( !mLayer )
3052  {
3053  return;
3054  }
3055 
3056  mLayer->setSvgStrokeColor( color );
3057  emit changed();
3058 }
3059 
3060 void QgsSVGFillSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
3061 {
3062  if ( mLayer )
3063  {
3064  mLayer->setSvgStrokeWidth( d );
3065  emit changed();
3066  }
3067 }
3068 
3069 void QgsSVGFillSymbolLayerWidget::mTextureWidthUnitWidget_changed()
3070 {
3071  if ( mLayer )
3072  {
3073  mLayer->setPatternWidthUnit( mTextureWidthUnitWidget->unit() );
3074  mLayer->setPatternWidthMapUnitScale( mTextureWidthUnitWidget->getMapUnitScale() );
3075  emit changed();
3076  }
3077 }
3078 
3079 void QgsSVGFillSymbolLayerWidget::mSvgStrokeWidthUnitWidget_changed()
3080 {
3081  if ( mLayer )
3082  {
3083  mLayer->setSvgStrokeWidthUnit( mSvgStrokeWidthUnitWidget->unit() );
3084  mLayer->setSvgStrokeWidthMapUnitScale( mSvgStrokeWidthUnitWidget->getMapUnitScale() );
3085  emit changed();
3086  }
3087 }
3088 
3090 
3092  QgsSymbolLayerWidget( parent, vl )
3093 {
3094  setupUi( this );
3095  connect( mAngleSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLinePatternFillSymbolLayerWidget::mAngleSpinBox_valueChanged );
3096  connect( mDistanceSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLinePatternFillSymbolLayerWidget::mDistanceSpinBox_valueChanged );
3097  connect( mOffsetSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLinePatternFillSymbolLayerWidget::mOffsetSpinBox_valueChanged );
3098  connect( mDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsLinePatternFillSymbolLayerWidget::mDistanceUnitWidget_changed );
3099  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsLinePatternFillSymbolLayerWidget::mOffsetUnitWidget_changed );
3104  mOffsetSpinBox->setClearValue( 0 );
3105  mAngleSpinBox->setClearValue( 0 );
3106 
3107  mCoordinateReferenceComboBox->addItem( tr( "Align Pattern to Feature" ), static_cast< int >( Qgis::SymbolCoordinateReference::Feature ) );
3108  mCoordinateReferenceComboBox->addItem( tr( "Align Pattern to Map Extent" ), static_cast< int >( Qgis::SymbolCoordinateReference::Viewport ) );
3109  connect( mCoordinateReferenceComboBox, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]
3110  {
3111  if ( mLayer )
3112  {
3113  mLayer->setCoordinateReference( static_cast< Qgis::SymbolCoordinateReference >( mCoordinateReferenceComboBox->currentData().toInt() ) );
3114  emit changed();
3115  }
3116  } );
3117 
3118  mClipModeComboBox->addItem( tr( "Clip During Render Only" ), static_cast< int >( Qgis::LineClipMode::ClipPainterOnly ) );
3119  mClipModeComboBox->addItem( tr( "Clip Lines Before Render" ), static_cast< int >( Qgis::LineClipMode::ClipToIntersection ) );
3120  mClipModeComboBox->addItem( tr( "No Clipping" ), static_cast< int >( Qgis::LineClipMode::NoClipping ) );
3121  connect( mClipModeComboBox, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]
3122  {
3123  if ( mLayer )
3124  {
3125  mLayer->setClipMode( static_cast< Qgis::LineClipMode >( mClipModeComboBox->currentData().toInt() ) );
3126  emit changed();
3127  }
3128  } );
3129 
3130 }
3131 
3133 {
3134  if ( layer->layerType() != QLatin1String( "LinePatternFill" ) )
3135  {
3136  return;
3137  }
3138 
3139  QgsLinePatternFillSymbolLayer *patternLayer = static_cast<QgsLinePatternFillSymbolLayer *>( layer );
3140  if ( patternLayer )
3141  {
3142  mLayer = patternLayer;
3143  whileBlocking( mAngleSpinBox )->setValue( mLayer->lineAngle() );
3144  whileBlocking( mDistanceSpinBox )->setValue( mLayer->distance() );
3145  whileBlocking( mOffsetSpinBox )->setValue( mLayer->offset() );
3146 
3147  //units
3148  mDistanceUnitWidget->blockSignals( true );
3149  mDistanceUnitWidget->setUnit( mLayer->distanceUnit() );
3150  mDistanceUnitWidget->setMapUnitScale( mLayer->distanceMapUnitScale() );
3151  mDistanceUnitWidget->blockSignals( false );
3152  mOffsetUnitWidget->blockSignals( true );
3153  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
3154  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
3155  mOffsetUnitWidget->blockSignals( false );
3156 
3157  whileBlocking( mCoordinateReferenceComboBox )->setCurrentIndex( mCoordinateReferenceComboBox->findData( static_cast< int >( mLayer->coordinateReference() ) ) );
3158 
3159  whileBlocking( mClipModeComboBox )->setCurrentIndex( mClipModeComboBox->findData( static_cast< int >( mLayer->clipMode() ) ) );
3160  }
3161 
3166 }
3167 
3169 {
3170  return mLayer;
3171 }
3172 
3173 void QgsLinePatternFillSymbolLayerWidget::mAngleSpinBox_valueChanged( double d )
3174 {
3175  if ( mLayer )
3176  {
3177  mLayer->setLineAngle( d );
3178  emit changed();
3179  }
3180 }
3181 
3182 void QgsLinePatternFillSymbolLayerWidget::mDistanceSpinBox_valueChanged( double d )
3183 {
3184  if ( mLayer )
3185  {
3186  mLayer->setDistance( d );
3187  emit changed();
3188  }
3189 }
3190 
3191 void QgsLinePatternFillSymbolLayerWidget::mOffsetSpinBox_valueChanged( double d )
3192 {
3193  if ( mLayer )
3194  {
3195  mLayer->setOffset( d );
3196  emit changed();
3197  }
3198 }
3199 
3200 void QgsLinePatternFillSymbolLayerWidget::mDistanceUnitWidget_changed()
3201 {
3202  if ( mLayer )
3203  {
3204  mLayer->setDistanceUnit( mDistanceUnitWidget->unit() );
3205  mLayer->setDistanceMapUnitScale( mDistanceUnitWidget->getMapUnitScale() );
3206  emit changed();
3207  }
3208 }
3209 
3210 void QgsLinePatternFillSymbolLayerWidget::mOffsetUnitWidget_changed()
3211 {
3212  if ( mLayer )
3213  {
3214  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
3215  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
3216  emit changed();
3217  }
3218 }
3219 
3221 
3223  QgsSymbolLayerWidget( parent, vl )
3224 {
3225  setupUi( this );
3226  connect( mHorizontalDistanceSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceSpinBox_valueChanged );
3227  connect( mVerticalDistanceSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceSpinBox_valueChanged );
3228  connect( mHorizontalDisplacementSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementSpinBox_valueChanged );
3229  connect( mVerticalDisplacementSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementSpinBox_valueChanged );
3230  connect( mHorizontalOffsetSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetSpinBox_valueChanged );
3231  connect( mVerticalOffsetSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetSpinBox_valueChanged );
3232  connect( mHorizontalDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceUnitWidget_changed );
3233  connect( mVerticalDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceUnitWidget_changed );
3234  connect( mHorizontalDisplacementUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementUnitWidget_changed );
3235  connect( mVerticalDisplacementUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementUnitWidget_changed );
3236  connect( mHorizontalOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetUnitWidget_changed );
3237  connect( mVerticalOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetUnitWidget_changed );
3250 
3251  mClipModeComboBox->addItem( tr( "Clip to Shape" ), static_cast< int >( Qgis::MarkerClipMode::Shape ) );
3252  mClipModeComboBox->addItem( tr( "Marker Centroid Within Shape" ), static_cast< int >( Qgis::MarkerClipMode::CentroidWithin ) );
3253  mClipModeComboBox->addItem( tr( "Marker Completely Within Shape" ), static_cast< int >( Qgis::MarkerClipMode::CompletelyWithin ) );
3254  mClipModeComboBox->addItem( tr( "No Clipping" ), static_cast< int >( Qgis::MarkerClipMode::NoClipping ) );
3255  connect( mClipModeComboBox, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]
3256  {
3257  if ( mLayer )
3258  {
3259  mLayer->setClipMode( static_cast< Qgis::MarkerClipMode >( mClipModeComboBox->currentData().toInt() ) );
3260  emit changed();
3261  }
3262  } );
3263 
3264  mCoordinateReferenceComboBox->addItem( tr( "Align Pattern to Feature" ), static_cast< int >( Qgis::SymbolCoordinateReference::Feature ) );
3265  mCoordinateReferenceComboBox->addItem( tr( "Align Pattern to Map Extent" ), static_cast< int >( Qgis::SymbolCoordinateReference::Viewport ) );
3266  connect( mCoordinateReferenceComboBox, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]
3267  {
3268  if ( mLayer )
3269  {
3270  mLayer->setCoordinateReference( static_cast< Qgis::SymbolCoordinateReference >( mCoordinateReferenceComboBox->currentData().toInt() ) );
3271  emit changed();
3272  }
3273  } );
3274 
3275  mSeedSpinBox->setShowClearButton( true );
3276  mSeedSpinBox->setClearValue( 0 );
3277  mRandomXSpinBox->setClearValue( 0 );
3278  mRandomYSpinBox->setClearValue( 0 );
3279 
3284  connect( mRandomXSpinBox, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double d )
3285  {
3286  if ( mLayer )
3287  {
3289  emit changed();
3290  }
3291  } );
3292  connect( mRandomYSpinBox, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double d )
3293  {
3294  if ( mLayer )
3295  {
3297  emit changed();
3298  }
3299  } );
3300  connect( mRandomXOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, [ = ]
3301  {
3302  if ( mLayer )
3303  {
3304  mLayer->setRandomDeviationXUnit( mRandomXOffsetUnitWidget->unit() );
3305  mLayer->setRandomDeviationXMapUnitScale( mRandomXOffsetUnitWidget->getMapUnitScale() );
3306  emit changed();
3307  }
3308  } );
3309  connect( mRandomYOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, [ = ]
3310  {
3311  if ( mLayer )
3312  {
3313  mLayer->setRandomDeviationYUnit( mRandomYOffsetUnitWidget->unit() );
3314  mLayer->setRandomDeviationYMapUnitScale( mRandomYOffsetUnitWidget->getMapUnitScale() );
3315  emit changed();
3316  }
3317  } );
3318  connect( mSeedSpinBox, qOverload< int > ( &QSpinBox::valueChanged ), this, [ = ]( int v )
3319  {
3320  if ( mLayer )
3321  {
3322  mLayer->setSeed( v );
3323  emit changed();
3324  }
3325  } );
3326 
3327  mAngleSpinBox->setShowClearButton( true );
3328  mAngleSpinBox->setClearValue( 0 );
3329  connect( mAngleSpinBox, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double d )
3330  {
3331  if ( mLayer )
3332  {
3333  mLayer->setAngle( d );
3334  emit changed();
3335  }
3336  } );
3337 }
3338 
3340 {
3341  if ( !layer || layer->layerType() != QLatin1String( "PointPatternFill" ) )
3342  {
3343  return;
3344  }
3345 
3346  mLayer = static_cast<QgsPointPatternFillSymbolLayer *>( layer );
3347  whileBlocking( mHorizontalDistanceSpinBox )->setValue( mLayer->distanceX() );
3348  whileBlocking( mVerticalDistanceSpinBox )->setValue( mLayer->distanceY() );
3349  whileBlocking( mHorizontalDisplacementSpinBox )->setValue( mLayer->displacementX() );
3350  whileBlocking( mVerticalDisplacementSpinBox )->setValue( mLayer->displacementY() );
3351  whileBlocking( mHorizontalOffsetSpinBox )->setValue( mLayer->offsetX() );
3352  whileBlocking( mVerticalOffsetSpinBox )->setValue( mLayer->offsetY() );
3353  whileBlocking( mAngleSpinBox )->setValue( mLayer->angle() );
3354 
3355  mHorizontalDistanceUnitWidget->blockSignals( true );
3356  mHorizontalDistanceUnitWidget->setUnit( mLayer->distanceXUnit() );
3357  mHorizontalDistanceUnitWidget->setMapUnitScale( mLayer->distanceXMapUnitScale() );
3358  mHorizontalDistanceUnitWidget->blockSignals( false );
3359  mVerticalDistanceUnitWidget->blockSignals( true );
3360  mVerticalDistanceUnitWidget->setUnit( mLayer->distanceYUnit() );
3361  mVerticalDistanceUnitWidget->setMapUnitScale( mLayer->distanceYMapUnitScale() );
3362  mVerticalDistanceUnitWidget->blockSignals( false );
3363  mHorizontalDisplacementUnitWidget->blockSignals( true );
3364  mHorizontalDisplacementUnitWidget->setUnit( mLayer->displacementXUnit() );
3365  mHorizontalDisplacementUnitWidget->setMapUnitScale( mLayer->displacementXMapUnitScale() );
3366  mHorizontalDisplacementUnitWidget->blockSignals( false );
3367  mVerticalDisplacementUnitWidget->blockSignals( true );
3368  mVerticalDisplacementUnitWidget->setUnit( mLayer->displacementYUnit() );
3369  mVerticalDisplacementUnitWidget->setMapUnitScale( mLayer->displacementYMapUnitScale() );
3370  mVerticalDisplacementUnitWidget->blockSignals( false );
3371  mHorizontalOffsetUnitWidget->blockSignals( true );
3372  mHorizontalOffsetUnitWidget->setUnit( mLayer->offsetXUnit() );
3373  mHorizontalOffsetUnitWidget->setMapUnitScale( mLayer->offsetXMapUnitScale() );
3374  mHorizontalOffsetUnitWidget->blockSignals( false );
3375  mVerticalOffsetUnitWidget->blockSignals( true );
3376  mVerticalOffsetUnitWidget->setUnit( mLayer->offsetYUnit() );
3377  mVerticalOffsetUnitWidget->setMapUnitScale( mLayer->offsetYMapUnitScale() );
3378  mVerticalOffsetUnitWidget->blockSignals( false );
3379 
3380  whileBlocking( mClipModeComboBox )->setCurrentIndex( mClipModeComboBox->findData( static_cast< int >( mLayer->clipMode() ) ) );
3381  whileBlocking( mCoordinateReferenceComboBox )->setCurrentIndex( mCoordinateReferenceComboBox->findData( static_cast< int >( mLayer->coordinateReference() ) ) );
3382 
3383  whileBlocking( mRandomXSpinBox )->setValue( mLayer->maximumRandomDeviationX() );
3384  whileBlocking( mRandomYSpinBox )->setValue( mLayer->maximumRandomDeviationY() );
3385  whileBlocking( mRandomXOffsetUnitWidget )->setUnit( mLayer->randomDeviationXUnit() );
3386  whileBlocking( mRandomXOffsetUnitWidget )->setMapUnitScale( mLayer->randomDeviationXMapUnitScale() );
3387  whileBlocking( mRandomYOffsetUnitWidget )->setUnit( mLayer->randomDeviationYUnit() );
3388  whileBlocking( mRandomYOffsetUnitWidget )->setMapUnitScale( mLayer->randomDeviationYMapUnitScale() );
3389  whileBlocking( mSeedSpinBox )->setValue( mLayer->seed() );
3390 
3391  registerDataDefinedButton( mHorizontalDistanceDDBtn, QgsSymbolLayer::PropertyDistanceX );
3393  registerDataDefinedButton( mHorizontalDisplacementDDBtn, QgsSymbolLayer::PropertyDisplacementX );
3403 }
3404 
3406 {
3407  return mLayer;
3408 }
3409 
3410 void QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceSpinBox_valueChanged( double d )
3411 {
3412  if ( mLayer )
3413  {
3414  mLayer->setDistanceX( d );
3415  emit changed();
3416  }
3417 }
3418 
3419 void QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceSpinBox_valueChanged( double d )
3420 {
3421  if ( mLayer )
3422  {
3423  mLayer->setDistanceY( d );
3424  emit changed();
3425  }
3426 }
3427 
3428 void QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementSpinBox_valueChanged( double d )
3429 {
3430  if ( mLayer )
3431  {
3432  mLayer->setDisplacementX( d );
3433  emit changed();
3434  }
3435 }
3436 
3437 void QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementSpinBox_valueChanged( double d )
3438 {
3439  if ( mLayer )
3440  {
3441  mLayer->setDisplacementY( d );
3442  emit changed();
3443  }
3444 }
3445 
3446 void QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetSpinBox_valueChanged( double d )
3447 {
3448  if ( mLayer )
3449  {
3450  mLayer->setOffsetX( d );
3451  emit changed();
3452  }
3453 }
3454 
3455 void QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetSpinBox_valueChanged( double d )
3456 {
3457  if ( mLayer )
3458  {
3459  mLayer->setOffsetY( d );
3460  emit changed();
3461  }
3462 }
3463 
3464 void QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceUnitWidget_changed()
3465 {
3466  if ( mLayer )
3467  {
3468  mLayer->setDistanceXUnit( mHorizontalDistanceUnitWidget->unit() );
3469  mLayer->setDistanceXMapUnitScale( mHorizontalDistanceUnitWidget->getMapUnitScale() );
3470  emit changed();
3471  }
3472 }
3473 
3474 void QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceUnitWidget_changed()
3475 {
3476  if ( mLayer )
3477  {
3478  mLayer->setDistanceYUnit( mVerticalDistanceUnitWidget->unit() );
3479  mLayer->setDistanceYMapUnitScale( mVerticalDistanceUnitWidget->getMapUnitScale() );
3480  emit changed();
3481  }
3482 }
3483 
3484 void QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementUnitWidget_changed()
3485 {
3486  if ( mLayer )
3487  {
3488  mLayer->setDisplacementXUnit( mHorizontalDisplacementUnitWidget->unit() );
3489  mLayer->setDisplacementXMapUnitScale( mHorizontalDisplacementUnitWidget->getMapUnitScale() );
3490  emit changed();
3491  }
3492 }
3493 
3494 void QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementUnitWidget_changed()
3495 {
3496  if ( mLayer )
3497  {
3498  mLayer->setDisplacementYUnit( mVerticalDisplacementUnitWidget->unit() );
3499  mLayer->setDisplacementYMapUnitScale( mVerticalDisplacementUnitWidget->getMapUnitScale() );
3500  emit changed();
3501  }
3502 }
3503 
3504 void QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetUnitWidget_changed()
3505 {
3506  if ( mLayer )
3507  {
3508  mLayer->setOffsetXUnit( mHorizontalOffsetUnitWidget->unit() );
3509  mLayer->setOffsetXMapUnitScale( mHorizontalOffsetUnitWidget->getMapUnitScale() );
3510  emit changed();
3511  }
3512 }
3513 
3514 void QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetUnitWidget_changed()
3515 {
3516  if ( mLayer )
3517  {
3518  mLayer->setOffsetYUnit( mVerticalOffsetUnitWidget->unit() );
3519  mLayer->setOffsetYMapUnitScale( mVerticalOffsetUnitWidget->getMapUnitScale() );
3520  emit changed();
3521  }
3522 }
3523 
3525 
3527  : QgsSymbolLayerWidget( parent, vl )
3528 {
3529  mLayer = nullptr;
3530 
3531  setupUi( this );
3532  connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
3533  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
3534  connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
3535  connect( mStrokeWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
3536  connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
3537  connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
3544 
3545  widgetChar = new CharacterWidget();
3546  scrollArea->setWidget( widgetChar );
3547  scrollArea->setVerticalOnly( true );
3548 
3549  btnColor->setAllowOpacity( true );
3550  btnColor->setColorDialogTitle( tr( "Select Symbol Fill Color" ) );
3551  btnColor->setContext( QStringLiteral( "symbology" ) );
3552  btnStrokeColor->setAllowOpacity( true );
3553  btnStrokeColor->setColorDialogTitle( tr( "Select Symbol Stroke Color" ) );
3554  btnStrokeColor->setContext( QStringLiteral( "symbology" ) );
3555 
3556  mColorDDBtn->registerLinkedWidget( btnColor );
3557  mStrokeColorDDBtn->registerLinkedWidget( btnStrokeColor );
3558 
3559  spinOffsetX->setClearValue( 0.0 );
3560  spinOffsetY->setClearValue( 0.0 );
3561  spinAngle->setClearValue( 0.0 );
3562 
3563  //make a temporary symbol for the size assistant preview
3564  mAssistantPreviewSymbol.reset( new QgsMarkerSymbol() );
3565 
3566  if ( vectorLayer() )
3567  mSizeDDBtn->setSymbol( mAssistantPreviewSymbol );
3568 
3569  connect( cboFont, &QFontComboBox::currentFontChanged, this, &QgsFontMarkerSymbolLayerWidget::setFontFamily );
3570  connect( mFontStyleComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::mFontStyleComboBox_currentIndexChanged );
3571  connect( spinSize, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setSize );
3572  connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::penJoinStyleChanged );
3575  connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::penJoinStyleChanged );
3576  connect( spinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setAngle );
3577  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setOffset );
3578  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setOffset );
3580  connect( mCharLineEdit, &QLineEdit::textChanged, this, &QgsFontMarkerSymbolLayerWidget::setCharacterFromText );
3581 
3582  connect( this, &QgsSymbolLayerWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::updateAssistantSymbol );
3583 }
3584 
3586 
3588 {
3589  if ( layer->layerType() != QLatin1String( "FontMarker" ) )
3590  return;
3591 
3592  // layer type is correct, we can do the cast
3593  mLayer = static_cast<QgsFontMarkerSymbolLayer *>( layer );
3594 
3595  mRefFont.setFamily( mLayer->fontFamily() );
3596  mRefFont.setStyleName( QgsFontUtils::translateNamedStyle( mLayer->fontStyle() ) );
3597 
3598  mFontStyleComboBox->blockSignals( true );
3599  populateFontStyleComboBox();
3600  mFontStyleComboBox->blockSignals( false );
3601 
3602  // set values
3603  whileBlocking( cboFont )->setCurrentFont( mRefFont );
3604  whileBlocking( spinSize )->setValue( mLayer->size() );
3605  whileBlocking( btnColor )->setColor( mLayer->color() );
3606  whileBlocking( btnStrokeColor )->setColor( mLayer->strokeColor() );
3607  whileBlocking( mStrokeWidthSpinBox )->setValue( mLayer->strokeWidth() );
3608  whileBlocking( spinAngle )->setValue( mLayer->angle() );
3609 
3610  widgetChar->blockSignals( true );
3611  widgetChar->setFont( mRefFont );
3612  if ( mLayer->character().length() == 1 )
3613  {
3614  widgetChar->setCharacter( mLayer->character().at( 0 ) );
3615  }
3616  widgetChar->blockSignals( false );
3617  whileBlocking( mCharLineEdit )->setText( mLayer->character() );
3618  mCharPreview->setFont( mRefFont );
3619 
3620  //block
3621  whileBlocking( spinOffsetX )->setValue( mLayer->offset().x() );
3622  whileBlocking( spinOffsetY )->setValue( mLayer->offset().y() );
3623 
3624  mSizeUnitWidget->blockSignals( true );
3625  mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
3626  mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
3627  mSizeUnitWidget->blockSignals( false );
3628 
3629  mStrokeWidthUnitWidget->blockSignals( true );
3630  mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
3631  mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
3632  mStrokeWidthUnitWidget->blockSignals( false );
3633 
3634  mOffsetUnitWidget->blockSignals( true );
3635  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
3636  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
3637  mOffsetUnitWidget->blockSignals( false );
3638 
3639  whileBlocking( cboJoinStyle )->setPenJoinStyle( mLayer->penJoinStyle() );
3640 
3641  //anchor points
3642  whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mLayer->horizontalAnchorPoint() );
3643  whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mLayer->verticalAnchorPoint() );
3644 
3657 
3658  updateAssistantSymbol();
3659 }
3660 
3662 {
3663  return mLayer;
3664 }
3665 
3667 {
3668  if ( mLayer )
3669  {
3670  mLayer->setFontFamily( font.family() );
3671  mRefFont.setFamily( font.family() );
3672  widgetChar->setFont( mRefFont );
3673  mCharPreview->setFont( mRefFont );
3674  populateFontStyleComboBox();
3675  emit changed();
3676  }
3677 }
3678 
3679 void QgsFontMarkerSymbolLayerWidget::setFontStyle( const QString &style )
3680 {
3681  if ( mLayer )
3682  {
3683  QgsFontUtils::updateFontViaStyle( mRefFont, style );
3685  widgetChar->setFont( mRefFont );
3686  mCharPreview->setFont( mRefFont );
3687  emit changed();
3688  }
3689 }
3690 
3691 void QgsFontMarkerSymbolLayerWidget::setColor( const QColor &color )
3692 {
3693  mLayer->setColor( color );
3694  emit changed();
3695 }
3696 
3698 {
3699  mLayer->setStrokeColor( color );
3700  emit changed();
3701 }
3702 
3704 {
3705  mLayer->setSize( size );
3706  //widgetChar->updateSize(size);
3707  emit changed();
3708 }
3709 
3711 {
3712  mLayer->setAngle( angle );
3713  emit changed();
3714 }
3715 
3717 {
3718  mCharPreview->setText( text );
3719 
3720  if ( text.isEmpty() )
3721  return;
3722 
3723  // take the last character of a string for a better experience when users cycle through several characters on their keyboard
3724  QString character = text;
3725  if ( text.contains( QRegularExpression( QStringLiteral( "^0x[0-9a-fA-F]{1,4}$" ) ) ) )
3726  {
3727  bool ok = false;
3728  const unsigned int value = text.toUInt( &ok, 0 );
3729  if ( ok )
3730  {
3731  character = QChar( value );
3732  mCharPreview->setText( character );
3733  }
3734  }
3735 
3736  if ( character != mLayer->character() )
3737  {
3738  mLayer->setCharacter( character );
3739  if ( mLayer->character().length() == 1 )
3740  {
3741  whileBlocking( widgetChar )->setCharacter( mLayer->character().at( 0 ) );
3742  }
3743  else
3744  {
3746  }
3747  emit changed();
3748  }
3749 }
3750 
3752 {
3753  if ( mLayer->character().length() > 1 || QGuiApplication::keyboardModifiers() & Qt::ControlModifier )
3754  {
3755  mCharLineEdit->insert( chr );
3756  return;
3757  }
3758 
3759  mLayer->setCharacter( chr );
3760  whileBlocking( mCharLineEdit )->setText( chr );
3761  mCharPreview->setText( chr );
3762  emit changed();
3763 }
3764 
3765 void QgsFontMarkerSymbolLayerWidget::setOffset()
3766 {
3767  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
3768  emit changed();
3769 }
3770 
3771 void QgsFontMarkerSymbolLayerWidget::penJoinStyleChanged()
3772 {
3773  mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
3774  emit changed();
3775 }
3776 
3777 void QgsFontMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
3778 {
3779  if ( mLayer )
3780  {
3781  mLayer->setSizeUnit( mSizeUnitWidget->unit() );
3782  mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
3783  emit changed();
3784  }
3785 }
3786 
3787 void QgsFontMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
3788 {
3789  if ( mLayer )
3790  {
3791  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
3792  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
3793  emit changed();
3794  }
3795 }
3796 
3797 void QgsFontMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
3798 {
3799  if ( mLayer )
3800  {
3801  mLayer->setStrokeWidthUnit( mSizeUnitWidget->unit() );
3802  mLayer->setStrokeWidthMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
3803  emit changed();
3804  }
3805 }
3806 
3807 void QgsFontMarkerSymbolLayerWidget::populateFontStyleComboBox()
3808 {
3809  mFontStyleComboBox->clear();
3810  const QStringList styles = mFontDB.styles( mRefFont.family() );
3811  const auto constStyles = styles;
3812  for ( const QString &style : constStyles )
3813  {
3814  mFontStyleComboBox->addItem( style );
3815  }
3816 
3817  QString targetStyle = mFontDB.styleString( mRefFont );
3818  if ( !styles.contains( targetStyle ) )
3819  {
3820  const QFont f = QFont( mRefFont.family() );
3821  targetStyle = QFontInfo( f ).styleName();
3822  mRefFont.setStyleName( targetStyle );
3823  }
3824  int curIndx = 0;
3825  const int stylIndx = mFontStyleComboBox->findText( targetStyle );
3826  if ( stylIndx > -1 )
3827  {
3828  curIndx = stylIndx;
3829  }
3830 
3831  mFontStyleComboBox->setCurrentIndex( curIndx );
3832 }
3833 
3834 void QgsFontMarkerSymbolLayerWidget::mFontStyleComboBox_currentIndexChanged( int index )
3835 {
3836  Q_UNUSED( index );
3837  setFontStyle( mFontStyleComboBox->currentText() );
3838 }
3839 
3840 void QgsFontMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
3841 {
3842  if ( mLayer )
3843  {
3845  emit changed();
3846  }
3847 }
3848 
3849 void QgsFontMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
3850 {
3851  if ( mLayer )
3852  {
3854  emit changed();
3855  }
3856 }
3857 
3858 void QgsFontMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
3859 {
3860  if ( mLayer )
3861  {
3862  mLayer->setStrokeWidth( d );
3863  emit changed();
3864  }
3865 }
3866 
3867 void QgsFontMarkerSymbolLayerWidget::updateAssistantSymbol()
3868 {
3869  for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
3870  {
3871  mAssistantPreviewSymbol->deleteSymbolLayer( i );
3872  }
3873  mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
3875  if ( ddSize )
3876  mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
3877 }
3878 
3880 
3881 
3883  : QgsSymbolLayerWidget( parent, vl )
3884 {
3885  mLayer = nullptr;
3886 
3887  setupUi( this );
3888  connect( mDrawInsideCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mDrawInsideCheckBox_stateChanged );
3889  connect( mDrawAllPartsCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mDrawAllPartsCheckBox_stateChanged );
3890  connect( mClipPointsCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mClipPointsCheckBox_stateChanged );
3891  connect( mClipOnCurrentPartOnlyCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mClipOnCurrentPartOnlyCheckBox_stateChanged );
3892 }
3893 
3895 {
3896  if ( layer->layerType() != QLatin1String( "CentroidFill" ) )
3897  return;
3898 
3899  // layer type is correct, we can do the cast
3900  mLayer = static_cast<QgsCentroidFillSymbolLayer *>( layer );
3901 
3902  // set values
3903  whileBlocking( mDrawInsideCheckBox )->setChecked( mLayer->pointOnSurface() );
3904  whileBlocking( mDrawAllPartsCheckBox )->setChecked( mLayer->pointOnAllParts() );
3905  whileBlocking( mClipPointsCheckBox )->setChecked( mLayer->clipPoints() );
3906  whileBlocking( mClipOnCurrentPartOnlyCheckBox )->setChecked( mLayer->clipOnCurrentPartOnly() );
3907 }
3908 
3910 {
3911  return mLayer;
3912 }
3913 
3914 void QgsCentroidFillSymbolLayerWidget::mDrawInsideCheckBox_stateChanged( int state )
3915 {
3916  mLayer->setPointOnSurface( state == Qt::Checked );
3917  emit changed();
3918 }
3919 
3920 void QgsCentroidFillSymbolLayerWidget::mDrawAllPartsCheckBox_stateChanged( int state )
3921 {
3922  mLayer->setPointOnAllParts( state == Qt::Checked );
3923  emit changed();
3924 }
3925 
3926 void QgsCentroidFillSymbolLayerWidget::mClipPointsCheckBox_stateChanged( int state )
3927 {
3928  mLayer->setClipPoints( state == Qt::Checked );
3929  emit changed();
3930 }
3931 
3932 void QgsCentroidFillSymbolLayerWidget::mClipOnCurrentPartOnlyCheckBox_stateChanged( int state )
3933 {
3934  mLayer->setClipOnCurrentPartOnly( state == Qt::Checked );
3935  emit changed();
3936 }
3937 
3939 
3941  : QgsSymbolLayerWidget( parent, vl )
3942 {
3943  mLayer = nullptr;
3944 
3945  setupUi( this );
3946 
3947  mImageSourceLineEdit->setLastPathSettingsKey( QStringLiteral( "/UI/lastRasterMarkerImageDir" ) );
3948 
3949  connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsRasterMarkerSymbolLayerWidget::imageSourceChanged );
3950  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
3951  connect( mRotationSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setAngle );
3952  connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
3953  connect( mWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setWidth );
3954  connect( mHeightSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setHeight );
3955  connect( mLockAspectRatio, static_cast < void ( QgsRatioLockButton::* )( bool ) > ( &QgsRatioLockButton::lockChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setLockAspectRatio );
3956 
3961 
3962  mSpinOffsetX->setClearValue( 0.0 );
3963  mSpinOffsetY->setClearValue( 0.0 );
3964  mRotationSpinBox->setClearValue( 0.0 );
3965 
3966  connect( mSpinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setOffset );
3967  connect( mSpinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setOffset );
3968  connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsRasterMarkerSymbolLayerWidget::setOpacity );
3969 
3970  connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
3971  connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
3972 }
3973 
3975 {
3976  if ( !layer )
3977  {
3978  return;
3979  }
3980 
3981  if ( layer->layerType() != QLatin1String( "RasterMarker" ) )
3982  return;
3983 
3984  // layer type is correct, we can do the cast
3985  mLayer = static_cast<QgsRasterMarkerSymbolLayer *>( layer );
3986 
3987  // set values
3988  whileBlocking( mImageSourceLineEdit )->setSource( mLayer->path() );
3989 
3990  whileBlocking( mWidthSpinBox )->setValue( mLayer->size() );
3991  const bool preservedAspectRatio = mLayer->preservedAspectRatio();
3992  mHeightSpinBox->blockSignals( true );
3993  if ( preservedAspectRatio )
3994  {
3995  mHeightSpinBox->setValue( mLayer->size() );
3996  }
3997  else
3998  {
3999  mHeightSpinBox->setValue( mLayer->size() * mLayer->fixedAspectRatio() );
4000  }
4001  mHeightSpinBox->setEnabled( mLayer->defaultAspectRatio() > 0.0 );
4002  mHeightSpinBox->blockSignals( false );
4003  whileBlocking( mLockAspectRatio )->setLocked( preservedAspectRatio );
4004 
4005  whileBlocking( mRotationSpinBox )->setValue( mLayer->angle() );
4006  whileBlocking( mOpacityWidget )->setOpacity( mLayer->opacity() );
4007 
4008  whileBlocking( mSpinOffsetX )->setValue( mLayer->offset().x() );
4009  whileBlocking( mSpinOffsetY )->setValue( mLayer->offset().y() );
4010 
4011  mSizeUnitWidget->blockSignals( true );
4012  mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
4013  mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
4014  mSizeUnitWidget->blockSignals( false );
4015  mOffsetUnitWidget->blockSignals( true );
4016  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
4017  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
4018  mOffsetUnitWidget->blockSignals( false );
4019 
4020  //anchor points
4021  whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mLayer->horizontalAnchorPoint() );
4022  whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mLayer->verticalAnchorPoint() );
4023 
4032 
4033  updatePreviewImage();
4034 }
4035 
4037 {
4038  return mLayer;
4039 }
4040 
4042 {
4044  mImageSourceLineEdit->setMessageBar( context.messageBar() );
4045 }
4046 
4047 void QgsRasterMarkerSymbolLayerWidget::imageSourceChanged( const QString &text )
4048 {
4049  mLayer->setPath( text );
4050  updatePreviewImage();
4051  emit changed();
4052 }
4053 
4054 void QgsRasterMarkerSymbolLayerWidget::updatePreviewImage()
4055 {
4056  bool fitsInCache = false;
4057  const QImage image = QgsApplication::imageCache()->pathAsImage( mLayer->path(), QSize( 150, 150 ), true, 1.0, fitsInCache );
4058  if ( image.isNull() )
4059  {
4060  mLabelImagePreview->setPixmap( QPixmap() );
4061  return;
4062  }
4063 
4064  QImage previewImage( 150, 150, QImage::Format_ARGB32 );
4065  previewImage.fill( Qt::transparent );
4066  const QRect imageRect( ( 150 - image.width() ) / 2.0, ( 150 - image.height() ) / 2.0, image.width(), image.height() );
4067  QPainter p;
4068  p.begin( &previewImage );
4069  //draw a checkerboard background
4070  uchar pixDataRGB[] = { 150, 150, 150, 150,
4071  100, 100, 100, 150,
4072  100, 100, 100, 150,
4073  150, 150, 150, 150
4074  };
4075  const QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
4076  const QPixmap pix = QPixmap::fromImage( img.scaled( 8, 8 ) );
4077  QBrush checkerBrush;
4078  checkerBrush.setTexture( pix );
4079  p.fillRect( imageRect, checkerBrush );
4080 
4081  if ( mLayer->opacity() < 1.0 )
4082  {
4083  p.setOpacity( mLayer->opacity() );
4084  }
4085 
4086  p.drawImage( imageRect.left(), imageRect.top(), image );
4087  p.end();
4088  mLabelImagePreview->setPixmap( QPixmap::fromImage( previewImage ) );
4089 }
4090 
4091 void QgsRasterMarkerSymbolLayerWidget::setWidth()
4092 {
4093  const double defaultAspectRatio = mLayer->defaultAspectRatio();
4094  double fixedAspectRatio = 0.0;
4095  mHeightSpinBox->blockSignals( true );
4096  if ( defaultAspectRatio <= 0.0 )
4097  {
4098  mHeightSpinBox->setValue( mWidthSpinBox->value() );
4099  }
4100  else if ( mLockAspectRatio->locked() )
4101  {
4102  mHeightSpinBox->setValue( mWidthSpinBox->value() * defaultAspectRatio );
4103  }
4104  else
4105  {
4106  fixedAspectRatio = mHeightSpinBox->value() / mWidthSpinBox->value();
4107  }
4108  mHeightSpinBox->blockSignals( false );
4109  mLayer->setSize( mWidthSpinBox->value() );
4110  mLayer->setFixedAspectRatio( fixedAspectRatio );
4111  emit changed();
4112 }
4113 
4114 void QgsRasterMarkerSymbolLayerWidget::setHeight()
4115 {
4116  const double defaultAspectRatio = mLayer->defaultAspectRatio();
4117  double fixedAspectRatio = 0.0;
4118  mWidthSpinBox->blockSignals( true );
4119  if ( defaultAspectRatio <= 0.0 )
4120  {
4121  mWidthSpinBox->setValue( mHeightSpinBox->value() );
4122  }
4123  else if ( mLockAspectRatio->locked() )
4124  {
4125  mWidthSpinBox->setValue( mHeightSpinBox->value() / defaultAspectRatio );
4126  }
4127  else
4128  {
4129  fixedAspectRatio = mHeightSpinBox->value() / mWidthSpinBox->value();
4130  }
4131  mWidthSpinBox->blockSignals( false );
4132  mLayer->setSize( mWidthSpinBox->value() );
4133  mLayer->setFixedAspectRatio( fixedAspectRatio );
4134  emit changed();
4135 }
4136 
4137 void QgsRasterMarkerSymbolLayerWidget::setLockAspectRatio( const bool locked )
4138 {
4139  const double defaultAspectRatio = mLayer->defaultAspectRatio();
4140  if ( defaultAspectRatio <= 0.0 )
4141  {
4142  whileBlocking( mLockAspectRatio )->setLocked( true );
4143  }
4144  else if ( locked )
4145  {
4146  mLayer->setFixedAspectRatio( 0.0 );
4147  setWidth();
4148  }
4149  else
4150  {
4151  mLayer->setFixedAspectRatio( mHeightSpinBox->value() / mWidthSpinBox->value() );
4152  }
4153 }
4154 
4155 void QgsRasterMarkerSymbolLayerWidget::setAngle()
4156 {
4157  mLayer->setAngle( mRotationSpinBox->value() );
4158  emit changed();
4159 }
4160 
4161 void QgsRasterMarkerSymbolLayerWidget::setOpacity( double value )
4162 {
4163  mLayer->setOpacity( value );
4164  emit changed();
4165  updatePreviewImage();
4166 }
4167 
4168 void QgsRasterMarkerSymbolLayerWidget::setOffset()
4169 {
4170  mLayer->setOffset( QPointF( mSpinOffsetX->value(), mSpinOffsetY->value() ) );
4171  emit changed();
4172 }
4173 
4174 void QgsRasterMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
4175 {
4176  if ( mLayer )
4177  {
4178  mLayer->setSizeUnit( mSizeUnitWidget->unit() );
4179  mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
4180  emit changed();
4181  }
4182 }
4183 
4184 void QgsRasterMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
4185 {
4186  if ( mLayer )
4187  {
4188  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
4189  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
4190  emit changed();
4191  }
4192 }
4193 
4194 void QgsRasterMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
4195 {
4196  if ( mLayer )
4197  {
4199  emit changed();
4200  }
4201 }
4202 
4203 void QgsRasterMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
4204 {
4205  if ( mLayer )
4206  {
4208  emit changed();
4209  }
4210 }
4211 
4213 
4215  : QgsSymbolLayerWidget( parent, vl )
4216 {
4217  mLayer = nullptr;
4218  setupUi( this );
4219 
4220  mImageSourceLineEdit->setLastPathSettingsKey( QStringLiteral( "/UI/lastRasterMarkerImageDir" ) );
4221  connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsRasterFillSymbolLayerWidget::imageSourceChanged );
4222 
4223  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterFillSymbolLayerWidget::mOffsetUnitWidget_changed );
4224  connect( mRotationSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::mRotationSpinBox_valueChanged );
4225  connect( mWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterFillSymbolLayerWidget::mWidthUnitWidget_changed );
4226  connect( mWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::mWidthSpinBox_valueChanged );
4227 
4232 
4233  mSpinOffsetX->setClearValue( 0.0 );
4234  mSpinOffsetY->setClearValue( 0.0 );
4235  mRotationSpinBox->setClearValue( 0.0 );
4236 
4237  connect( cboCoordinateMode, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterFillSymbolLayerWidget::setCoordinateMode );
4238  connect( mSpinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::offsetChanged );
4239  connect( mSpinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::offsetChanged );
4240  connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsRasterFillSymbolLayerWidget::opacityChanged );
4241 }
4242 
4243 
4245 {
4246  if ( !layer )
4247  {
4248  return;
4249  }
4250 
4251  if ( layer->layerType() != QLatin1String( "RasterFill" ) )
4252  {
4253  return;
4254  }
4255 
4256  mLayer = dynamic_cast<QgsRasterFillSymbolLayer *>( layer );
4257  if ( !mLayer )
4258  {
4259  return;
4260  }
4261 
4262  whileBlocking( mImageSourceLineEdit )->setSource( mLayer->imageFilePath() );
4263 
4264  cboCoordinateMode->blockSignals( true );
4265  switch ( mLayer->coordinateMode() )
4266  {
4268  cboCoordinateMode->setCurrentIndex( 1 );
4269  break;
4271  default:
4272  cboCoordinateMode->setCurrentIndex( 0 );
4273  break;
4274  }
4275  cboCoordinateMode->blockSignals( false );
4276  whileBlocking( mOpacityWidget )->setOpacity( mLayer->opacity() );
4277  whileBlocking( mRotationSpinBox )->setValue( mLayer->angle() );
4278 
4279  whileBlocking( mSpinOffsetX )->setValue( mLayer->offset().x() );
4280  whileBlocking( mSpinOffsetY )->setValue( mLayer->offset().y() );
4281  mOffsetUnitWidget->blockSignals( true );
4282  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
4283  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
4284  mOffsetUnitWidget->blockSignals( false );
4285 
4286  whileBlocking( mWidthSpinBox )->setValue( mLayer->width() );
4287  mWidthUnitWidget->blockSignals( true );
4288  mWidthUnitWidget->setUnit( mLayer->widthUnit() );
4289  mWidthUnitWidget->setMapUnitScale( mLayer->widthMapUnitScale() );
4290  mWidthUnitWidget->blockSignals( false );
4291 
4292  updatePreviewImage();
4293 
4299 }
4300 
4302 {
4303  return mLayer;
4304 }
4305 
4306 void QgsRasterFillSymbolLayerWidget::imageSourceChanged( const QString &text )
4307 {
4308  mLayer->setImageFilePath( text );
4309  updatePreviewImage();
4310  emit changed();
4311 }
4312 
4313 void QgsRasterFillSymbolLayerWidget::setCoordinateMode( int index )
4314 {
4315  switch ( index )
4316  {
4317  case 0:
4318  //feature coordinate mode
4320  break;
4321  case 1:
4322  //viewport coordinate mode
4324  break;
4325  }
4326 
4327  emit changed();
4328 }
4329 
4330 void QgsRasterFillSymbolLayerWidget::opacityChanged( double value )
4331 {
4332  if ( !mLayer )
4333  {
4334  return;
4335  }
4336 
4337  mLayer->setOpacity( value );
4338  emit changed();
4339  updatePreviewImage();
4340 }
4341 
4342 void QgsRasterFillSymbolLayerWidget::offsetChanged()
4343 {
4344  mLayer->setOffset( QPointF( mSpinOffsetX->value(), mSpinOffsetY->value() ) );
4345  emit changed();
4346 }
4347 
4348 void QgsRasterFillSymbolLayerWidget::mOffsetUnitWidget_changed()
4349 {
4350  if ( !mLayer )
4351  {
4352  return;
4353  }
4354  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
4355  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
4356  emit changed();
4357 }
4358 
4359 void QgsRasterFillSymbolLayerWidget::mRotationSpinBox_valueChanged( double d )
4360 {
4361  if ( mLayer )
4362  {
4363  mLayer->setAngle( d );
4364  emit changed();
4365  }
4366 }
4367 
4368 void QgsRasterFillSymbolLayerWidget::mWidthUnitWidget_changed()
4369 {
4370  if ( !mLayer )
4371  {
4372  return;
4373  }
4374  mLayer->setWidthUnit( mWidthUnitWidget->unit() );
4375  mLayer->setWidthMapUnitScale( mWidthUnitWidget->getMapUnitScale() );
4376  emit changed();
4377 }
4378 
4379 void QgsRasterFillSymbolLayerWidget::mWidthSpinBox_valueChanged( double d )
4380 {
4381  if ( !mLayer )
4382  {
4383  return;
4384  }
4385  mLayer->setWidth( d );
4386  emit changed();
4387 }
4388 
4389 void QgsRasterFillSymbolLayerWidget::updatePreviewImage()
4390 {
4391  bool fitsInCache = false;
4392  const QImage image = QgsApplication::imageCache()->pathAsImage( mLayer->imageFilePath(), QSize( 150, 150 ), true, 1.0, fitsInCache );
4393  if ( image.isNull() )
4394  {
4395  mLabelImagePreview->setPixmap( QPixmap() );
4396  return;
4397  }
4398 
4399  QImage previewImage( 150, 150, QImage::Format_ARGB32 );
4400  previewImage.fill( Qt::transparent );
4401  const QRect imageRect( ( 150 - image.width() ) / 2.0, ( 150 - image.height() ) / 2.0, image.width(), image.height() );
4402  QPainter p;
4403  p.begin( &previewImage );
4404  //draw a checkerboard background
4405  uchar pixDataRGB[] = { 150, 150, 150, 150,
4406  100, 100, 100, 150,
4407  100, 100, 100, 150,
4408  150, 150, 150, 150
4409  };
4410  const QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
4411  const QPixmap pix = QPixmap::fromImage( img.scaled( 8, 8 ) );
4412  QBrush checkerBrush;
4413  checkerBrush.setTexture( pix );
4414  p.fillRect( imageRect, checkerBrush );
4415 
4416  if ( mLayer->opacity() < 1.0 )
4417  {
4418  p.setOpacity( mLayer->opacity() );
4419  }
4420 
4421  p.drawImage( imageRect.left(), imageRect.top(), image );
4422  p.end();
4423  mLabelImagePreview->setPixmap( QPixmap::fromImage( previewImage ) );
4424 }
4425 
4426 //
4427 // QgsRasterLineSymbolLayerWidget
4428 //
4429 
4430 
4432  : QgsSymbolLayerWidget( parent, vl )
4433 {
4434  mLayer = nullptr;
4435  setupUi( this );
4436 
4437  mImageSourceLineEdit->setLastPathSettingsKey( QStringLiteral( "/UI/lastRasterMarkerImageDir" ) );
4438 
4443 
4444  connect( mPenWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, [ = ]
4445  {
4446  if ( mLayer )
4447  {
4448  mLayer->setWidthUnit( mPenWidthUnitWidget->unit() );
4449  mLayer->setWidthMapUnitScale( mPenWidthUnitWidget->getMapUnitScale() );
4450  emit changed();
4451  }
4452  } );
4453 
4454  connect( spinWidth, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]
4455  {
4456  if ( mLayer )
4457  {
4458  mLayer->setWidth( spinWidth->value() );
4459  emit changed();
4460  }
4461  } );
4462 
4463  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, [ = ]
4464  {
4465  if ( mLayer )
4466  {
4467  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
4468  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
4469  emit changed();
4470  }
4471  } );
4472 
4473 
4474  spinOffset->setClearValue( 0.0 );
4475  connect( spinOffset, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double val )
4476  {
4477  if ( mLayer )
4478  {
4479  mLayer->setOffset( val );
4480  emit changed();
4481  }
4482  } );
4483 
4484  connect( cboCapStyle, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]
4485  {
4486  if ( mLayer )
4487  {
4488  mLayer->setPenCapStyle( cboCapStyle->penCapStyle() );
4489  emit changed();
4490  }
4491  } );
4492  connect( cboJoinStyle, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]
4493  {
4494  if ( mLayer )
4495  {
4496  mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
4497  emit changed();
4498  }
4499  } );
4500 
4501  connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsRasterLineSymbolLayerWidget::imageSourceChanged );
4502  connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, [ = ]( double opacity )
4503  {
4504  if ( mLayer )
4505  {
4506  mLayer->setOpacity( opacity );
4507  updatePreviewImage();
4508  emit changed();
4509  }
4510  } );
4511 }
4512 
4514 {
4515  if ( !layer )
4516  {
4517  return;
4518  }
4519 
4520  if ( layer->layerType() != QLatin1String( "RasterLine" ) )
4521  {
4522  return;
4523  }
4524 
4525  mLayer = dynamic_cast<QgsRasterLineSymbolLayer *>( layer );
4526  if ( !mLayer )
4527  {
4528  return;
4529  }
4530 
4531  whileBlocking( mImageSourceLineEdit )->setSource( mLayer->path() );
4532  whileBlocking( mOpacityWidget )->setOpacity( mLayer->opacity() );
4533 
4534  whileBlocking( spinWidth )->setValue( mLayer->width() );
4535  whileBlocking( mPenWidthUnitWidget )->setUnit( mLayer->widthUnit() );
4536  whileBlocking( mPenWidthUnitWidget )->setMapUnitScale( mLayer->widthMapUnitScale() );
4537  whileBlocking( cboJoinStyle )->setPenJoinStyle( mLayer->penJoinStyle() );
4538  whileBlocking( cboCapStyle )->setPenCapStyle( mLayer->penCapStyle() );
4539 
4540  whileBlocking( mOffsetUnitWidget )->setUnit( mLayer->offsetUnit() );
4541  whileBlocking( mOffsetUnitWidget )->setMapUnitScale( mLayer->offsetMapUnitScale() );
4542  whileBlocking( spinOffset )->setValue( mLayer->offset() );
4543 
4544  updatePreviewImage();
4545 
4552 }
4553 
4555 {
4556  return mLayer;
4557 }
4558 
4559 void QgsRasterLineSymbolLayerWidget::imageSourceChanged( const QString &text )
4560 {
4561  mLayer->setPath( text );
4562  updatePreviewImage();
4563  emit changed();
4564 }
4565 
4566 void QgsRasterLineSymbolLayerWidget::updatePreviewImage()
4567 {
4568  bool fitsInCache = false;
4569  const QImage image = QgsApplication::imageCache()->pathAsImage( mLayer->path(), QSize( 150, 150 ), true, 1.0, fitsInCache );
4570  if ( image.isNull() )
4571  {
4572  mLabelImagePreview->setPixmap( QPixmap() );
4573  return;
4574  }
4575 
4576  QImage previewImage( 150, 150, QImage::Format_ARGB32 );
4577  previewImage.fill( Qt::transparent );
4578  const QRect imageRect( ( 150 - image.width() ) / 2.0, ( 150 - image.height() ) / 2.0, image.width(), image.height() );
4579  QPainter p;
4580  p.begin( &previewImage );
4581  //draw a checkerboard background
4582  uchar pixDataRGB[] = { 150, 150, 150, 150,
4583  100, 100, 100, 150,
4584  100, 100, 100, 150,
4585  150, 150, 150, 150
4586  };
4587  const QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
4588  const QPixmap pix = QPixmap::fromImage( img.scaled( 8, 8 ) );
4589  QBrush checkerBrush;
4590  checkerBrush.setTexture( pix );
4591  p.fillRect( imageRect, checkerBrush );
4592 
4593  if ( mLayer->opacity() < 1.0 )
4594  {
4595  p.setOpacity( mLayer->opacity() );
4596  }
4597 
4598  p.drawImage( imageRect.left(), imageRect.top(), image );
4599  p.end();
4600  mLabelImagePreview->setPixmap( QPixmap::fromImage( previewImage ) );
4601 }
4602 
4603 
4604 
4605 //
4606 // QgsGeometryGeneratorSymbolLayerWidget
4607 //
4608 
4610  : QgsSymbolLayerWidget( parent, vl )
4611 
4612 {
4613  setupUi( this );
4614  modificationExpressionSelector->setMultiLine( true );
4615  modificationExpressionSelector->setLayer( const_cast<QgsVectorLayer *>( vl ) );
4616  modificationExpressionSelector->registerExpressionContextGenerator( this );
4617  cbxGeometryType->addItem( QgsIconUtils::iconPolygon(), tr( "Polygon / MultiPolygon" ), static_cast< int >( Qgis::SymbolType::Fill ) );
4618  cbxGeometryType->addItem( QgsIconUtils::iconLine(), tr( "LineString / MultiLineString" ), static_cast< int >( Qgis::SymbolType::Line ) );
4619  cbxGeometryType->addItem( QgsIconUtils::iconPoint(), tr( "Point / MultiPoint" ), static_cast< int >( Qgis::SymbolType::Marker ) );
4620 
4621  mUnitWidget->setUnits( {QgsUnitTypes::RenderMillimeters,
4626  } );
4627  mUnitWidget->setShowMapScaleButton( false );
4628 
4629  connect( modificationExpressionSelector, &QgsExpressionLineEdit::expressionChanged, this, &QgsGeometryGeneratorSymbolLayerWidget::updateExpression );
4630  connect( cbxGeometryType, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGeometryGeneratorSymbolLayerWidget::updateSymbolType );
4631  connect( mUnitWidget, &QgsUnitSelectionWidget::changed, this, [ = ]
4632  {
4633  if ( !mBlockSignals )
4634  {
4635  mLayer->setUnits( mUnitWidget->unit() );
4636  emit symbolChanged();
4637  }
4638  } );
4639 }
4640 
4642 {
4643  mBlockSignals++;
4644  mLayer = static_cast<QgsGeometryGeneratorSymbolLayer *>( l );
4645  modificationExpressionSelector->setExpression( mLayer->geometryExpression() );
4646  cbxGeometryType->setCurrentIndex( cbxGeometryType->findData( static_cast< int >( mLayer->symbolType() ) ) );
4647  mUnitWidget->setUnit( mLayer->units() );
4648  mBlockSignals--;
4649 }
4650 
4652 {
4653  return mLayer;
4654 }
4655 
4656 void QgsGeometryGeneratorSymbolLayerWidget::updateExpression( const QString &string )
4657 {
4658  mLayer->setGeometryExpression( string );
4659 
4660  emit changed();
4661 }
4662 
4663 void QgsGeometryGeneratorSymbolLayerWidget::updateSymbolType()
4664 {
4665  // we try to keep the subsymbol, if we can!
4666  std::unique_ptr< QgsSymbol > subSymbol( mLayer->subSymbol()->clone() );
4667 
4668  mLayer->setSymbolType( static_cast<Qgis::SymbolType>( cbxGeometryType->currentData().toInt() ) );
4669 
4670  switch ( mLayer->symbolType() )
4671  {
4674  break;
4676  {
4677  if ( subSymbol->type() == Qgis::SymbolType::Fill )
4678  {
4679  // going from fill -> line type, so we can copy any LINE symbol layers across
4680  QgsSymbolLayerList layers;
4681  for ( int i = 0; i < subSymbol->symbolLayerCount(); ++i )
4682  {
4683  if ( dynamic_cast< const QgsLineSymbolLayer * >( subSymbol->symbolLayer( i ) ) )
4684  layers << subSymbol->symbolLayer( i )->clone();
4685  }
4686 
4687  if ( !layers.empty() )
4688  mLayer->setSubSymbol( new QgsLineSymbol( layers ) );
4689  }
4690  break;
4691  }
4693  if ( subSymbol->type() == Qgis::SymbolType::Line )
4694  {
4695  // going from line -> fill type, so copy ALL line symbol layers across
4696  QgsSymbolLayerList layers;
4697  for ( int i = 0; i < subSymbol->symbolLayerCount(); ++i )
4698  layers << subSymbol->symbolLayer( i )->clone();
4699  mLayer->setSubSymbol( new QgsFillSymbol( layers ) );
4700  }
4701  break;
4702  }
4703 
4704  emit symbolChanged();
4705 }
4706 
4707 //
4708 // QgsRandomMarkerFillSymbolLayerWidget
4709 //
4710 
4711 
4713  QgsSymbolLayerWidget( parent, vl )
4714 {
4715  setupUi( this );
4716 
4717  mCountMethodComboBox->addItem( tr( "Absolute Count" ), static_cast< int >( Qgis::PointCountMethod::Absolute ) );
4718  mCountMethodComboBox->addItem( tr( "Density-based Count" ), static_cast< int >( Qgis::PointCountMethod::DensityBased ) );
4719 
4720  mPointCountSpinBox->setShowClearButton( true );
4721  mPointCountSpinBox->setClearValue( 100 );
4722  mSeedSpinBox->setShowClearButton( true );
4723  mSeedSpinBox->setClearValue( 0 );
4724 
4725  connect( mCountMethodComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRandomMarkerFillSymbolLayerWidget::countMethodChanged );
4726  connect( mPointCountSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsRandomMarkerFillSymbolLayerWidget::countChanged );
4727  connect( mDensityAreaSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRandomMarkerFillSymbolLayerWidget::densityAreaChanged );
4728  connect( mSeedSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsRandomMarkerFillSymbolLayerWidget::seedChanged );
4729  connect( mClipPointsCheckBox, &QCheckBox::toggled, this, [ = ]( bool checked )
4730  {
4731  if ( mLayer )
4732  {
4733  mLayer->setClipPoints( checked );
4734  emit changed();
4735  }
4736  } );
4737 
4740 
4741  connect( mDensityAreaUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRandomMarkerFillSymbolLayerWidget::densityAreaUnitChanged );
4742 }
4743 
4745 {
4746  if ( !layer || layer->layerType() != QLatin1String( "RandomMarkerFill" ) )
4747  {
4748  return;
4749  }
4750 
4751  mLayer = static_cast<QgsRandomMarkerFillSymbolLayer *>( layer );
4752  whileBlocking( mPointCountSpinBox )->setValue( mLayer->pointCount() );
4753  whileBlocking( mSeedSpinBox )->setValue( mLayer->seed() );
4754  whileBlocking( mClipPointsCheckBox )->setChecked( mLayer->clipPoints() );
4755 
4756  bool showDensityBasedCountWidgets = false;
4757  switch ( mLayer->countMethod() )
4758  {
4759  case Qgis::PointCountMethod::DensityBased:
4760  showDensityBasedCountWidgets = true;
4761  break;
4762  case Qgis::PointCountMethod::Absolute:
4763  break;
4764  }
4765  mDensityAreaLabel->setVisible( showDensityBasedCountWidgets );
4766  mDensityAreaSpinBox->setVisible( showDensityBasedCountWidgets );
4767  mDensityAreaUnitWidget->setVisible( showDensityBasedCountWidgets );
4768  mDensityAreaDdbtn->setVisible( showDensityBasedCountWidgets );
4769 
4770  whileBlocking( mCountMethodComboBox )->setCurrentIndex( mCountMethodComboBox->findData( static_cast< int >( mLayer->countMethod() ) ) );
4771  whileBlocking( mDensityAreaSpinBox )->setValue( mLayer->densityArea() );
4772  mDensityAreaUnitWidget->blockSignals( true );
4773  mDensityAreaUnitWidget->setUnit( mLayer->densityAreaUnit() );
4774  mDensityAreaUnitWidget->setMapUnitScale( mLayer->densityAreaUnitScale() );
4775  mDensityAreaUnitWidget->blockSignals( false );
4776 
4781 }
4782 
4784 {
4785  return mLayer;
4786 }
4787 
4788 void QgsRandomMarkerFillSymbolLayerWidget::countMethodChanged( int )
4789 {
4790 
4791  bool showDensityBasedCountWidgets = false;
4792  switch ( static_cast< Qgis::PointCountMethod >( mCountMethodComboBox->currentData().toInt() ) )
4793  {
4794  case Qgis::PointCountMethod::DensityBased:
4795  showDensityBasedCountWidgets = true;
4796  break;
4797  case Qgis::PointCountMethod::Absolute:
4798  break;
4799  }
4800  mDensityAreaLabel->setVisible( showDensityBasedCountWidgets );
4801  mDensityAreaSpinBox->setVisible( showDensityBasedCountWidgets );
4802  mDensityAreaUnitWidget->setVisible( showDensityBasedCountWidgets );
4803  mDensityAreaDdbtn->setVisible( showDensityBasedCountWidgets );
4804 
4805  if ( mLayer )
4806  {
4807  mLayer->setCountMethod( static_cast< Qgis::PointCountMethod >( mCountMethodComboBox->currentData().toInt() ) );
4808  emit changed();
4809  }
4810 }
4811 
4812 void QgsRandomMarkerFillSymbolLayerWidget::countChanged( int d )
4813 {
4814  if ( mLayer )
4815  {
4816  mLayer->setPointCount( d );
4817  emit changed();
4818  }
4819 }
4820 
4821 void QgsRandomMarkerFillSymbolLayerWidget::densityAreaChanged( double d )
4822 {
4823  if ( mLayer )
4824  {
4825  mLayer->setDensityArea( d );
4826  emit changed();
4827  }
4828 }
4829 
4830 void QgsRandomMarkerFillSymbolLayerWidget::densityAreaUnitChanged()
4831 {
4832  if ( mLayer )
4833  {
4834  mLayer->setDensityAreaUnit( mDensityAreaUnitWidget->unit() );
4835  mLayer->setDensityAreaUnitScale( mDensityAreaUnitWidget->getMapUnitScale() );
4836  emit changed();
4837  }
4838 }
4839 
4840 void QgsRandomMarkerFillSymbolLayerWidget::seedChanged( int d )
4841 {
4842  if ( mLayer )
4843  {
4844  mLayer->setSeed( d );
4845  emit changed();
4846  }
4847 }
4848 
4849 //
4850 // QgsGradientLineSymbolLayerWidget
4851 //
4852 
4854  : QgsSymbolLayerWidget( parent, vl )
4855 {
4856  mLayer = nullptr;
4857  setupUi( this );
4858 
4859  btnColorRamp->setShowGradientOnly( true );
4860 
4861  btnChangeColor->setAllowOpacity( true );
4862  btnChangeColor->setColorDialogTitle( tr( "Select Gradient Color" ) );
4863  btnChangeColor->setContext( QStringLiteral( "symbology" ) );
4864  btnChangeColor->setShowNoColor( true );
4865  btnChangeColor->setNoColorString( tr( "Transparent" ) );
4866  btnChangeColor2->setAllowOpacity( true );
4867  btnChangeColor2->setColorDialogTitle( tr( "Select Gradient Color" ) );
4868  btnChangeColor2->setContext( QStringLiteral( "symbology" ) );
4869  btnChangeColor2->setShowNoColor( true );
4870  btnChangeColor2->setNoColorString( tr( "Transparent" ) );
4871 
4872  mStartColorDDBtn->registerLinkedWidget( btnChangeColor );
4873  mEndColorDDBtn->registerLinkedWidget( btnChangeColor2 );
4874 
4875  connect( btnChangeColor, &QgsColorButton::colorChanged, this, [ = ]( const QColor & color )
4876  {
4877  if ( mLayer )
4878  {
4879  mLayer->setColor( color );
4880  emit changed();
4881  }
4882  } );
4883  connect( btnChangeColor2, &QgsColorButton::colorChanged, this, [ = ]( const QColor & color )
4884  {
4885  if ( mLayer )
4886  {
4887  mLayer->setColor2( color );
4888  emit changed();
4889  }
4890  } );
4891  connect( btnColorRamp, &QgsColorRampButton::colorRampChanged, this, [ = ]
4892  {
4893  if ( btnColorRamp->isNull() )
4894  return;
4895 
4896  if ( mLayer )
4897  {
4898  mLayer->setColorRamp( btnColorRamp->colorRamp()->clone() );
4899  emit changed();
4900  }
4901  } );
4902 
4903  connect( radioTwoColor, &QAbstractButton::toggled, this, [ = ]
4904  {
4905  if ( mLayer )
4906  {
4907  if ( radioTwoColor->isChecked() )
4908  {
4909  mLayer->setGradientColorType( Qgis::GradientColorSource::SimpleTwoColor );
4910  btnChangeColor->setEnabled( true );
4911  btnChangeColor2->setEnabled( true );
4912  btnColorRamp->setEnabled( false );
4913  }
4914  else
4915  {
4916  mLayer->setGradientColorType( Qgis::GradientColorSource::ColorRamp );
4917  btnColorRamp->setEnabled( true );
4918  btnChangeColor->setEnabled( false );
4919  btnChangeColor2->setEnabled( false );
4920  }
4921  emit changed();
4922  }
4923  } );
4924 
4929 
4930  connect( mPenWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, [ = ]
4931  {
4932  if ( mLayer )
4933  {
4934  mLayer->setWidthUnit( mPenWidthUnitWidget->unit() );
4935  mLayer->setWidthMapUnitScale( mPenWidthUnitWidget->getMapUnitScale() );
4936  emit changed();
4937  }
4938  } );
4939 
4940  connect( spinWidth, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, [ = ]
4941  {
4942  if ( mLayer )
4943  {
4944  mLayer->setWidth( spinWidth->value() );
4945  emit changed();
4946  }
4947  } );
4948 
4949  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, [ = ]
4950  {
4951  if ( mLayer )
4952  {
4953  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
4954  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
4955  emit changed();
4956  }
4957  } );
4958 
4959  spinOffset->setClearValue( 0.0 );
4960  connect( spinOffset, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double val )
4961  {
4962  if ( mLayer )
4963  {
4964  mLayer->setOffset( val );
4965  emit changed();
4966  }
4967  } );
4968 
4969  connect( cboCapStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [ = ]
4970  {
4971  if ( mLayer )
4972  {
4973  mLayer->setPenCapStyle( cboCapStyle->penCapStyle() );
4974  emit changed();
4975  }
4976  } );
4977  connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [ = ]
4978  {
4979  if ( mLayer )
4980  {
4981  mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
4982  emit changed();
4983  }
4984  } );
4985 }
4986 
4988 {
4989  if ( !layer )
4990  {
4991  return;
4992  }
4993 
4994  if ( layer->layerType() != QLatin1String( "Lineburst" ) )
4995  {
4996  return;
4997  }
4998 
4999  mLayer = dynamic_cast<QgsLineburstSymbolLayer *>( layer );
5000  if ( !mLayer )
5001  {
5002  return;
5003  }
5004 
5005  btnChangeColor->blockSignals( true );
5006  btnChangeColor->setColor( mLayer->color() );
5007  btnChangeColor->blockSignals( false );
5008  btnChangeColor2->blockSignals( true );
5009  btnChangeColor2->setColor( mLayer->color2() );
5010  btnChangeColor2->blockSignals( false );
5011 
5013  {
5014  radioTwoColor->setChecked( true );
5015  btnColorRamp->setEnabled( false );
5016  }
5017  else
5018  {
5019  radioColorRamp->setChecked( true );
5020  btnChangeColor->setEnabled( false );
5021  btnChangeColor2->setEnabled( false );
5022  }
5023 
5024  // set source color ramp
5025  if ( mLayer->colorRamp() )
5026  {
5027  btnColorRamp->blockSignals( true );
5028  btnColorRamp->setColorRamp( mLayer->colorRamp() );
5029  btnColorRamp->blockSignals( false );
5030  }
5031 
5032  whileBlocking( spinWidth )->setValue( mLayer->width() );
5033  whileBlocking( mPenWidthUnitWidget )->setUnit( mLayer->widthUnit() );
5034  whileBlocking( mPenWidthUnitWidget )->setMapUnitScale( mLayer->widthMapUnitScale() );
5035 
5036  whileBlocking( mOffsetUnitWidget )->setUnit( mLayer->offsetUnit() );
5037  whileBlocking( mOffsetUnitWidget )->setMapUnitScale( mLayer->offsetMapUnitScale() );
5038  whileBlocking( spinOffset )->setValue( mLayer->offset() );
5039 
5040  whileBlocking( cboJoinStyle )->setPenJoinStyle( mLayer->penJoinStyle() );
5041  whileBlocking( cboCapStyle )->setPenCapStyle( mLayer->penCapStyle() );
5042 
5049 }
5050 
5052 {
5053  return mLayer;
5054 }
A widget for displaying characters available in a preset font, and allowing users to select an indivi...
void characterSelected(QChar character)
Emitted when a character is selected in the widget.
void setCharacter(QChar character)
Sets the currently selected character in the widget.
void setFont(const QFont &font)
Sets the font to show in the widget.
void clearCharacter()
Clears the currently selected character in the widget.
@ CurvePoint
Place symbols at every virtual curve point in the line (used when rendering curved geometry types onl...
@ InnerVertices
Inner vertices (i.e. all vertices except the first and last vertex) (since QGIS 3....
@ LastVertex
Place symbols on the last vertex in the line.
@ CentralPoint
Place symbols at the mid point of the line.
@ SegmentCenter
Place symbols at the center of every line segment.
@ Vertex
Place symbols on every vertex in the line.
@ Interval
Place symbols at regular intervals.
@ FirstVertex
Place symbols on the first vertex in the line.
MarkerClipMode
Marker clipping modes.
Definition: qgis.h:1176
@ CompletelyWithin
Render complete markers wherever the completely fall within the polygon shape.
@ NoClipping
No clipping, render complete markers.
@ Shape
Clip to polygon shape.
@ CentroidWithin
Render complete markers wherever their centroid falls within the polygon shape.
LineClipMode
Line clipping modes.
Definition: qgis.h:1190
@ NoClipping
Lines are not clipped, will extend to shape's bounding box.
@ ClipPainterOnly
Applying clipping on the painter only (i.e. line endpoints will coincide with polygon bounding box,...
@ ClipToIntersection
Clip lines to intersection with polygon shape (slower) (i.e. line endpoints will coincide with polygo...
@ ColorRamp
Gradient color ramp.
@ SimpleTwoColor
Simple two color gradient.
@ Repeat
Repeat gradient.
@ Reflect
Reflect gradient.
@ Pad
Pad out gradient using colors at endpoint of gradient.
PointCountMethod
Methods which define the number of points randomly filling a polygon.
Definition: qgis.h:1164
MarkerShape
Marker shapes.
Definition: qgis.h:1042
@ Linear
Linear gradient.
@ Conical
Conical (polar) gradient.
@ Radial
Radial (circular) gradient.
SymbolType
Symbol types.
Definition: qgis.h:183
@ Marker
Marker symbol.
@ Line
Line symbol.
@ Fill
Fill symbol.
@ Hybrid
Hybrid symbol.
SymbolCoordinateReference
Symbol coordinate reference modes.
Definition: qgis.h:1134
@ Feature
Relative to feature/shape being rendered.
@ Viewport
Relative to the whole viewport/output device.
static const double UI_SCALE_FACTOR
UI scaling factor.
Definition: qgis.h:1380
void setPenJoinStyle(Qt::PenJoinStyle style)
Sets the pen join style used to render the line (e.g.
Qt::PenCapStyle penCapStyle() const
Returns the pen cap style used to render the line (e.g.
Qt::PenJoinStyle penJoinStyle() const
Returns the pen join style used to render the line (e.g.
void setPenCapStyle(Qt::PenCapStyle style)
Sets the pen cap style used to render the line (e.g.
void sourceChanged(const QString &source)
Emitted whenever the file source is changed in the widget.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QgsImageCache * imageCache()
Returns the application's image cache, used for caching resampled versions of raster images.
static QgsSvgCache * svgCache()
Returns the application's SVG cache, used for caching SVG images and handling parameter replacement w...
static QString nameFromProperty(const QgsPropertyDefinition &def, bool joined=false)
Returns the name of the auxiliary field for a property definition.
bool exists(const QgsPropertyDefinition &definition) const
Returns true if the property is stored in the layer already, false otherwise.
QgsSymbolLayer * symbolLayer() override
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsCentroidFillSymbolLayer * mLayer
QgsCentroidFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsCentroidFillSymbolLayerWidget.
void setPointOnAllParts(bool pointOnAllParts)
Sets whether a point is drawn for all parts or only on the biggest part of multi-part features.
void setClipOnCurrentPartOnly(bool clipOnCurrentPartOnly)
Sets whether point markers should be clipped to the current part boundary only.
void setClipPoints(bool clipPoints)
Sets whether point markers should be clipped to the polygon boundary.
bool pointOnAllParts() const
Returns whether a point is drawn for all parts or only on the biggest part of multi-part features.
bool clipPoints() const
Returns true if point markers should be clipped to the polygon boundary.
bool clipOnCurrentPartOnly() const
Returns true if point markers should be clipped to the current part boundary only.
void setPointOnSurface(bool pointOnSurface)
void colorChanged(const QColor &color)
Emitted whenever a new color is set for the button.
void colorRampChanged()
Emitted whenever a new color ramp is set for the button.
Abstract base class for color ramps.
Definition: qgscolorramp.h:30
A dialog to enter a custom dash space pattern for lines.
A widget to enter a custom dash space pattern for lines.
QVector< qreal > dashDotVector() const
Returns the dash pattern as a list of numbers.
void setUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit type used for the dash space pattern (used to update interface labels)
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
static QgsExpressionContextScope * updateSymbolScope(const QgsSymbol *symbol, QgsExpressionContextScope *symbolScope=nullptr)
Updates a symbol scope related to a QgsSymbol to an expression context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
static const QString EXPR_GEOMETRY_PART_COUNT
Inbuilt variable name for geometry part count variable.
static const QString EXPR_GEOMETRY_POINT_COUNT
Inbuilt variable name for point count variable.
static const QString EXPR_CLUSTER_SIZE
Inbuilt variable name for cluster size variable.
static const QString EXPR_GEOMETRY_POINT_NUM
Inbuilt variable name for point number variable.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
static const QString EXPR_GEOMETRY_RING_NUM
Inbuilt variable name for geometry ring number variable.
static const QString EXPR_GEOMETRY_PART_NUM
Inbuilt variable name for geometry part number variable.
static const QString EXPR_SYMBOL_COLOR
Inbuilt variable name for symbol color variable.
QgsExpressionContextScope * lastScope()
Returns the last scope added to the context.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
bool hasVariable(const QString &name) const
Check whether a variable is specified by any scope within the context.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user.
static const QString EXPR_ORIGINAL_VALUE
Inbuilt variable name for value original value variable.
static const QString EXPR_CLUSTER_COLOR
Inbuilt variable name for cluster color variable.
void expressionChanged(const QString &expression)
Emitted when the expression is changed.
double angle() const
void setAngle(double angle)
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
Definition: qgsfillsymbol.h:30
QgsFilledMarkerSymbolLayer * mLayer
QgsSymbolLayer * symbolLayer() override
QgsFilledMarkerSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsFilledMarkerSymbolLayerWidget.
void setSymbolLayer(QgsSymbolLayer *layer) override
Filled marker symbol layer, consisting of a shape which is rendered using a QgsFillSymbol.
QgsFilledMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
QgsFontMarkerSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsFontMarkerSymbolLayerWidget.
void setCharacter(QChar chr)
Set the font marker character from char.
void setSymbolLayer(QgsSymbolLayer *layer) override
~QgsFontMarkerSymbolLayerWidget() override
QgsSymbolLayer * symbolLayer() override
QgsFontMarkerSymbolLayer * mLayer
void setCharacterFromText(const QString &text)
Set the font marker character from a text string.
void setColor(const QColor &color)
void setColorStroke(const QColor &color)
Set stroke color.
void setStrokeColor(const QColor &color) override
Sets the stroke color for the symbol layer.
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the stroke width map unit scale.
double strokeWidth() const
Returns the marker's stroke width.
void setFontStyle(const QString &style)
Sets the font style for the font which will be used to render the point.
QString fontStyle() const
Returns the font style for the associated font which will be used to render the point.
QColor strokeColor() const override
Returns the stroke color for the symbol layer.
QString fontFamily() const
Returns the font family name for the associated font which will be used to render the point.
void setCharacter(QString chr)
Sets the character(s) used when rendering points.
QgsUnitTypes::RenderUnit strokeWidthUnit() const
Returns the stroke width unit.
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the stroke width unit.
void setFontFamily(const QString &family)
Sets the font family for the font which will be used to render the point.
const QgsMapUnitScale & strokeWidthMapUnitScale() const
Returns the stroke width map unit scale.
void setStrokeWidth(double width)
Set's the marker's stroke width.
void setPenJoinStyle(Qt::PenJoinStyle style)
Sets the stroke join style.
QgsFontMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
Qt::PenJoinStyle penJoinStyle() const
Returns the stroke join style.
QString character() const
Returns the character(s) used when rendering points.
static QString translateNamedStyle(const QString &namedStyle)
Returns the localized named style of a font, if such a translation is available.
static QString untranslateNamedStyle(const QString &namedStyle)
Returns the english named style of a font, if possible.
static bool updateFontViaStyle(QFont &f, const QString &fontstyle, bool fallback=false)
Updates font with named style and retain all font properties.
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsGeometryGeneratorSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsGeometryGeneratorSymbolLayerWidget.
QString geometryExpression() const
Gets the expression to generate this geometry.
void setGeometryExpression(const QString &exp)
Set the expression to generate this geometry.
void setSymbolType(Qgis::SymbolType symbolType)
Set the type of symbol which should be created.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
Qgis::SymbolType symbolType() const
Access the symbol type.
void setUnits(QgsUnitTypes::RenderUnit units)
Sets the units for the geometry expression.
QgsUnitTypes::RenderUnit units() const
Returns the unit for the geometry expression.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsGradientFillSymbolLayer * mLayer
QgsSymbolLayer * symbolLayer() override
void applyColorRamp()
Applies the color ramp passed on by the color ramp button.
QgsGradientFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsGradientFillSymbolLayerWidget.
QgsColorRamp * colorRamp()
Returns the color ramp used for the gradient fill.
void setColorRamp(QgsColorRamp *ramp)
Sets the color ramp used for the gradient fill.
QColor color2() const
Returns the color for endpoint of gradient, only used if the gradient color type is set to SimpleTwoC...
void setGradientSpread(Qgis::GradientSpread gradientSpread)
Sets the gradient spread mode, which controls how the gradient behaves outside of the predefined stop...
Qgis::SymbolCoordinateReference coordinateMode() const
Returns the coordinate mode for gradient, which controls how the gradient stops are positioned.
void setOffsetUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the fill's offset.
bool referencePoint2IsCentroid() const
Returns whether the end point for the gradient is taken from the feature centroid.
void setGradientType(Qgis::GradientType gradientType)
Sets the type of gradient, e.g., linear or radial.
void setReferencePoint2(QPointF referencePoint)
Sets the end point of gradient fill, in the range [0,0] - [1,1].
void setCoordinateMode(Qgis::SymbolCoordinateReference coordinateMode)
Sets the coordinate mode for gradient, which controls how the gradient stops are positioned.
void setReferencePoint2IsCentroid(bool isCentroid)
Sets whether the end point for the gradient is taken from the feature centroid.
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units for the fill's offset.
void setReferencePoint1IsCentroid(bool isCentroid)
Sets whether the starting point for the gradient is taken from the feature centroid.
void setOffset(QPointF offset)
Sets an offset by which polygons will be translated during rendering.
void setGradientColorType(Qgis::GradientColorSource gradientColorType)
Sets the gradient color mode, which controls how gradient color stops are created.
QPointF referencePoint1() const
Returns the starting point of gradient fill, in the range [0,0] - [1,1].
Qgis::GradientSpread gradientSpread() const
Returns the gradient spread mode, which controls how the gradient behaves outside of the predefined s...
void setReferencePoint1(QPointF referencePoint)
Sets the starting point of gradient fill, in the range [0,0] - [1,1].
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the fill's offset.
Qgis::GradientColorSource gradientColorType() const
Returns the gradient color mode, which controls how gradient color stops are created.
QPointF offset() const
Returns the offset by which polygons will be translated during rendering.
const QgsMapUnitScale & offsetMapUnitScale() const
Returns the map unit scale for the fill's offset.
Qgis::GradientType gradientType() const
Returns the type of gradient, e.g., linear or radial.
bool referencePoint1IsCentroid() const
Returns whether the starting point for the gradient is taken from the feature centroid.
QPointF referencePoint2() const
Returns the end point of gradient fill, in the range [0,0] - [1,1].
void setColor2(const QColor &color2)
Sets the color for endpoint of gradient, only used if the gradient color type is set to SimpleTwoColo...
QgsHashedLineSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsHashedLineSymbolLayerWidget.
QgsSymbolLayer * symbolLayer() override
void setSymbolLayer(QgsSymbolLayer *layer) override
void setContext(const QgsSymbolWidgetContext &context) override
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
Line symbol layer type which draws repeating line sections along a line feature.
void setHashLength(double length)
Sets the length of hash symbols.
double hashAngle() const
Returns the angle to use when drawing the hashed lines sections, in degrees clockwise.
QgsUnitTypes::RenderUnit hashLengthUnit() const
Returns the units for the length of hash symbols.
const QgsMapUnitScale & hashLengthMapUnitScale() const
Returns the map unit scale for the hash length.
void setHashLengthUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the length of hash symbols.
void setHashLengthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the hash length.
double hashLength() const
Returns the length of hash symbols.
void setHashAngle(double angle)
Sets the angle to use when drawing the hashed lines sections, in degrees clockwise.
static QIcon iconLine()
Returns an icon representing line geometries.
static QIcon iconPolygon()
Returns an icon representing polygon geometries.
static QIcon iconPoint()
Returns an icon representing point geometries.
QImage pathAsImage(const QString &path, const QSize size, const bool keepAspectRatio, const double opacity, bool &fitsInCache, bool blocking=false, double targetDpi=96, bool *isMissing=nullptr)
Returns the specified path rendered as an image.
Qgis::SymbolCoordinateReference coordinateReference() const
Returns the coordinate reference mode for fill which controls how the top left corner of the image fi...
void setCoordinateReference(Qgis::SymbolCoordinateReference coordinateReference)
Sets the coordinate reference mode for fill which controls how the top left corner of the image fill ...
QgsLinePatternFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsLinePatternFillSymbolLayerWidget.
QgsLinePatternFillSymbolLayer * mLayer
void setSymbolLayer(QgsSymbolLayer *layer) override
A symbol fill consisting of repeated parallel lines.
const QgsMapUnitScale & offsetMapUnitScale() const
Returns the map unit scale for the pattern's line offset.
void setDistanceMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the pattern's line distance.
Qgis::LineClipMode clipMode() const
Returns the line clipping mode, which defines how lines are clipped at the edges of shapes.
double lineAngle() const
Returns the angle for the parallel lines used to fill the symbol.
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units for the line pattern's offset.
void setDistance(double d)
Sets the distance between lines in the fill pattern.
void setDistanceUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the distance between lines in the fill pattern.
void setClipMode(Qgis::LineClipMode mode)
Sets the line clipping mode, which defines how lines are clipped at the edges of shapes.
void setLineAngle(double a)
Sets the angle for the parallel lines used to fill the symbol.
double offset() const
Returns the offset distance for lines within the fill, which is the distance to offset the parallel l...
void setOffsetUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the line pattern's offset.
double distance() const
Returns the distance between lines in the fill pattern.
QgsUnitTypes::RenderUnit distanceUnit() const
Returns the units for the distance between lines in the fill pattern.
void setOffset(double offset)
Sets the offset distance for lines within the fill, which is the distance to offset the parallel line...
const QgsMapUnitScale & distanceMapUnitScale() const
Returns the map unit scale for the pattern's line distance.
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the pattern's line offset.
RenderRingFilter
Options for filtering rings when the line symbol layer is being used to render a polygon's rings.
@ ExteriorRingOnly
Render the exterior ring only.
@ InteriorRingsOnly
Render the interior rings only.
@ AllRings
Render both exterior and interior rings.
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units for the line's offset.
virtual void setWidth(double width)
Sets the width of the line symbol layer.
RenderRingFilter ringFilter() const
Returns the line symbol layer's ring filter, which controls which rings are rendered when the line sy...
const QgsMapUnitScale & offsetMapUnitScale() const
Returns the map unit scale for the line's offset.
void setWidthMapUnitScale(const QgsMapUnitScale &scale)
void setWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the line's width.
void setOffsetUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the line's offset.
void setOffset(double offset)
Sets the line's offset.
QgsUnitTypes::RenderUnit widthUnit() const
Returns the units for the line's width.
virtual double width() const
Returns the estimated width for the line symbol layer.
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the line's offset.
void setRingFilter(QgsLineSymbolLayer::RenderRingFilter filter)
Sets the line symbol layer's ring filter, which controls which rings are rendered when the line symbo...
double offset() const
Returns the line's offset.
const QgsMapUnitScale & widthMapUnitScale() const
A line symbol type, for rendering LineString and MultiLineString geometries.
Definition: qgslinesymbol.h:30
QgsLineburstSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsLineburstSymbolLayerWidget.
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsLineburstSymbolLayer * mLayer
QgsSymbolLayer * symbolLayer() override
Line symbol layer type which draws a gradient pattern perpendicularly along a line.
void setColorRamp(QgsColorRamp *ramp)
Sets the color ramp used for the gradient line.
QColor color2() const
Returns the color for endpoint of gradient, only used if the gradient color type is set to SimpleTwoC...
Qgis::GradientColorSource gradientColorType() const
Returns the gradient color mode, which controls how gradient color stops are created.
void setColor2(const QColor &color2)
Sets the color for endpoint of gradient, only used if the gradient color type is set to SimpleTwoColo...
QColor color() const override
Returns the "representative" color of the symbol layer.
QgsColorRamp * colorRamp()
Returns the color ramp used for the gradient line.
QgsMarkerLineSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsMarkerLineSymbolLayerWidget.
QgsMarkerLineSymbolLayer * mLayer
void setSymbolLayer(QgsSymbolLayer *layer) override
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
Line symbol layer type which draws repeating marker symbols along a line feature.
virtual void setSize(double size)
Sets the symbol size.
QPointF offset() const
Returns the marker's offset, which is the horizontal and vertical displacement which the rendered mar...
HorizontalAnchorPoint
Symbol horizontal anchor points.
void setAngle(double angle)
Sets the rotation angle for the marker.
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units for the symbol's size.
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the symbol's size.
void setVerticalAnchorPoint(VerticalAnchorPoint v)
Sets the vertical anchor point for positioning the symbol.
void setHorizontalAnchorPoint(HorizontalAnchorPoint h)
Sets the horizontal anchor point for positioning the symbol.
void setOffset(QPointF offset)
Sets the marker's offset, which is the horizontal and vertical displacement which the rendered marker...
void setSizeMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the symbol's size.
const QgsMapUnitScale & offsetMapUnitScale() const
Returns the map unit scale for the symbol's offset.
double size() const
Returns the symbol size.
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units for the symbol's offset.
VerticalAnchorPoint verticalAnchorPoint() const
Returns the vertical anchor point for positioning the symbol.
HorizontalAnchorPoint horizontalAnchorPoint() const
Returns the horizontal anchor point for positioning the symbol.
VerticalAnchorPoint
Symbol vertical anchor points.
void setOffsetUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the symbol's offset.
const QgsMapUnitScale & sizeMapUnitScale() const
Returns the map unit scale for the symbol's size.
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the symbol's offset.
double angle() const
Returns the rotation angle for the marker, in degrees clockwise from north.
A marker symbol type, for rendering Point and MultiPoint geometries.
A dialog to create a new auxiliary field.
A dialog to create a new auxiliary layer.
void opacityChanged(double opacity)
Emitted when the opacity is changed in the widget, where opacity ranges from 0.0 (transparent) to 1....
Base class for any widget that can be shown as a inline panel.
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
void widgetChanged()
Emitted when the widget state changes.
static QgsPanelWidget * findParentPanel(QWidget *widget)
Traces through the parents of a widget to find if it is contained within a QgsPanelWidget widget.
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
bool dockMode()
Returns the dock mode state.
QgsPointPatternFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsPointPatternFillSymbolLayerWidget.
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsPointPatternFillSymbolLayer * mLayer
A fill symbol layer which fills polygon shapes with repeating marker symbols.
void setDisplacementX(double d)
Sets the horizontal displacement for odd numbered rows in the pattern.
const QgsMapUnitScale & displacementYMapUnitScale() const
Returns the map unit scale for the vertical displacement between odd numbered columns in the pattern.
void setOffsetYUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the vertical offset for rows in the pattern.
void setRandomDeviationXUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the horizontal random deviation of points in the pattern.
void setOffsetX(double offset)
Sets the horizontal offset values for points in the pattern.
double maximumRandomDeviationY() const
Returns the maximum vertical random deviation of points in the pattern.
QgsUnitTypes::RenderUnit offsetYUnit() const
Returns the units for the vertical offset for rows in the pattern.
double distanceX() const
Returns the horizontal distance between rendered markers in the fill.
double displacementY() const
Returns the vertical displacement for odd numbered columns in the pattern.
void setRandomDeviationYMapUnitScale(const QgsMapUnitScale &scale)
Sets the unit scale for the vertical random deviation of points in the pattern.
const QgsMapUnitScale & offsetYMapUnitScale() const
Returns the unit scale for the vertical offset between rows in the pattern.
unsigned long seed() const
Returns the random number seed to use when randomly shifting points, or 0 if a truly random sequence ...
Qgis::MarkerClipMode clipMode() const
Returns the marker clipping mode, which defines how markers are clipped at the edges of shapes.
QgsUnitTypes::RenderUnit displacementYUnit() const
Returns the units for the vertical displacement between rows in the pattern.
void setRandomDeviationXMapUnitScale(const QgsMapUnitScale &scale)
Sets the unit scale for the horizontal random deviation of points in the pattern.
QgsUnitTypes::RenderUnit distanceYUnit() const
Returns the units for the vertical distance between points in the pattern.
QgsUnitTypes::RenderUnit randomDeviationYUnit() const
Returns the units for the vertical random deviation of points in the pattern.
double offsetY() const
Returns the vertical offset values for points in the pattern.
void setDisplacementY(double d)
Sets the vertical displacement for odd numbered columns in the pattern.
QgsUnitTypes::RenderUnit randomDeviationXUnit() const
Returns the units for the horizontal random deviation of points in the pattern.
const QgsMapUnitScale & distanceYMapUnitScale() const
Returns the map unit scale for the vertical distance between points in the pattern.
void setMaximumRandomDeviationX(double deviation)
Sets the maximum horizontal random deviation of points in the pattern.
void setDisplacementYMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the vertical displacement between odd numbered columns in the pattern.
void setSeed(unsigned long seed)
Sets the random number seed to use when randomly shifting points, or 0 if a truly random sequence wil...
void setOffsetY(double offset)
Sets the vertical offset values for points in the pattern.
QgsUnitTypes::RenderUnit offsetXUnit() const
Returns the units for the horizontal offset for rows in the pattern.
void setDistanceXUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the horizontal distance between points in the pattern.
void setDistanceXMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the horizontal distance between points in the pattern.
const QgsMapUnitScale & offsetXMapUnitScale() const
Returns the unit scale for the horizontal offset for rows in the pattern.
const QgsMapUnitScale & randomDeviationXMapUnitScale() const
Returns the unit scale for the horizontal random deviation of points in the pattern.
void setOffsetYMapUnitScale(const QgsMapUnitScale &scale)
Sets the unit scale for the vertical offset for rows in the pattern.
void setDistanceY(double d)
Sets the vertical distance between rendered markers in the fill.
void setDisplacementYUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the vertical displacement between rows in the pattern.
void setDistanceX(double d)
Sets the horizontal distance between rendered markers in the fill.
double offsetX() const
Returns the horizontal offset values for points in the pattern.
double maximumRandomDeviationX() const
Returns the maximum horizontal random deviation of points in the pattern.
const QgsMapUnitScale & randomDeviationYMapUnitScale() const
Returns the unit scale for the vertical random deviation of points in the pattern.
void setDisplacementXUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the horizontal displacement between rows in the pattern.
void setDisplacementXMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the horizontal displacement between odd numbered rows in the pattern.
void setMaximumRandomDeviationY(double deviation)
Sets the maximum vertical random deviation of points in the pattern.
void setDistanceYMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the vertical distance between points in the pattern.
void setRandomDeviationYUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the vertical random deviation of points in the pattern.
QgsUnitTypes::RenderUnit displacementXUnit() const
Returns the units for the horizontal displacement between rows in the pattern.
double displacementX() const
Returns the horizontal displacement for odd numbered rows in the pattern.
void setOffsetXMapUnitScale(const QgsMapUnitScale &scale)
Sets the unit scale for the horizontal offset for rows in the pattern.
double angle() const
Returns the rotation angle of the pattern, in degrees clockwise.
void setOffsetXUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the horizontal offset between rows in the pattern.
const QgsMapUnitScale & distanceXMapUnitScale() const
Returns the map unit scale for the horizontal distance between points in the pattern.
QgsUnitTypes::RenderUnit distanceXUnit() const
Returns the units for the horizontal distance between points in the pattern.
void setDistanceYUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the vertical distance between points in the pattern.
void setAngle(double angle)
Sets the rotation angle of the pattern, in degrees clockwise.
double distanceY() const
Returns the vertical distance between rendered markers in the fill.
void setClipMode(Qgis::MarkerClipMode mode)
Sets the marker clipping mode, which defines how markers are clipped at the edges of shapes.
const QgsMapUnitScale & displacementXMapUnitScale() const
Returns the map unit scale for the horizontal displacement between odd numbered rows in the pattern.
QgsProperty property(int key) const override
Returns a matching property from the collection, if one exists.
Definition for a property.
Definition: qgsproperty.h:47
A button for controlling property overrides which may apply to a widget.
QgsProperty toProperty() const
Returns a QgsProperty object encapsulating the current state of the widget.
void updateFieldLists()
Updates list of fields.
void changed()
Emitted when property definition changes.
void init(int propertyKey, const QgsProperty &property, const QgsPropertiesDefinition &definitions, const QgsVectorLayer *layer=nullptr, bool auxiliaryStorageEnabled=false)
Initialize a newly constructed property button (useful if button was included in a UI layout).
void registerExpressionContextGenerator(QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
int propertyKey() const
Returns the property key linked to the button.
void setToProperty(const QgsProperty &property)
Sets the widget to reflect the current state of a QgsProperty.
void createAuxiliaryField()
Emitted when creating a new auxiliary field.
A store for object properties.
Definition: qgsproperty.h:231
void setField(const QString &field)
Sets the field name the property references.
QgsRandomMarkerFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsRandomMarkerFillSymbolLayerWidget.
void setSymbolLayer(QgsSymbolLayer *layer) override
A fill symbol layer which places markers at random locations within polygons.
QgsUnitTypes::RenderUnit densityAreaUnit() const
Returns the units for the density area.
int pointCount() const
Returns the count of random points to render in the fill.
unsigned long seed() const
Returns the random number seed to use when generating points, or 0 if a truly random sequence will be...
void setDensityAreaUnitScale(const QgsMapUnitScale &scale)
Sets the map scale for the density area.
void setDensityAreaUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the density area.
void setCountMethod(Qgis::PointCountMethod method)
Sets the count method used to randomly fill the polygon.
bool clipPoints() const
Returns true if point markers should be clipped to the polygon boundary.
void setClipPoints(bool clipped)
Sets whether point markers should be clipped to the polygon boundary.
void setSeed(unsigned long seed)
Sets the random number seed to use when generating points, or 0 if a truly random sequence will be us...
const QgsMapUnitScale & densityAreaUnitScale() const
Returns the map scale for the density area.
void setPointCount(int count)
Sets the count of random points to render in the fill.
Qgis::PointCountMethod countMethod() const
Returns the count method used to randomly fill the polygon.
double densityArea() const
Returns the density area used to count the number of points to randomly fill the polygon.
void setDensityArea(double area)
Sets the density area used to count the number of points to randomly fill the polygon.
QgsRasterFillSymbolLayer * mLayer
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsSymbolLayer * symbolLayer() override
QgsRasterFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsRasterFillSymbolLayerWidget.
A class for filling symbols with a repeated raster image.
double width() const
Returns the width used for scaling the image used in the fill.
void setWidthUnit(const QgsUnitTypes::RenderUnit unit)
Sets the units for the image's width.
void setOffsetUnit(const QgsUnitTypes::RenderUnit unit)
Sets the units for the fill's offset.
Qgis::SymbolCoordinateReference coordinateMode() const
Coordinate mode for fill.
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units for the fill's offset.
QgsUnitTypes::RenderUnit widthUnit() const
Returns the units for the image's width.
void setWidth(const double width)
Sets the width for scaling the image used in the fill.
double opacity() const
Returns the opacity for the raster image used in the fill.
const QgsMapUnitScale & widthMapUnitScale() const
Returns the map unit scale for the image's width.
void setOpacity(double opacity)
Sets the opacity for the raster image used in the fill.
void setWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the image's width.
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the fill's offset.
QString imageFilePath() const
The path to the raster image used for the fill.
const QgsMapUnitScale & offsetMapUnitScale() const
Returns the map unit scale for the fill's offset.
void setImageFilePath(const QString &imagePath)
Sets the path to the raster image used for the fill.
QPointF offset() const
Returns the offset for the fill.
void setOffset(QPointF offset)
Sets the offset for the fill.
void setCoordinateMode(Qgis::SymbolCoordinateReference mode)
Set the coordinate mode for fill.
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsSymbolLayer * symbolLayer() override
QgsRasterLineSymbolLayer * mLayer
QgsRasterLineSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsRasterLineSymbolLayerWidget.
Line symbol layer type which draws line sections using a raster image file.
double opacity() const
Returns the line opacity.
QString path() const
Returns the raster image path.
void setPath(const QString &path)
Set the raster image path.
void setOpacity(double opacity)
Set the line opacity.
QgsRasterMarkerSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsRasterMarkerSymbolLayerWidget.
QgsRasterMarkerSymbolLayer * mLayer
void setSymbolLayer(QgsSymbolLayer *layer) override
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
Raster marker symbol layer class.
void setOpacity(double opacity)
Set the marker opacity.
QString path() const
Returns the marker raster image path.
void setPath(const QString &path)
Set the marker raster image path.
double defaultAspectRatio() const
Returns the default marker aspect ratio between width and height, 0 if not yet calculated.
void setFixedAspectRatio(double ratio)
Set the marker aspect ratio between width and height to be used in rendering, if the value set is low...
bool preservedAspectRatio() const
Returns the preserved aspect ratio value, true if fixed aspect ratio has been lower or equal to 0.
double fixedAspectRatio() const
Returns the marker aspect ratio between width and height to be used in rendering, if the value set is...
double opacity() const
Returns the marker opacity.
A cross platform button subclass used to represent a locked / unlocked ratio state.
void lockChanged(bool locked)
Emitted whenever the lock state changes.
QgsSymbolLayer * symbolLayer() override
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsSVGFillSymbolLayer * mLayer
void updateParamGui(bool resetValues=true)
Enables or disables svg fill color, stroke color and stroke width based on whether the svg file suppo...
QgsSVGFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsSVGFillSymbolLayerWidget.
void setContext(const QgsSymbolWidgetContext &context) override
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
A class for filling symbols with a repeated SVG file.
void setParameters(const QMap< QString, QgsProperty > &parameters)
Sets the dynamic SVG parameters.
QString svgFilePath() const
Returns the path to the SVG file used to render the fill.
void setSvgStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the pattern's stroke.
void setPatternWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the width of the SVG images in the pattern.
QColor svgStrokeColor() const
Returns the stroke color used for rendering the SVG content.
const QgsMapUnitScale & svgStrokeWidthMapUnitScale() const
Returns the map unit scale for the pattern's stroke.
void setSvgFillColor(const QColor &c)
Sets the fill color used for rendering the SVG content.
QgsUnitTypes::RenderUnit svgStrokeWidthUnit() const
Returns the units for the stroke width.
double svgStrokeWidth() const
Returns the stroke width used for rendering the SVG content.
void setSvgStrokeWidth(double w)
Sets the stroke width used for rendering the SVG content.
void setSvgFilePath(const QString &svgPath)
Sets the path to the SVG file to render in the fill.
QColor svgFillColor() const
Returns the fill color used for rendering the SVG content.
const QgsMapUnitScale & patternWidthMapUnitScale() const
Returns the map unit scale for the pattern's width.
void setSvgStrokeColor(const QColor &c)
Sets the stroke color used for rendering the SVG content.
void setSvgStrokeWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the stroke width.
void setPatternWidth(double width)
Sets the width to render the SVG content as within the fill (i.e.
double patternWidth() const
Returns the width of the rendered SVG content within the fill (i.e.
QgsUnitTypes::RenderUnit patternWidthUnit() const
Returns the units for the width of the SVG images in the pattern.
void setPatternWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the pattern's width.
QgsShapeburstFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsShapeburstFillSymbolLayerWidget.
QgsShapeburstFillSymbolLayer * mLayer
QgsSymbolLayer * symbolLayer() override
void setSymbolLayer(QgsSymbolLayer *layer) override
int blurRadius() const
Returns the blur radius, which controls the amount of blurring applied to the fill.
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
QgsColorRamp * colorRamp()
Returns the color ramp used for the shapeburst fill.
void setOffset(QPointF offset)
Sets the offset for the shapeburst fill.
const QgsMapUnitScale & distanceMapUnitScale() const
void setBlurRadius(int blurRadius)
Sets the blur radius, which controls the amount of blurring applied to the fill.
void setUseWholeShape(bool useWholeShape)
Sets whether the shapeburst fill should be drawn using the entire shape.
QColor color2() const
Returns the color used for the endpoint of the shapeburst fill.
void setDistanceUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the maximum distance to shade inside of the shape from the polygon's boundary.
QgsUnitTypes::RenderUnit distanceUnit() const
Returns the unit for the maximum distance to shade inside of the shape from the polygon's boundary.
void setIgnoreRings(bool ignoreRings)
Sets whether the shapeburst fill should ignore polygon rings when calculating the buffered shading.
void setMaxDistance(double maxDistance)
Sets the maximum distance to shape inside of the shape from the polygon's boundary.
void setColor2(const QColor &color2)
Sets the color for the endpoint of the shapeburst fill.
const QgsMapUnitScale & offsetMapUnitScale() const
QPointF offset() const
Returns the offset for the shapeburst fill.
bool useWholeShape() const
Returns whether the shapeburst fill is set to cover the entire shape.
bool ignoreRings() const
Returns whether the shapeburst fill is set to ignore polygon interior rings.
double maxDistance() const
Returns the maximum distance from the shape's boundary which is shaded.
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units used for the offset of the shapeburst fill.
void setDistanceMapUnitScale(const QgsMapUnitScale &scale)
void setOffsetUnit(QgsUnitTypes::RenderUnit unit)
Sets the units used for the offset for the shapeburst fill.
void setColorType(Qgis::GradientColorSource colorType)
Sets the color mode to use for the shapeburst fill.
Qgis::GradientColorSource colorType() const
Returns the color mode used for the shapeburst fill.
void setColorRamp(QgsColorRamp *ramp)
Sets the color ramp used to draw the shapeburst fill.
void setColor(const QColor &color)
QgsSimpleFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsSimpleFillSymbolLayerWidget.
void setStrokeColor(const QColor &color)
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsSimpleFillSymbolLayer * mLayer
QgsSymbolLayer * symbolLayer() override
Qt::PenJoinStyle penJoinStyle() const
QColor strokeColor() const override
Returns the stroke color for the symbol layer.
void setBrushStyle(Qt::BrushStyle style)
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
const QgsMapUnitScale & offsetMapUnitScale() const
Returns the map unit scale for the fill's offset.
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the fill's offset.
QgsUnitTypes::RenderUnit strokeWidthUnit() const
Returns the units for the width of the fill's stroke.
void setPenJoinStyle(Qt::PenJoinStyle style)
Qt::PenStyle strokeStyle() const
void setStrokeWidth(double strokeWidth)
void setStrokeStyle(Qt::PenStyle strokeStyle)
const QgsMapUnitScale & strokeWidthMapUnitScale() const
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units for the fill's offset.
QPointF offset()
Returns the offset by which polygons will be translated during rendering.
void setOffset(QPointF offset)
Sets an offset by which polygons will be translated during rendering.
void setStrokeColor(const QColor &strokeColor) override
Sets the stroke color for the symbol layer.
void setOffsetUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the fill's offset.
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the width of the fill's stroke.
Qt::BrushStyle brushStyle() const
void setContext(const QgsSymbolWidgetContext &context) override
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
~QgsSimpleLineSymbolLayerWidget() override
QgsSimpleLineSymbolLayer * mLayer
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsSymbolLayer * symbolLayer() override
QgsSimpleLineSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsSimpleLineSymbolLayerWidget.
void resizeEvent(QResizeEvent *event) override
A simple line symbol layer, which renders lines using a line in a variety of styles (e....
QgsUnitTypes::RenderUnit dashPatternOffsetUnit() const
Returns the units for the dash pattern offset.
void setDrawInsidePolygon(bool drawInsidePolygon)
Sets whether the line should only be drawn inside polygons, and any portion of the line which falls o...
bool tweakDashPatternOnCorners() const
Returns true if dash patterns tweaks should be applied on sharp corners, to ensure that a double-leng...
void setPenCapStyle(Qt::PenCapStyle style)
Sets the pen cap style used to render the line (e.g.
const QgsMapUnitScale & trimDistanceStartMapUnitScale() const
Returns the map unit scale for the trim distance for the start of the line.
Qt::PenJoinStyle penJoinStyle() const
Returns the pen join style used to render the line (e.g.
void setDashPatternOffsetUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the dash pattern offset.
QgsUnitTypes::RenderUnit trimDistanceStartUnit() const
Returns the unit for the trim distance for the start of the line.
void setCustomDashPatternMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for lengths used in the custom dash pattern.
QgsUnitTypes::RenderUnit customDashPatternUnit() const
Returns the units for lengths used in the custom dash pattern.
void setTrimDistanceEndMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the trim distance for the end of the line.
QVector< qreal > customDashVector() const
Returns the custom dash vector, which is the pattern of alternating drawn/skipped lengths used while ...
void setTrimDistanceEnd(double distance)
Sets the trim distance for the end of the line, which dictates a length from the end of the line at w...
void setCustomDashPatternUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for lengths used in the custom dash pattern.
double trimDistanceStart() const
Returns the trim distance for the start of the line, which dictates a length from the start of the li...
void setUseCustomDashPattern(bool b)
Sets whether the line uses a custom dash pattern.
void setTweakDashPatternOnCorners(bool enabled)
Sets whether dash patterns tweaks should be applied on sharp corners, to ensure that a double-length ...
double trimDistanceEnd() const
Returns the trim distance for the end of the line, which dictates a length from the end of the line a...
void setCustomDashVector(const QVector< qreal > &vector)
Sets the custom dash vector, which is the pattern of alternating drawn/skipped lengths used while ren...
bool useCustomDashPattern() const
Returns true if the line uses a custom dash pattern.
QgsUnitTypes::RenderUnit trimDistanceEndUnit() const
Returns the unit for the trim distance for the end of the line.
void setDashPatternOffset(double offset)
Sets the dash pattern offset, which dictates how far along the dash pattern the pattern should start ...
const QgsMapUnitScale & dashPatternOffsetMapUnitScale() const
Returns the map unit scale for the dash pattern offset value.
void setDashPatternOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the dash pattern offset.
QgsSimpleLineSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
void setPenStyle(Qt::PenStyle style)
Sets the pen style used to render the line (e.g.
Qt::PenStyle penStyle() const
Returns the pen style used to render the line (e.g.
void setPenJoinStyle(Qt::PenJoinStyle style)
Sets the pen join style used to render the line (e.g.
double dashPatternOffset() const
Returns the dash pattern offset, which dictates how far along the dash pattern the pattern should sta...
void setAlignDashPattern(bool enabled)
Sets whether dash patterns should be aligned to the start and end of lines, by applying subtle tweaks...
void setTrimDistanceStartUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the trim distance for the start of the line.
void setTrimDistanceStartMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the trim distance for the start of the line.
void setTrimDistanceEndUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the trim distance for the end of the line.
Qt::PenCapStyle penCapStyle() const
Returns the pen cap style used to render the line (e.g.
const QgsMapUnitScale & trimDistanceEndMapUnitScale() const
Returns the map unit scale for the trim distance for the end of the line.
const QgsMapUnitScale & customDashPatternMapUnitScale() const
Returns the map unit scale for lengths used in the custom dash pattern.
bool drawInsidePolygon() const
Returns true if the line should only be drawn inside polygons, and any portion of the line which fall...
void setMapUnitScale(const QgsMapUnitScale &scale) override
void setTrimDistanceStart(double distance)
Sets the trim distance for the start of the line, which dictates a length from the start of the line ...
bool alignDashPattern() const
Returns true if dash patterns should be aligned to the start and end of lines, by applying subtle twe...
static QList< Qgis::MarkerShape > availableShapes()
Returns a list of all available shape types.
static bool shapeIsFilled(Qgis::MarkerShape shape)
Returns true if a symbol shape has a fill.
Qgis::MarkerShape shape() const
Returns the shape for the rendered marker symbol.
static QString encodeShape(Qgis::MarkerShape shape)
Encodes a shape to its string representation.
void setShape(Qgis::MarkerShape shape)
Sets the rendered marker shape.
QgsSymbolLayer * symbolLayer() override
void setColorStroke(const QColor &color)
void setColorFill(const QColor &color)
QgsSimpleMarkerSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsSimpleMarkerSymbolLayerWidget.
QgsSimpleMarkerSymbolLayer * mLayer
void setSymbolLayer(QgsSymbolLayer *layer) override
Simple marker symbol layer, consisting of a rendered shape with solid fill color and an stroke.
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit u)
Sets the unit for the width of the marker's stroke.
void setColor(const QColor &color) override
Sets the "representative" color for the symbol layer.
Qt::PenJoinStyle penJoinStyle() const
Returns the marker's stroke join style (e.g., miter, bevel, etc).
QgsSimpleMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
Qt::PenCapStyle penCapStyle() const
Returns the marker's stroke cap style (e.g., flat, round, etc).
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map scale for the width of the marker's stroke.
void setStrokeStyle(Qt::PenStyle strokeStyle)
Sets the marker's stroke style (e.g., solid, dashed, etc)
const QgsMapUnitScale & strokeWidthMapUnitScale() const
Returns the map scale for the width of the marker's stroke.
QColor fillColor() const override
Returns the fill color for the symbol layer.
QgsUnitTypes::RenderUnit strokeWidthUnit() const
Returns the unit for the width of the marker's stroke.
void setPenJoinStyle(Qt::PenJoinStyle style)
Sets the marker's stroke join style (e.g., miter, bevel, etc).
QColor strokeColor() const override
Returns the marker's stroke color.
void setStrokeWidth(double w)
Sets the width of the marker's stroke.
void setStrokeColor(const QColor &color) override
Sets the marker's stroke color.
Qt::PenStyle strokeStyle() const
Returns the marker's stroke style (e.g., solid, dashed, etc)
void setPenCapStyle(Qt::PenCapStyle style)
Sets the marker's stroke cap style (e.g., flat, round, etc).
double strokeWidth() const
Returns the width of the marker's stroke.
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.
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 setSymbolLayer(QgsSymbolLayer *layer) override
void setGuiForSvg(const QgsSvgMarkerSymbolLayer *layer, bool skipDefaultColors=false)
Updates the GUI to reflect the SVG marker symbol layer.
void setSvgPath(const QString &name)
Sets the SVG path.
QgsSvgMarkerSymbolLayer * mLayer
QgsSvgMarkerSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsSvgMarkerSymbolLayerWidget.
void setSvgParameters(const QMap< QString, QgsProperty > &parameters)
Sets the dynamic SVG parameters.
~QgsSvgMarkerSymbolLayerWidget() override
QgsSvgMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
QColor fillColor() const override
Returns the fill color for the symbol layer.
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
QString path() const
Returns the marker SVG path.
bool preservedAspectRatio() const
Returns the preserved aspect ratio value, true if fixed aspect ratio has been lower or equal to 0.
QgsUnitTypes::RenderUnit strokeWidthUnit() const
Returns the units for the stroke width.
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the stroke width.
const QgsMapUnitScale & strokeWidthMapUnitScale() const
double fixedAspectRatio() const
Returns the marker aspect ratio between width and height to be used in rendering, if the value set is...
void setStrokeColor(const QColor &c) override
Sets the stroke color for the symbol layer.
void setMapUnitScale(const QgsMapUnitScale &scale) override
QColor strokeColor() const override
Returns the stroke color for the symbol layer.
void setFillColor(const QColor &color) override
Sets the fill color for the symbol layer.
QMap< QString, QgsProperty > parameters() const
Returns the dynamic SVG parameters.
void setParameters(const QMap< QString, QgsProperty > &parameters)
Sets the dynamic SVG parameters.
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 setPath(const QString &path)
Set the marker SVG path.
double defaultAspectRatio() const
Returns the default marker aspect ratio between width and height, 0 if not yet calculated.
void svgParametersChanged(const QMap< QString, QgsProperty > &parameters)
Emitted when the parameters have changed.
void svgSelected(const QString &path)
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.
static QIcon symbolPreviewIcon(const QgsSymbol *symbol, QSize size, int padding=0, QgsLegendPatchShape *shape=nullptr)
Returns an icon preview for a color ramp.
static QIcon symbolLayerPreviewIcon(const QgsSymbolLayer *layer, QgsUnitTypes::RenderUnit u, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::SymbolType parentSymbolType=Qgis::SymbolType::Hybrid)
Draws a symbol layer preview to an icon.
void registerDataDefinedButton(QgsPropertyOverrideButton *button, QgsSymbolLayer::Property key)
Registers a data defined override button.
void changed()
Should be emitted whenever configuration changes happened on this symbol layer configuration.
const QgsVectorLayer * vectorLayer() const
Returns the vector layer associated with the widget.
virtual QgsSymbolLayer * symbolLayer()=0
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
void symbolChanged()
Should be emitted whenever the sub symbol changed on this symbol layer configuration.
virtual void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
QgsSymbolWidgetContext context() const
Returns the context in which the symbol widget is shown, e.g., the associated map canvas and expressi...
Property
Data definable properties.
@ PropertyGradientReference1X
Gradient reference point 1 x.
@ PropertyShapeburstIgnoreRings
Shapeburst ignore rings.
@ PropertyGradientReference2X
Gradient reference point 2 x.
@ PropertyStrokeStyle
Stroke style (eg solid, dashed)
@ PropertyPlacement
Line marker placement.
@ PropertyHorizontalAnchor
Horizontal anchor point.
@ PropertyDistanceX
Horizontal distance between points.
@ PropertyFile
Filename, eg for svg files.
@ PropertyGradientType
Gradient fill type.
@ PropertyCapStyle
Line cap style.
@ PropertyAngle
Symbol angle.
@ PropertyLineClipping
Line clipping mode (since QGIS 3.24)
@ PropertyDistanceY
Vertical distance between points.
@ PropertyDisplacementX
Horizontal displacement.
@ PropertyVerticalAnchor
Vertical anchor point.
@ PropertyGradientSpread
Gradient spread mode.
@ PropertyOffsetY
Vertical offset.
@ PropertyGradientReference1Y
Gradient reference point 1 y.
@ PropertyLineDistance
Distance between lines, or length of lines for hash line symbols.
@ PropertyOffsetAlongLine
Offset along line.
@ PropertyBlurRadius
Shapeburst blur radius.
@ PropertyGradientReference2Y
Gradient reference point 2 y.
@ PropertyMarkerClipping
Marker clipping mode (since QGIS 3.24)
@ PropertyDensityArea
Density area.
@ PropertyGradientReference1IsCentroid
Gradient reference point 1 is centroid.
@ PropertyCustomDash
Custom dash pattern.
@ PropertyShapeburstUseWholeShape
Shapeburst use whole shape.
@ PropertySize
Symbol size.
@ PropertyOffsetX
Horizontal offset.
@ PropertyJoinStyle
Line join style.
@ PropertyTrimEnd
Trim distance from end of line (since QGIS 3.20)
@ PropertyOpacity
Opacity.
@ PropertySecondaryColor
Secondary color (eg for gradient fills)
@ PropertyCharacter
Character, eg for font marker symbol layers.
@ PropertyCoordinateMode
Gradient coordinate mode.
@ PropertyRandomOffsetY
Random offset Y (since QGIS 3.24)
@ PropertyLineAngle
Line angle, or angle of hash lines for hash line symbols.
@ PropertyShapeburstMaxDistance
Shapeburst fill from edge distance.
@ PropertyTrimStart
Trim distance from start of line (since QGIS 3.20)
@ PropertyOffset
Symbol offset.
@ PropertyStrokeWidth
Stroke width.
@ PropertyDashPatternOffset
Dash pattern offset,.
@ PropertyFillColor
Fill color.
@ PropertyFontStyle
Font style.
@ PropertyHeight
Symbol height.
@ PropertyClipPoints
Whether markers should be clipped to polygon boundaries.
@ PropertyFontFamily
Font family.
@ PropertyPointCount
Point count.
@ PropertyRandomSeed
Random number seed.
@ PropertyName
Name, eg shape name for simple markers.
@ PropertyAverageAngleLength
Length to average symbol angles over.
@ PropertyInterval
Line marker interval.
@ PropertyRandomOffsetX
Random offset X (since QGIS 3.24)
@ PropertyFillStyle
Fill style (eg solid, dots)
@ PropertyDisplacementY
Vertical displacement.
@ PropertyStrokeColor
Stroke color.
@ PropertyGradientReference2IsCentroid
Gradient reference point 2 is centroid.
@ PropertyWidth
Symbol width.
virtual QString layerType() const =0
Returns a string that represents this layer type.
virtual void setDataDefinedProperty(Property key, const QgsProperty &property)
Sets a data defined property for the layer.
virtual void setColor(const QColor &color)
Sets the "representative" color for the symbol layer.
virtual QColor color() const
Returns the "representative" color of the symbol layer.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the symbol layer property definitions.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides.
Contains settings which reflect the context in which a symbol (or renderer) widget is shown,...
QList< QgsExpressionContextScope > additionalExpressionContextScopes() const
Returns the list of additional expression context scopes to show as available within the layer.
QList< QgsExpressionContextScope * > globalProjectAtlasMapLayerScopes(const QgsMapLayer *layer) const
Returns list of scopes: global, project, atlas, map, layer.
QgsExpressionContext * expressionContext() const
Returns the expression context used for the widget, if set.
QgsMapCanvas * mapCanvas() const
Returns the map canvas associated with the widget.
Qgis::SymbolType symbolType() const
Returns the associated symbol type, if the widget is being shown as a subcomponent of a parent symbol...
QgsMessageBar * messageBar() const
Returns the message bar associated with the widget.
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
bool rotateSymbols() const
Returns true if the repeating symbols be rotated to match their line segment orientation.
bool placeOnEveryPart() const
Returns true if the placement applies for every part of multi-part feature geometries.
double averageAngleLength() const
Returns the length of line over which the line's direction is averaged when calculating individual sy...
const QgsMapUnitScale & intervalMapUnitScale() const
Returns the map unit scale for the interval between symbols.
void setRotateSymbols(bool rotate)
Sets whether the repeating symbols should be rotated to match their line segment orientation.
const QgsMapUnitScale & averageAngleMapUnitScale() const
Returns the map unit scale for the length over which the line's direction is averaged when calculatin...
double interval() const
Returns the interval between individual symbols.
void setAverageAngleMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the length over which the line's direction is averaged when calculating i...
double offsetAlongLine() const
Returns the offset along the line for the symbol placement.
Qgis::MarkerLinePlacements placements() const
Returns the placement of the symbols.
void setOffsetAlongLine(double offsetAlongLine)
Sets the the offset along the line for the symbol placement.
void setOffsetAlongLineUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit used for calculating the offset along line for symbols.
void setInterval(double interval)
Sets the interval between individual symbols.
const QgsMapUnitScale & offsetAlongLineMapUnitScale() const
Returns the map unit scale used for calculating the offset in map units along line for symbols.
QgsUnitTypes::RenderUnit averageAngleUnit() const
Returns the unit for the length over which the line's direction is averaged when calculating individu...
void setPlaceOnEveryPart(bool respect)
Sets whether the placement applies for every part of multi-part feature geometries.
QgsUnitTypes::RenderUnit offsetAlongLineUnit() const
Returns the unit used for calculating the offset along line for symbols.
void setPlacements(Qgis::MarkerLinePlacements placements)
Sets the placement of the symbols.
QgsUnitTypes::RenderUnit intervalUnit() const
Returns the units for the interval between symbols.
void setAverageAngleUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the length over which the line's direction is averaged when calculating individual ...
void setIntervalUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the interval between symbols.
void setIntervalMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the interval between symbols.
void setOffsetAlongLineMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale used for calculating the offset in map units along line for symbols.
void setAverageAngleLength(double length)
Sets the length of line over which the line's direction is averaged when calculating individual symbo...
A widget displaying a combobox allowing the user to choose between various display units,...
QList< QgsUnitTypes::RenderUnit > RenderUnitList
List of render units.
Definition: qgsunittypes.h:240
@ RenderMetersInMapUnits
Meters value as Map units.
Definition: qgsunittypes.h:176
@ RenderPercentage
Percentage of another measurement (e.g., canvas size, feature size)
Definition: qgsunittypes.h:172
@ RenderPoints
Points (e.g., for font sizes)
Definition: qgsunittypes.h:173
@ RenderPixels
Pixels.
Definition: qgsunittypes.h:171
@ RenderInches
Inches.
Definition: qgsunittypes.h:174
@ RenderMillimeters
Millimeters.
Definition: qgsunittypes.h:169
@ RenderMapUnits
Map units.
Definition: qgsunittypes.h:170
Represents a vector layer which manages a vector based data sets.
QgsAuxiliaryLayer * auxiliaryLayer()
Returns the current auxiliary layer.
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
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:1517
QList< QgsSymbolLayer * > QgsSymbolLayerList
Definition: qgssymbol.h:27
Single variable definition for use within a QgsExpressionContextScope.