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