QGIS API Documentation  3.8.0-Zanzibar (11aff65)
qgssymbollayerwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgssymbollayerwidget.cpp - symbol layer widgets
3 
4  ---------------------
5  begin : November 2009
6  copyright : (C) 2009 by Martin Dobias
7  email : wonder dot sk at gmail dot com
8  ***************************************************************************
9  * *
10  * This program is free software; you can redistribute it and/or modify *
11  * it under the terms of the GNU General Public License as published by *
12  * the Free Software Foundation; either version 2 of the License, or *
13  * (at your option) any later version. *
14  * *
15  ***************************************************************************/
16 
17 #include "qgssymbollayerwidget.h"
18 
19 #include "qgslinesymbollayer.h"
20 #include "qgsmarkersymbollayer.h"
21 #include "qgsfillsymbollayer.h"
23 #include "qgssymbolslistwidget.h"
25 
26 #include "characterwidget.h"
27 #include "qgsdashspacedialog.h"
29 #include "qgssvgcache.h"
30 #include "qgssymbollayerutils.h"
31 #include "qgscolorramp.h"
32 #include "qgscolorrampbutton.h"
34 #include "qgsproperty.h"
35 #include "qgsstyle.h" //for symbol selector dialog
36 #include "qgsmapcanvas.h"
37 #include "qgsapplication.h"
38 #include "qgsvectorlayer.h"
39 #include "qgssvgselectorwidget.h"
40 #include "qgslogger.h"
41 #include "qgssettings.h"
44 #include "qgsauxiliarystorage.h"
45 #include "qgsimagecache.h"
46 
47 #include <QAbstractButton>
48 #include <QButtonGroup>
49 #include <QColorDialog>
50 #include <QCursor>
51 #include <QDir>
52 #include <QFileDialog>
53 #include <QPainter>
54 #include <QStandardItemModel>
55 #include <QSvgRenderer>
56 #include <QMessageBox>
57 #include <QMenu>
58 #include <QAction>
59 #include <QInputDialog>
60 
62 {
63  if ( mContext.expressionContext() )
64  return *mContext.expressionContext();
65 
67 
69  if ( const QgsSymbolLayer *symbolLayer = const_cast< QgsSymbolLayerWidget * >( this )->symbolLayer() )
70  {
71  //cheat a bit - set the symbol color variable to match the symbol layer's color (when we should really be using the *symbols*
72  //color, but that's not accessible here). 99% of the time these will be the same anyway
74  }
75  expContext << symbolScope;
76  expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_COUNT, 1, true ) );
77  expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, 1, true ) );
78  expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_POINT_COUNT, 1, true ) );
79  expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_POINT_NUM, 1, true ) );
80 
81  // additional scopes
82  const auto constAdditionalExpressionContextScopes = mContext.additionalExpressionContextScopes();
83  for ( const QgsExpressionContextScope &scope : constAdditionalExpressionContextScopes )
84  {
85  expContext.appendScope( new QgsExpressionContextScope( scope ) );
86  }
87 
88  //TODO - show actual value
89  expContext.setOriginalValueVariable( QVariant() );
90 
91  expContext.setHighlightedVariables( QStringList() << QgsExpressionContext::EXPR_ORIGINAL_VALUE << QgsExpressionContext::EXPR_SYMBOL_COLOR
95 
96  return expContext;
97 }
98 
100 {
101  mContext = context;
102  const auto unitSelectionWidgets = findChildren<QgsUnitSelectionWidget *>();
103  for ( QgsUnitSelectionWidget *unitWidget : unitSelectionWidgets )
104  {
105  unitWidget->setMapCanvas( mContext.mapCanvas() );
106  }
107 }
108 
110 {
111  return mContext;
112 }
113 
115 {
116  button->init( key, symbolLayer()->dataDefinedProperties(), QgsSymbolLayer::propertyDefinitions(), mVectorLayer, true );
118  connect( button, &QgsPropertyOverrideButton::createAuxiliaryField, this, &QgsSymbolLayerWidget::createAuxiliaryField );
119 
120  button->registerExpressionContextGenerator( this );
121 }
122 
123 void QgsSymbolLayerWidget::createAuxiliaryField()
124 {
125  // try to create an auxiliary layer if not yet created
126  if ( !mVectorLayer->auxiliaryLayer() )
127  {
128  QgsNewAuxiliaryLayerDialog dlg( mVectorLayer, this );
129  dlg.exec();
130  }
131 
132  // return if still not exists
133  if ( !mVectorLayer->auxiliaryLayer() )
134  return;
135 
136  QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
137  QgsSymbolLayer::Property key = static_cast< QgsSymbolLayer::Property >( button->propertyKey() );
139 
140  // create property in auxiliary storage if necessary
141  if ( !mVectorLayer->auxiliaryLayer()->exists( def ) )
142  {
143  QgsNewAuxiliaryFieldDialog dlg( def, mVectorLayer, true, this );
144  if ( dlg.exec() == QDialog::Accepted )
145  def = dlg.propertyDefinition();
146  }
147 
148  // return if still not exist
149  if ( !mVectorLayer->auxiliaryLayer()->exists( def ) )
150  return;
151 
152  // update property with join field name from auxiliary storage
153  QgsProperty property = button->toProperty();
154  property.setField( QgsAuxiliaryLayer::nameFromProperty( def, true ) );
155  property.setActive( true );
156  button->updateFieldLists();
157  button->setToProperty( property );
158  symbolLayer()->setDataDefinedProperty( key, button->toProperty() );
159 
160  emit changed();
161 }
162 
164 {
165  QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
166  QgsSymbolLayer::Property key = static_cast< QgsSymbolLayer::Property >( button->propertyKey() );
167  symbolLayer()->setDataDefinedProperty( key, button->toProperty() );
168  emit changed();
169 }
170 
172  : QgsSymbolLayerWidget( parent, vl )
173 {
174  mLayer = nullptr;
175 
176  setupUi( this );
177  connect( mCustomCheckBox, &QCheckBox::stateChanged, this, &QgsSimpleLineSymbolLayerWidget::mCustomCheckBox_stateChanged );
178  connect( mChangePatternButton, &QPushButton::clicked, this, &QgsSimpleLineSymbolLayerWidget::mChangePatternButton_clicked );
179  connect( mPenWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::mPenWidthUnitWidget_changed );
180  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::mOffsetUnitWidget_changed );
181  connect( mDashPatternUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::mDashPatternUnitWidget_changed );
182  connect( mDrawInsideCheckBox, &QCheckBox::stateChanged, this, &QgsSimpleLineSymbolLayerWidget::mDrawInsideCheckBox_stateChanged );
189 
190  btnChangeColor->setAllowOpacity( true );
191  btnChangeColor->setColorDialogTitle( tr( "Select Line Color" ) );
192  btnChangeColor->setContext( QStringLiteral( "symbology" ) );
193 
194  mColorDDBtn->registerLinkedWidget( btnChangeColor );
195 
196  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconAllRings.svg" ) ), tr( "All Rings" ), QgsLineSymbolLayer::AllRings );
197  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconExteriorRing.svg" ) ), tr( "Exterior Ring Only" ), QgsLineSymbolLayer::ExteriorRingOnly );
198  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconInteriorRings.svg" ) ), tr( "Interior Rings Only" ), QgsLineSymbolLayer::InteriorRingsOnly );
199  connect( mRingFilterComboBox, qgis::overload< int >::of( &QComboBox::currentIndexChanged ), this, [ = ]( int )
200  {
201  if ( mLayer )
202  {
203  mLayer->setRingFilter( static_cast< QgsLineSymbolLayer::RenderRingFilter >( mRingFilterComboBox->currentData().toInt() ) );
204  emit changed();
205  }
206  } );
207 
208  spinOffset->setClearValue( 0.0 );
209 
210  if ( vl && vl->geometryType() != QgsWkbTypes::PolygonGeometry )
211  {
212  //draw inside polygon checkbox only makes sense for polygon layers
213  mDrawInsideCheckBox->hide();
214  mRingFilterComboBox->hide();
215  mRingsLabel->hide();
216  }
217 
218  //make a temporary symbol for the size assistant preview
219  mAssistantPreviewSymbol.reset( new QgsLineSymbol() );
220 
221  if ( vectorLayer() )
222  mPenWidthDDBtn->setSymbol( mAssistantPreviewSymbol );
223 
224  connect( spinWidth, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleLineSymbolLayerWidget::penWidthChanged );
225  connect( btnChangeColor, &QgsColorButton::colorChanged, this, &QgsSimpleLineSymbolLayerWidget::colorChanged );
226  connect( cboPenStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleLineSymbolLayerWidget::penStyleChanged );
227  connect( spinOffset, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleLineSymbolLayerWidget::offsetChanged );
228  connect( cboCapStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleLineSymbolLayerWidget::penStyleChanged );
229  connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleLineSymbolLayerWidget::penStyleChanged );
230 
232 
233  connect( this, &QgsSymbolLayerWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::updateAssistantSymbol );
234 }
235 
236 void QgsSimpleLineSymbolLayerWidget::updateAssistantSymbol()
237 {
238  for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
239  {
240  mAssistantPreviewSymbol->deleteSymbolLayer( i );
241  }
242  mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
244  if ( ddWidth )
245  mAssistantPreviewSymbol->setDataDefinedWidth( ddWidth );
246 }
247 
248 
250 {
251  if ( !layer || layer->layerType() != QLatin1String( "SimpleLine" ) )
252  return;
253 
254  // layer type is correct, we can do the cast
255  mLayer = static_cast<QgsSimpleLineSymbolLayer *>( layer );
256 
257  // set units
258  mPenWidthUnitWidget->blockSignals( true );
259  mPenWidthUnitWidget->setUnit( mLayer->widthUnit() );
260  mPenWidthUnitWidget->setMapUnitScale( mLayer->widthMapUnitScale() );
261  mPenWidthUnitWidget->blockSignals( false );
262  mOffsetUnitWidget->blockSignals( true );
263  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
264  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
265  mOffsetUnitWidget->blockSignals( false );
266  mDashPatternUnitWidget->blockSignals( true );
267  mDashPatternUnitWidget->setUnit( mLayer->customDashPatternUnit() );
268  mDashPatternUnitWidget->setMapUnitScale( mLayer->customDashPatternMapUnitScale() );
269  mDashPatternUnitWidget->setMapUnitScale( mLayer->customDashPatternMapUnitScale() );
270  mDashPatternUnitWidget->blockSignals( false );
271 
272  // set values
273  spinWidth->blockSignals( true );
274  spinWidth->setValue( mLayer->width() );
275  spinWidth->blockSignals( false );
276  btnChangeColor->blockSignals( true );
277  btnChangeColor->setColor( mLayer->color() );
278  btnChangeColor->blockSignals( false );
279  spinOffset->blockSignals( true );
280  spinOffset->setValue( mLayer->offset() );
281  spinOffset->blockSignals( false );
282  cboPenStyle->blockSignals( true );
283  cboJoinStyle->blockSignals( true );
284  cboCapStyle->blockSignals( true );
285  cboPenStyle->setPenStyle( mLayer->penStyle() );
286  cboJoinStyle->setPenJoinStyle( mLayer->penJoinStyle() );
287  cboCapStyle->setPenCapStyle( mLayer->penCapStyle() );
288  cboPenStyle->blockSignals( false );
289  cboJoinStyle->blockSignals( false );
290  cboCapStyle->blockSignals( false );
291 
292  //use a custom dash pattern?
293  bool useCustomDashPattern = mLayer->useCustomDashPattern();
294  mChangePatternButton->setEnabled( useCustomDashPattern );
295  label_3->setEnabled( !useCustomDashPattern );
296  cboPenStyle->setEnabled( !useCustomDashPattern );
297  mCustomCheckBox->blockSignals( true );
298  mCustomCheckBox->setCheckState( useCustomDashPattern ? Qt::Checked : Qt::Unchecked );
299  mCustomCheckBox->blockSignals( false );
300 
301  //make sure height of custom dash button looks good under different platforms
302  QSize size = mChangePatternButton->minimumSizeHint();
303  int fontHeight = static_cast< int >( Qgis::UI_SCALE_FACTOR * fontMetrics().height() * 1.4 );
304  mChangePatternButton->setMinimumSize( QSize( size.width(), std::max( size.height(), fontHeight ) ) );
305 
306  //draw inside polygon?
307  const bool drawInsidePolygon = mLayer->drawInsidePolygon();
308  whileBlocking( mDrawInsideCheckBox )->setCheckState( drawInsidePolygon ? Qt::Checked : Qt::Unchecked );
309 
310  whileBlocking( mRingFilterComboBox )->setCurrentIndex( mRingFilterComboBox->findData( mLayer->ringFilter() ) );
311 
313 
321 
322  updateAssistantSymbol();
323 }
324 
326 {
327  return mLayer;
328 }
329 
330 void QgsSimpleLineSymbolLayerWidget::penWidthChanged()
331 {
332  mLayer->setWidth( spinWidth->value() );
334  emit changed();
335 }
336 
337 void QgsSimpleLineSymbolLayerWidget::colorChanged( const QColor &color )
338 {
339  mLayer->setColor( color );
340  emit changed();
341 }
342 
343 void QgsSimpleLineSymbolLayerWidget::penStyleChanged()
344 {
345  mLayer->setPenStyle( cboPenStyle->penStyle() );
346  mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
347  mLayer->setPenCapStyle( cboCapStyle->penCapStyle() );
349  emit changed();
350 }
351 
352 void QgsSimpleLineSymbolLayerWidget::offsetChanged()
353 {
354  mLayer->setOffset( spinOffset->value() );
356  emit changed();
357 }
358 
359 void QgsSimpleLineSymbolLayerWidget::mCustomCheckBox_stateChanged( int state )
360 {
361  bool checked = ( state == Qt::Checked );
362  mChangePatternButton->setEnabled( checked );
363  label_3->setEnabled( !checked );
364  cboPenStyle->setEnabled( !checked );
365 
366  mLayer->setUseCustomDashPattern( checked );
367  emit changed();
368 }
369 
370 void QgsSimpleLineSymbolLayerWidget::mChangePatternButton_clicked()
371 {
373  if ( panel && panel->dockMode() )
374  {
376  widget->setPanelTitle( tr( "Custom Dash Pattern" ) );
377  widget->setUnit( mDashPatternUnitWidget->unit() );
378  connect( widget, &QgsPanelWidget::widgetChanged, this, [ this, widget ]()
379  {
382  } );
384  panel->openPanel( widget );
385  return;
386  }
387 
389  d.setUnit( mDashPatternUnitWidget->unit() );
390  if ( d.exec() == QDialog::Accepted )
391  {
392  mLayer->setCustomDashVector( d.dashDotVector() );
394  emit changed();
395  }
396 }
397 
398 void QgsSimpleLineSymbolLayerWidget::mPenWidthUnitWidget_changed()
399 {
400  if ( mLayer )
401  {
402  mLayer->setWidthUnit( mPenWidthUnitWidget->unit() );
403  mLayer->setWidthMapUnitScale( mPenWidthUnitWidget->getMapUnitScale() );
405  emit changed();
406  }
407 }
408 
409 void QgsSimpleLineSymbolLayerWidget::mOffsetUnitWidget_changed()
410 {
411  if ( mLayer )
412  {
413  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
414  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
415  emit changed();
416  }
417 }
418 
419 void QgsSimpleLineSymbolLayerWidget::mDashPatternUnitWidget_changed()
420 {
421  if ( mLayer )
422  {
423  mLayer->setCustomDashPatternUnit( mDashPatternUnitWidget->unit() );
424  mLayer->setCustomDashPatternMapUnitScale( mDashPatternUnitWidget->getMapUnitScale() );
426  emit changed();
427  }
428 }
429 
430 void QgsSimpleLineSymbolLayerWidget::mDrawInsideCheckBox_stateChanged( int state )
431 {
432  bool checked = ( state == Qt::Checked );
433  mLayer->setDrawInsidePolygon( checked );
434  emit changed();
435 }
436 
437 
439 {
440  if ( !mLayer )
441  {
442  return;
443  }
444  std::unique_ptr< QgsSimpleLineSymbolLayer > layerCopy( mLayer->clone() );
445  if ( !layerCopy )
446  {
447  return;
448  }
449  QColor color = qApp->palette().color( QPalette::WindowText );
450  layerCopy->setColor( color );
451  // reset offset, we don't want to show that in the preview
452  layerCopy->setOffset( 0 );
453  layerCopy->setUseCustomDashPattern( true );
454 
455  QSize currentIconSize;
456  //icon size is button size with a small margin
457 #ifdef Q_OS_WIN
458  currentIconSize = QSize( mChangePatternButton->width() - 10, mChangePatternButton->height() - 6 );
459 #else
460  currentIconSize = QSize( mChangePatternButton->width() - 10, mChangePatternButton->height() - 12 );
461 #endif
462 
463  if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 )
464  {
465  return;
466  }
467 
468  //create an icon pixmap
469  std::unique_ptr< QgsLineSymbol > previewSymbol = qgis::make_unique< QgsLineSymbol >( QgsSymbolLayerList() << layerCopy.release() );
470  const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( previewSymbol.get(), currentIconSize );
471  mChangePatternButton->setIconSize( currentIconSize );
472  mChangePatternButton->setIcon( icon );
473 
474  // set tooltip
475  // create very large preview image
476  int width = static_cast< int >( Qgis::UI_SCALE_FACTOR * fontMetrics().width( 'X' ) * 23 );
477  int height = static_cast< int >( width / 1.61803398875 ); // golden ratio
478 
479  QPixmap pm = QgsSymbolLayerUtils::symbolPreviewPixmap( previewSymbol.get(), QSize( width, height ), height / 20 );
480  QByteArray data;
481  QBuffer buffer( &data );
482  pm.save( &buffer, "PNG", 100 );
483  mChangePatternButton->setToolTip( QStringLiteral( "<img src='data:image/png;base64, %3'>" ).arg( QString( data.toBase64() ) ) );
484 }
485 
487 {
488  QgsSymbolLayerWidget::resizeEvent( event );
489  // redraw custom dash pattern icon -- the button size has changed
491 }
492 
493 
495 
496 
498  : QgsSymbolLayerWidget( parent, vl )
499 {
500  mLayer = nullptr;
501 
502  setupUi( this );
503  connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
504  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
505  connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
506  connect( mStrokeStyleComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mStrokeStyleComboBox_currentIndexChanged );
507  connect( mStrokeWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
508  connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
509  connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
516 
517  btnChangeColorFill->setAllowOpacity( true );
518  btnChangeColorFill->setColorDialogTitle( tr( "Select Fill Color" ) );
519  btnChangeColorFill->setContext( QStringLiteral( "symbology" ) );
520  btnChangeColorFill->setShowNoColor( true );
521  btnChangeColorFill->setNoColorString( tr( "Transparent Fill" ) );
522  btnChangeColorStroke->setAllowOpacity( true );
523  btnChangeColorStroke->setColorDialogTitle( tr( "Select Stroke Color" ) );
524  btnChangeColorStroke->setContext( QStringLiteral( "symbology" ) );
525  btnChangeColorStroke->setShowNoColor( true );
526  btnChangeColorStroke->setNoColorString( tr( "Transparent Stroke" ) );
527 
528  mFillColorDDBtn->registerLinkedWidget( btnChangeColorFill );
529  mStrokeColorDDBtn->registerLinkedWidget( btnChangeColorStroke );
530 
531  spinOffsetX->setClearValue( 0.0 );
532  spinOffsetY->setClearValue( 0.0 );
533  spinAngle->setClearValue( 0.0 );
534 
535  //make a temporary symbol for the size assistant preview
536  mAssistantPreviewSymbol.reset( new QgsMarkerSymbol() );
537 
538  if ( vectorLayer() )
539  mSizeDDBtn->setSymbol( mAssistantPreviewSymbol );
540 
541  int size = lstNames->iconSize().width();
542  size = std::max( 30, static_cast< int >( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().width( QStringLiteral( "XXX" ) ) ) ) );
543  lstNames->setGridSize( QSize( size * 1.2, size * 1.2 ) );
544  lstNames->setIconSize( QSize( size, size ) );
545 
546  double markerSize = size * 0.8;
548  for ( QgsSimpleMarkerSymbolLayerBase::Shape shape : shapes )
549  {
550  QgsSimpleMarkerSymbolLayer *lyr = new QgsSimpleMarkerSymbolLayer( shape, markerSize );
552  lyr->setColor( QColor( 200, 200, 200 ) );
553  lyr->setStrokeColor( QColor( 0, 0, 0 ) );
554  QIcon icon = QgsSymbolLayerUtils::symbolLayerPreviewIcon( lyr, QgsUnitTypes::RenderPixels, QSize( size, size ) );
555  QListWidgetItem *item = new QListWidgetItem( icon, QString(), lstNames );
556  item->setData( Qt::UserRole, static_cast< int >( shape ) );
557  item->setToolTip( QgsSimpleMarkerSymbolLayerBase::encodeShape( shape ) );
558  delete lyr;
559  }
560  // show at least 3 rows
561  lstNames->setMinimumHeight( lstNames->gridSize().height() * 3.1 );
562 
563  connect( lstNames, &QListWidget::currentRowChanged, this, &QgsSimpleMarkerSymbolLayerWidget::setShape );
564  connect( btnChangeColorStroke, &QgsColorButton::colorChanged, this, &QgsSimpleMarkerSymbolLayerWidget::setColorStroke );
566  connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::penJoinStyleChanged );
567  connect( spinSize, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setSize );
568  connect( spinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setAngle );
569  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setOffset );
570  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setOffset );
571  connect( this, &QgsSymbolLayerWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::updateAssistantSymbol );
572 }
573 
575 {
576  if ( layer->layerType() != QLatin1String( "SimpleMarker" ) )
577  return;
578 
579  // layer type is correct, we can do the cast
580  mLayer = static_cast<QgsSimpleMarkerSymbolLayer *>( layer );
581 
582  // set values
584  for ( int i = 0; i < lstNames->count(); ++i )
585  {
586  if ( static_cast< QgsSimpleMarkerSymbolLayerBase::Shape >( lstNames->item( i )->data( Qt::UserRole ).toInt() ) == shape )
587  {
588  lstNames->setCurrentRow( i );
589  break;
590  }
591  }
592  btnChangeColorStroke->blockSignals( true );
593  btnChangeColorStroke->setColor( mLayer->strokeColor() );
594  btnChangeColorStroke->blockSignals( false );
595  btnChangeColorFill->blockSignals( true );
596  btnChangeColorFill->setColor( mLayer->fillColor() );
597  btnChangeColorFill->setEnabled( QgsSimpleMarkerSymbolLayerBase::shapeIsFilled( mLayer->shape() ) );
598  btnChangeColorFill->blockSignals( false );
599  spinSize->blockSignals( true );
600  spinSize->setValue( mLayer->size() );
601  spinSize->blockSignals( false );
602  spinAngle->blockSignals( true );
603  spinAngle->setValue( mLayer->angle() );
604  spinAngle->blockSignals( false );
605  mStrokeStyleComboBox->blockSignals( true );
606  mStrokeStyleComboBox->setPenStyle( mLayer->strokeStyle() );
607  mStrokeStyleComboBox->blockSignals( false );
608  mStrokeWidthSpinBox->blockSignals( true );
609  mStrokeWidthSpinBox->setValue( mLayer->strokeWidth() );
610  mStrokeWidthSpinBox->blockSignals( false );
611  cboJoinStyle->blockSignals( true );
612  cboJoinStyle->setPenJoinStyle( mLayer->penJoinStyle() );
613  cboJoinStyle->blockSignals( false );
614 
615  // without blocking signals the value gets changed because of slot setOffset()
616  spinOffsetX->blockSignals( true );
617  spinOffsetX->setValue( mLayer->offset().x() );
618  spinOffsetX->blockSignals( false );
619  spinOffsetY->blockSignals( true );
620  spinOffsetY->setValue( mLayer->offset().y() );
621  spinOffsetY->blockSignals( false );
622 
623  mSizeUnitWidget->blockSignals( true );
624  mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
625  mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
626  mSizeUnitWidget->blockSignals( false );
627  mOffsetUnitWidget->blockSignals( true );
628  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
629  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
630  mOffsetUnitWidget->blockSignals( false );
631  mStrokeWidthUnitWidget->blockSignals( true );
632  mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
633  mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
634  mStrokeWidthUnitWidget->blockSignals( false );
635 
636  //anchor points
637  mHorizontalAnchorComboBox->blockSignals( true );
638  mVerticalAnchorComboBox->blockSignals( true );
639  mHorizontalAnchorComboBox->setCurrentIndex( mLayer->horizontalAnchorPoint() );
640  mVerticalAnchorComboBox->setCurrentIndex( mLayer->verticalAnchorPoint() );
641  mHorizontalAnchorComboBox->blockSignals( false );
642  mVerticalAnchorComboBox->blockSignals( false );
643 
655 
656  updateAssistantSymbol();
657 }
658 
660 {
661  return mLayer;
662 }
663 
664 void QgsSimpleMarkerSymbolLayerWidget::setShape()
665 {
666  mLayer->setShape( static_cast< QgsSimpleMarkerSymbolLayerBase::Shape>( lstNames->currentItem()->data( Qt::UserRole ).toInt() ) );
667  btnChangeColorFill->setEnabled( QgsSimpleMarkerSymbolLayerBase::shapeIsFilled( mLayer->shape() ) );
668  emit changed();
669 }
670 
672 {
673  mLayer->setStrokeColor( color );
674  emit changed();
675 }
676 
678 {
679  mLayer->setColor( color );
680  emit changed();
681 }
682 
683 void QgsSimpleMarkerSymbolLayerWidget::penJoinStyleChanged()
684 {
685  mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
686  emit changed();
687 }
688 
689 void QgsSimpleMarkerSymbolLayerWidget::setSize()
690 {
691  mLayer->setSize( spinSize->value() );
692  emit changed();
693 }
694 
695 void QgsSimpleMarkerSymbolLayerWidget::setAngle()
696 {
697  mLayer->setAngle( spinAngle->value() );
698  emit changed();
699 }
700 
701 void QgsSimpleMarkerSymbolLayerWidget::setOffset()
702 {
703  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
704  emit changed();
705 }
706 
707 void QgsSimpleMarkerSymbolLayerWidget::mStrokeStyleComboBox_currentIndexChanged( int index )
708 {
709  Q_UNUSED( index )
710 
711  if ( mLayer )
712  {
713  mLayer->setStrokeStyle( mStrokeStyleComboBox->penStyle() );
714  emit changed();
715  }
716 }
717 
718 void QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
719 {
720  if ( mLayer )
721  {
722  mLayer->setStrokeWidth( d );
723  emit changed();
724  }
725 }
726 
727 void QgsSimpleMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
728 {
729  if ( mLayer )
730  {
731  mLayer->setSizeUnit( mSizeUnitWidget->unit() );
732  mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
733  emit changed();
734  }
735 }
736 
737 void QgsSimpleMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
738 {
739  if ( mLayer )
740  {
741  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
742  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
743  emit changed();
744  }
745 }
746 
747 void QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
748 {
749  if ( mLayer )
750  {
751  mLayer->setStrokeWidthUnit( mStrokeWidthUnitWidget->unit() );
752  mLayer->setStrokeWidthMapUnitScale( mStrokeWidthUnitWidget->getMapUnitScale() );
753  emit changed();
754  }
755 }
756 
757 void QgsSimpleMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
758 {
759  if ( mLayer )
760  {
762  emit changed();
763  }
764 }
765 
766 void QgsSimpleMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
767 {
768  if ( mLayer )
769  {
771  emit changed();
772  }
773 }
774 
775 void QgsSimpleMarkerSymbolLayerWidget::updateAssistantSymbol()
776 {
777  for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
778  {
779  mAssistantPreviewSymbol->deleteSymbolLayer( i );
780  }
781  mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
783  if ( ddSize )
784  mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
785 }
786 
787 
789 
791  : QgsSymbolLayerWidget( parent, vl )
792 {
793  mLayer = nullptr;
794 
795  setupUi( this );
796  connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleFillSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
797  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleFillSymbolLayerWidget::mOffsetUnitWidget_changed );
802 
803  btnChangeColor->setAllowOpacity( true );
804  btnChangeColor->setColorDialogTitle( tr( "Select Fill Color" ) );
805  btnChangeColor->setContext( QStringLiteral( "symbology" ) );
806  btnChangeColor->setShowNoColor( true );
807  btnChangeColor->setNoColorString( tr( "Transparent Fill" ) );
808  btnChangeStrokeColor->setAllowOpacity( true );
809  btnChangeStrokeColor->setColorDialogTitle( tr( "Select Stroke Color" ) );
810  btnChangeStrokeColor->setContext( QStringLiteral( "symbology" ) );
811  btnChangeStrokeColor->setShowNoColor( true );
812  btnChangeStrokeColor->setNoColorString( tr( "Transparent Stroke" ) );
813 
814  spinOffsetX->setClearValue( 0.0 );
815  spinOffsetY->setClearValue( 0.0 );
816 
818  connect( cboFillStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleFillSymbolLayerWidget::setBrushStyle );
819  connect( btnChangeStrokeColor, &QgsColorButton::colorChanged, this, &QgsSimpleFillSymbolLayerWidget::setStrokeColor );
820  connect( spinStrokeWidth, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleFillSymbolLayerWidget::strokeWidthChanged );
821  connect( cboStrokeStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleFillSymbolLayerWidget::strokeStyleChanged );
822  connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleFillSymbolLayerWidget::strokeStyleChanged );
823  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleFillSymbolLayerWidget::offsetChanged );
824  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleFillSymbolLayerWidget::offsetChanged );
825 
826  mFillColorDDBtn->registerLinkedWidget( btnChangeColor );
827  mStrokeColorDDBtn->registerLinkedWidget( btnChangeStrokeColor );
828 }
829 
831 {
832  if ( layer->layerType() != QLatin1String( "SimpleFill" ) )
833  return;
834 
835  // layer type is correct, we can do the cast
836  mLayer = static_cast<QgsSimpleFillSymbolLayer *>( layer );
837 
838  // set values
839  btnChangeColor->blockSignals( true );
840  btnChangeColor->setColor( mLayer->color() );
841  btnChangeColor->blockSignals( false );
842  cboFillStyle->blockSignals( true );
843  cboFillStyle->setBrushStyle( mLayer->brushStyle() );
844  cboFillStyle->blockSignals( false );
845  btnChangeStrokeColor->blockSignals( true );
846  btnChangeStrokeColor->setColor( mLayer->strokeColor() );
847  btnChangeStrokeColor->blockSignals( false );
848  cboStrokeStyle->blockSignals( true );
849  cboStrokeStyle->setPenStyle( mLayer->strokeStyle() );
850  cboStrokeStyle->blockSignals( false );
851  spinStrokeWidth->blockSignals( true );
852  spinStrokeWidth->setValue( mLayer->strokeWidth() );
853  spinStrokeWidth->blockSignals( false );
854  cboJoinStyle->blockSignals( true );
855  cboJoinStyle->setPenJoinStyle( mLayer->penJoinStyle() );
856  cboJoinStyle->blockSignals( false );
857  spinOffsetX->blockSignals( true );
858  spinOffsetX->setValue( mLayer->offset().x() );
859  spinOffsetX->blockSignals( false );
860  spinOffsetY->blockSignals( true );
861  spinOffsetY->setValue( mLayer->offset().y() );
862  spinOffsetY->blockSignals( false );
863 
864  mStrokeWidthUnitWidget->blockSignals( true );
865  mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
866  mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
867  mStrokeWidthUnitWidget->blockSignals( false );
868  mOffsetUnitWidget->blockSignals( true );
869  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
870  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
871  mOffsetUnitWidget->blockSignals( false );
872 
879 
880 }
881 
883 {
884  return mLayer;
885 }
886 
887 void QgsSimpleFillSymbolLayerWidget::setColor( const QColor &color )
888 {
889  mLayer->setColor( color );
890  emit changed();
891 }
892 
894 {
895  mLayer->setStrokeColor( color );
896  emit changed();
897 }
898 
899 void QgsSimpleFillSymbolLayerWidget::setBrushStyle()
900 {
901  mLayer->setBrushStyle( cboFillStyle->brushStyle() );
902  emit changed();
903 }
904 
905 void QgsSimpleFillSymbolLayerWidget::strokeWidthChanged()
906 {
907  mLayer->setStrokeWidth( spinStrokeWidth->value() );
908  emit changed();
909 }
910 
911 void QgsSimpleFillSymbolLayerWidget::strokeStyleChanged()
912 {
913  mLayer->setStrokeStyle( cboStrokeStyle->penStyle() );
914  mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
915  emit changed();
916 }
917 
918 void QgsSimpleFillSymbolLayerWidget::offsetChanged()
919 {
920  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
921  emit changed();
922 }
923 
924 void QgsSimpleFillSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
925 {
926  if ( mLayer )
927  {
928  mLayer->setStrokeWidthUnit( mStrokeWidthUnitWidget->unit() );
929  mLayer->setStrokeWidthMapUnitScale( mStrokeWidthUnitWidget->getMapUnitScale() );
930  emit changed();
931  }
932 }
933 
934 void QgsSimpleFillSymbolLayerWidget::mOffsetUnitWidget_changed()
935 {
936  if ( mLayer )
937  {
938  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
939  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
940  emit changed();
941  }
942 }
943 
945 
947  : QgsSymbolLayerWidget( parent, vl )
948 {
949  mLayer = nullptr;
950 
951  setupUi( this );
952  connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFilledMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
953  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFilledMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
954  connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFilledMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
955  connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFilledMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
960 
961  spinOffsetX->setClearValue( 0.0 );
962  spinOffsetY->setClearValue( 0.0 );
963  spinAngle->setClearValue( 0.0 );
964 
965  //make a temporary symbol for the size assistant preview
966  mAssistantPreviewSymbol.reset( new QgsMarkerSymbol() );
967 
968  if ( vectorLayer() )
969  mSizeDDBtn->setSymbol( mAssistantPreviewSymbol );
970 
971  int size = lstNames->iconSize().width();
972  size = std::max( 30, static_cast< int >( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().width( QStringLiteral( "XXX" ) ) ) ) );
973  lstNames->setGridSize( QSize( size * 1.2, size * 1.2 ) );
974  lstNames->setIconSize( QSize( size, size ) );
975 
976  double markerSize = size * 0.8;
978  for ( QgsSimpleMarkerSymbolLayerBase::Shape shape : shapes )
979  {
980  QgsSimpleMarkerSymbolLayer *lyr = new QgsSimpleMarkerSymbolLayer( shape, markerSize );
982  lyr->setColor( QColor( 200, 200, 200 ) );
983  lyr->setStrokeColor( QColor( 0, 0, 0 ) );
984  QIcon icon = QgsSymbolLayerUtils::symbolLayerPreviewIcon( lyr, QgsUnitTypes::RenderPixels, QSize( size, size ) );
985  QListWidgetItem *item = new QListWidgetItem( icon, QString(), lstNames );
986  item->setData( Qt::UserRole, static_cast< int >( shape ) );
987  item->setToolTip( QgsSimpleMarkerSymbolLayerBase::encodeShape( shape ) );
988  delete lyr;
989  }
990  // show at least 3 rows
991  lstNames->setMinimumHeight( lstNames->gridSize().height() * 3.1 );
992 
993  connect( lstNames, &QListWidget::currentRowChanged, this, &QgsFilledMarkerSymbolLayerWidget::setShape );
994  connect( spinSize, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setSize );
995  connect( spinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setAngle );
996  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setOffset );
997  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setOffset );
998  connect( this, &QgsSymbolLayerWidget::changed, this, &QgsFilledMarkerSymbolLayerWidget::updateAssistantSymbol );
999 }
1000 
1002 {
1003  if ( layer->layerType() != QLatin1String( "FilledMarker" ) )
1004  return;
1005 
1006  // layer type is correct, we can do the cast
1007  mLayer = static_cast<QgsFilledMarkerSymbolLayer *>( layer );
1008 
1009  // set values
1011  for ( int i = 0; i < lstNames->count(); ++i )
1012  {
1013  if ( static_cast< QgsSimpleMarkerSymbolLayerBase::Shape >( lstNames->item( i )->data( Qt::UserRole ).toInt() ) == shape )
1014  {
1015  lstNames->setCurrentRow( i );
1016  break;
1017  }
1018  }
1019  whileBlocking( spinSize )->setValue( mLayer->size() );
1020  whileBlocking( spinAngle )->setValue( mLayer->angle() );
1021  whileBlocking( spinOffsetX )->setValue( mLayer->offset().x() );
1022  whileBlocking( spinOffsetY )->setValue( mLayer->offset().y() );
1023 
1024  mSizeUnitWidget->blockSignals( true );
1025  mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
1026  mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
1027  mSizeUnitWidget->blockSignals( false );
1028  mOffsetUnitWidget->blockSignals( true );
1029  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1030  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1031  mOffsetUnitWidget->blockSignals( false );
1032 
1033  //anchor points
1034  whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mLayer->horizontalAnchorPoint() );
1035  whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mLayer->verticalAnchorPoint() );
1036 
1043 
1044  updateAssistantSymbol();
1045 }
1046 
1048 {
1049  return mLayer;
1050 }
1051 
1052 void QgsFilledMarkerSymbolLayerWidget::setShape()
1053 {
1054  mLayer->setShape( static_cast< QgsSimpleMarkerSymbolLayerBase::Shape>( lstNames->currentItem()->data( Qt::UserRole ).toInt() ) );
1055  emit changed();
1056 }
1057 
1058 void QgsFilledMarkerSymbolLayerWidget::setSize()
1059 {
1060  mLayer->setSize( spinSize->value() );
1061  emit changed();
1062 }
1063 
1064 void QgsFilledMarkerSymbolLayerWidget::setAngle()
1065 {
1066  mLayer->setAngle( spinAngle->value() );
1067  emit changed();
1068 }
1069 
1070 void QgsFilledMarkerSymbolLayerWidget::setOffset()
1071 {
1072  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1073  emit changed();
1074 }
1075 
1076 void QgsFilledMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
1077 {
1078  if ( mLayer )
1079  {
1080  mLayer->setSizeUnit( mSizeUnitWidget->unit() );
1081  mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
1082  emit changed();
1083  }
1084 }
1085 
1086 void QgsFilledMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
1087 {
1088  if ( mLayer )
1089  {
1090  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1091  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1092  emit changed();
1093  }
1094 }
1095 
1096 void QgsFilledMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
1097 {
1098  if ( mLayer )
1099  {
1101  emit changed();
1102  }
1103 }
1104 
1105 void QgsFilledMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
1106 {
1107  if ( mLayer )
1108  {
1110  emit changed();
1111  }
1112 }
1113 
1114 void QgsFilledMarkerSymbolLayerWidget::updateAssistantSymbol()
1115 {
1116  for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
1117  {
1118  mAssistantPreviewSymbol->deleteSymbolLayer( i );
1119  }
1120  mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
1122  if ( ddSize )
1123  mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
1124 }
1125 
1126 
1128 
1130  : QgsSymbolLayerWidget( parent, vl )
1131 {
1132  mLayer = nullptr;
1133 
1134  setupUi( this );
1135  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsGradientFillSymbolLayerWidget::mOffsetUnitWidget_changed );
1136  connect( mSpinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::mSpinAngle_valueChanged );
1139 
1140  btnColorRamp->setShowGradientOnly( true );
1141 
1142  btnChangeColor->setAllowOpacity( true );
1143  btnChangeColor->setColorDialogTitle( tr( "Select Gradient Color" ) );
1144  btnChangeColor->setContext( QStringLiteral( "symbology" ) );
1145  btnChangeColor->setShowNoColor( true );
1146  btnChangeColor->setNoColorString( tr( "Transparent" ) );
1147  btnChangeColor2->setAllowOpacity( true );
1148  btnChangeColor2->setColorDialogTitle( tr( "Select Gradient Color" ) );
1149  btnChangeColor2->setContext( QStringLiteral( "symbology" ) );
1150  btnChangeColor2->setShowNoColor( true );
1151  btnChangeColor2->setNoColorString( tr( "Transparent" ) );
1152 
1153  mStartColorDDBtn->registerLinkedWidget( btnChangeColor );
1154  mEndColorDDBtn->registerLinkedWidget( btnChangeColor2 );
1155 
1156  spinOffsetX->setClearValue( 0.0 );
1157  spinOffsetY->setClearValue( 0.0 );
1158  mSpinAngle->setClearValue( 0.0 );
1159 
1163  connect( cboGradientType, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGradientFillSymbolLayerWidget::setGradientType );
1164  connect( cboCoordinateMode, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGradientFillSymbolLayerWidget::setCoordinateMode );
1165  connect( cboGradientSpread, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGradientFillSymbolLayerWidget::setGradientSpread );
1166  connect( radioTwoColor, &QAbstractButton::toggled, this, &QgsGradientFillSymbolLayerWidget::colorModeChanged );
1167  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::offsetChanged );
1168  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::offsetChanged );
1169  connect( spinRefPoint1X, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1170  connect( spinRefPoint1Y, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1171  connect( checkRefPoint1Centroid, &QAbstractButton::toggled, this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1172  connect( spinRefPoint2X, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1173  connect( spinRefPoint2Y, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1174  connect( checkRefPoint2Centroid, &QAbstractButton::toggled, this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1175 }
1176 
1178 {
1179  if ( layer->layerType() != QLatin1String( "GradientFill" ) )
1180  return;
1181 
1182  // layer type is correct, we can do the cast
1183  mLayer = static_cast<QgsGradientFillSymbolLayer *>( layer );
1184 
1185  // set values
1186  btnChangeColor->blockSignals( true );
1187  btnChangeColor->setColor( mLayer->color() );
1188  btnChangeColor->blockSignals( false );
1189  btnChangeColor2->blockSignals( true );
1190  btnChangeColor2->setColor( mLayer->color2() );
1191  btnChangeColor2->blockSignals( false );
1192 
1194  {
1195  radioTwoColor->setChecked( true );
1196  btnColorRamp->setEnabled( false );
1197  }
1198  else
1199  {
1200  radioColorRamp->setChecked( true );
1201  btnChangeColor->setEnabled( false );
1202  btnChangeColor2->setEnabled( false );
1203  }
1204 
1205  // set source color ramp
1206  if ( mLayer->colorRamp() )
1207  {
1208  btnColorRamp->blockSignals( true );
1209  btnColorRamp->setColorRamp( mLayer->colorRamp() );
1210  btnColorRamp->blockSignals( false );
1211  }
1212 
1213  cboGradientType->blockSignals( true );
1214  switch ( mLayer->gradientType() )
1215  {
1217  cboGradientType->setCurrentIndex( 0 );
1218  break;
1220  cboGradientType->setCurrentIndex( 1 );
1221  break;
1223  cboGradientType->setCurrentIndex( 2 );
1224  break;
1225  }
1226  cboGradientType->blockSignals( false );
1227 
1228  cboCoordinateMode->blockSignals( true );
1229  switch ( mLayer->coordinateMode() )
1230  {
1232  cboCoordinateMode->setCurrentIndex( 1 );
1233  checkRefPoint1Centroid->setEnabled( false );
1234  checkRefPoint2Centroid->setEnabled( false );
1235  break;
1237  default:
1238  cboCoordinateMode->setCurrentIndex( 0 );
1239  break;
1240  }
1241  cboCoordinateMode->blockSignals( false );
1242 
1243  cboGradientSpread->blockSignals( true );
1244  switch ( mLayer->gradientSpread() )
1245  {
1247  cboGradientSpread->setCurrentIndex( 0 );
1248  break;
1250  cboGradientSpread->setCurrentIndex( 1 );
1251  break;
1253  cboGradientSpread->setCurrentIndex( 2 );
1254  break;
1255  }
1256  cboGradientSpread->blockSignals( false );
1257 
1258  spinRefPoint1X->blockSignals( true );
1259  spinRefPoint1X->setValue( mLayer->referencePoint1().x() );
1260  spinRefPoint1X->blockSignals( false );
1261  spinRefPoint1Y->blockSignals( true );
1262  spinRefPoint1Y->setValue( mLayer->referencePoint1().y() );
1263  spinRefPoint1Y->blockSignals( false );
1264  checkRefPoint1Centroid->blockSignals( true );
1265  checkRefPoint1Centroid->setChecked( mLayer->referencePoint1IsCentroid() );
1267  {
1268  spinRefPoint1X->setEnabled( false );
1269  spinRefPoint1Y->setEnabled( false );
1270  }
1271  checkRefPoint1Centroid->blockSignals( false );
1272  spinRefPoint2X->blockSignals( true );
1273  spinRefPoint2X->setValue( mLayer->referencePoint2().x() );
1274  spinRefPoint2X->blockSignals( false );
1275  spinRefPoint2Y->blockSignals( true );
1276  spinRefPoint2Y->setValue( mLayer->referencePoint2().y() );
1277  spinRefPoint2Y->blockSignals( false );
1278  checkRefPoint2Centroid->blockSignals( true );
1279  checkRefPoint2Centroid->setChecked( mLayer->referencePoint2IsCentroid() );
1281  {
1282  spinRefPoint2X->setEnabled( false );
1283  spinRefPoint2Y->setEnabled( false );
1284  }
1285  checkRefPoint2Centroid->blockSignals( false );
1286 
1287  spinOffsetX->blockSignals( true );
1288  spinOffsetX->setValue( mLayer->offset().x() );
1289  spinOffsetX->blockSignals( false );
1290  spinOffsetY->blockSignals( true );
1291  spinOffsetY->setValue( mLayer->offset().y() );
1292  spinOffsetY->blockSignals( false );
1293  mSpinAngle->blockSignals( true );
1294  mSpinAngle->setValue( mLayer->angle() );
1295  mSpinAngle->blockSignals( false );
1296 
1297  mOffsetUnitWidget->blockSignals( true );
1298  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1299  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1300  mOffsetUnitWidget->blockSignals( false );
1301 
1314 }
1315 
1317 {
1318  return mLayer;
1319 }
1320 
1322 {
1323  mLayer->setColor( color );
1324  emit changed();
1325 }
1326 
1328 {
1329  mLayer->setColor2( color );
1330  emit changed();
1331 }
1332 
1333 void QgsGradientFillSymbolLayerWidget::colorModeChanged()
1334 {
1335  if ( radioTwoColor->isChecked() )
1336  {
1338  }
1339  else
1340  {
1342  }
1343  emit changed();
1344 }
1345 
1347 {
1348  if ( btnColorRamp->isNull() )
1349  return;
1350 
1351  mLayer->setColorRamp( btnColorRamp->colorRamp()->clone() );
1352  emit changed();
1353 }
1354 
1356 {
1357  switch ( index )
1358  {
1359  case 0:
1361  //set sensible default reference points
1362  spinRefPoint1X->setValue( 0.5 );
1363  spinRefPoint1Y->setValue( 0 );
1364  spinRefPoint2X->setValue( 0.5 );
1365  spinRefPoint2Y->setValue( 1 );
1366  break;
1367  case 1:
1369  //set sensible default reference points
1370  spinRefPoint1X->setValue( 0 );
1371  spinRefPoint1Y->setValue( 0 );
1372  spinRefPoint2X->setValue( 1 );
1373  spinRefPoint2Y->setValue( 1 );
1374  break;
1375  case 2:
1377  spinRefPoint1X->setValue( 0.5 );
1378  spinRefPoint1Y->setValue( 0.5 );
1379  spinRefPoint2X->setValue( 1 );
1380  spinRefPoint2Y->setValue( 1 );
1381  break;
1382  }
1383  emit changed();
1384 }
1385 
1387 {
1388 
1389  switch ( index )
1390  {
1391  case 0:
1392  //feature coordinate mode
1394  //allow choice of centroid reference positions
1395  checkRefPoint1Centroid->setEnabled( true );
1396  checkRefPoint2Centroid->setEnabled( true );
1397  break;
1398  case 1:
1399  //viewport coordinate mode
1401  //disable choice of centroid reference positions
1402  checkRefPoint1Centroid->setChecked( Qt::Unchecked );
1403  checkRefPoint1Centroid->setEnabled( false );
1404  checkRefPoint2Centroid->setChecked( Qt::Unchecked );
1405  checkRefPoint2Centroid->setEnabled( false );
1406  break;
1407  }
1408 
1409  emit changed();
1410 }
1411 
1413 {
1414  switch ( index )
1415  {
1416  case 0:
1418  break;
1419  case 1:
1421  break;
1422  case 2:
1424  break;
1425  }
1426 
1427  emit changed();
1428 }
1429 
1430 void QgsGradientFillSymbolLayerWidget::offsetChanged()
1431 {
1432  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1433  emit changed();
1434 }
1435 
1436 void QgsGradientFillSymbolLayerWidget::referencePointChanged()
1437 {
1438  mLayer->setReferencePoint1( QPointF( spinRefPoint1X->value(), spinRefPoint1Y->value() ) );
1439  mLayer->setReferencePoint1IsCentroid( checkRefPoint1Centroid->isChecked() );
1440  mLayer->setReferencePoint2( QPointF( spinRefPoint2X->value(), spinRefPoint2Y->value() ) );
1441  mLayer->setReferencePoint2IsCentroid( checkRefPoint2Centroid->isChecked() );
1442  emit changed();
1443 }
1444 
1445 void QgsGradientFillSymbolLayerWidget::mSpinAngle_valueChanged( double value )
1446 {
1447  mLayer->setAngle( value );
1448  emit changed();
1449 }
1450 
1451 void QgsGradientFillSymbolLayerWidget::mOffsetUnitWidget_changed()
1452 {
1453  if ( mLayer )
1454  {
1455  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1456  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1457  emit changed();
1458  }
1459 }
1460 
1462 
1464  : QgsSymbolLayerWidget( parent, vl )
1465 {
1466  mLayer = nullptr;
1467 
1468  setupUi( this );
1469  connect( mSpinBlurRadius, qgis::overload< int >::of( &QSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::mSpinBlurRadius_valueChanged );
1470  connect( mSpinMaxDistance, qgis::overload< double >::of( &QDoubleSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::mSpinMaxDistance_valueChanged );
1471  connect( mDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsShapeburstFillSymbolLayerWidget::mDistanceUnitWidget_changed );
1472  connect( mRadioUseWholeShape, &QRadioButton::toggled, this, &QgsShapeburstFillSymbolLayerWidget::mRadioUseWholeShape_toggled );
1473  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsShapeburstFillSymbolLayerWidget::mOffsetUnitWidget_changed );
1474  connect( mIgnoreRingsCheckBox, &QCheckBox::stateChanged, this, &QgsShapeburstFillSymbolLayerWidget::mIgnoreRingsCheckBox_stateChanged );
1479 
1480  QButtonGroup *group1 = new QButtonGroup( this );
1481  group1->addButton( radioColorRamp );
1482  group1->addButton( radioTwoColor );
1483  QButtonGroup *group2 = new QButtonGroup( this );
1484  group2->addButton( mRadioUseMaxDistance );
1485  group2->addButton( mRadioUseWholeShape );
1486  btnChangeColor->setAllowOpacity( true );
1487  btnChangeColor->setColorDialogTitle( tr( "Select Gradient Color" ) );
1488  btnChangeColor->setContext( QStringLiteral( "symbology" ) );
1489  btnChangeColor->setShowNoColor( true );
1490  btnChangeColor->setNoColorString( tr( "Transparent" ) );
1491  btnChangeColor2->setAllowOpacity( true );
1492  btnChangeColor2->setColorDialogTitle( tr( "Select Gradient Color" ) );
1493  btnChangeColor2->setContext( QStringLiteral( "symbology" ) );
1494  btnChangeColor2->setShowNoColor( true );
1495  btnChangeColor2->setNoColorString( tr( "Transparent" ) );
1496 
1497  mStartColorDDBtn->registerLinkedWidget( btnChangeColor );
1498  mEndColorDDBtn->registerLinkedWidget( btnChangeColor2 );
1499 
1500  spinOffsetX->setClearValue( 0.0 );
1501  spinOffsetY->setClearValue( 0.0 );
1502 
1503  btnColorRamp->setShowGradientOnly( true );
1504 
1505  connect( btnColorRamp, &QgsColorRampButton::colorRampChanged, this, &QgsShapeburstFillSymbolLayerWidget::applyColorRamp );
1506 
1509  connect( radioTwoColor, &QAbstractButton::toggled, this, &QgsShapeburstFillSymbolLayerWidget::colorModeChanged );
1510  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::offsetChanged );
1511  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::offsetChanged );
1512 
1513  connect( mBlurSlider, &QAbstractSlider::valueChanged, mSpinBlurRadius, &QSpinBox::setValue );
1514  connect( mSpinBlurRadius, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), mBlurSlider, &QAbstractSlider::setValue );
1515 }
1516 
1518 {
1519  if ( layer->layerType() != QLatin1String( "ShapeburstFill" ) )
1520  return;
1521 
1522  // layer type is correct, we can do the cast
1523  mLayer = static_cast<QgsShapeburstFillSymbolLayer *>( layer );
1524 
1525  // set values
1526  btnChangeColor->blockSignals( true );
1527  btnChangeColor->setColor( mLayer->color() );
1528  btnChangeColor->blockSignals( false );
1529  btnChangeColor2->blockSignals( true );
1530  btnChangeColor2->setColor( mLayer->color2() );
1531  btnChangeColor2->blockSignals( false );
1532 
1534  {
1535  radioTwoColor->setChecked( true );
1536  btnColorRamp->setEnabled( false );
1537  }
1538  else
1539  {
1540  radioColorRamp->setChecked( true );
1541  btnChangeColor->setEnabled( false );
1542  btnChangeColor2->setEnabled( false );
1543  }
1544 
1545  mSpinBlurRadius->blockSignals( true );
1546  mBlurSlider->blockSignals( true );
1547  mSpinBlurRadius->setValue( mLayer->blurRadius() );
1548  mBlurSlider->setValue( mLayer->blurRadius() );
1549  mSpinBlurRadius->blockSignals( false );
1550  mBlurSlider->blockSignals( false );
1551 
1552  mSpinMaxDistance->blockSignals( true );
1553  mSpinMaxDistance->setValue( mLayer->maxDistance() );
1554  mSpinMaxDistance->blockSignals( false );
1555 
1556  mRadioUseWholeShape->blockSignals( true );
1557  mRadioUseMaxDistance->blockSignals( true );
1558  if ( mLayer->useWholeShape() )
1559  {
1560  mRadioUseWholeShape->setChecked( true );
1561  mSpinMaxDistance->setEnabled( false );
1562  mDistanceUnitWidget->setEnabled( false );
1563  }
1564  else
1565  {
1566  mRadioUseMaxDistance->setChecked( true );
1567  mSpinMaxDistance->setEnabled( true );
1568  mDistanceUnitWidget->setEnabled( true );
1569  }
1570  mRadioUseWholeShape->blockSignals( false );
1571  mRadioUseMaxDistance->blockSignals( false );
1572 
1573  mDistanceUnitWidget->blockSignals( true );
1574  mDistanceUnitWidget->setUnit( mLayer->distanceUnit() );
1575  mDistanceUnitWidget->setMapUnitScale( mLayer->distanceMapUnitScale() );
1576  mDistanceUnitWidget->blockSignals( false );
1577 
1578  mIgnoreRingsCheckBox->blockSignals( true );
1579  mIgnoreRingsCheckBox->setCheckState( mLayer->ignoreRings() ? Qt::Checked : Qt::Unchecked );
1580  mIgnoreRingsCheckBox->blockSignals( false );
1581 
1582  // set source color ramp
1583  if ( mLayer->colorRamp() )
1584  {
1585  btnColorRamp->blockSignals( true );
1586  btnColorRamp->setColorRamp( mLayer->colorRamp() );
1587  btnColorRamp->blockSignals( false );
1588  }
1589 
1590  spinOffsetX->blockSignals( true );
1591  spinOffsetX->setValue( mLayer->offset().x() );
1592  spinOffsetX->blockSignals( false );
1593  spinOffsetY->blockSignals( true );
1594  spinOffsetY->setValue( mLayer->offset().y() );
1595  spinOffsetY->blockSignals( false );
1596  mOffsetUnitWidget->blockSignals( true );
1597  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1598  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1599  mOffsetUnitWidget->blockSignals( false );
1600 
1607 }
1608 
1610 {
1611  return mLayer;
1612 }
1613 
1615 {
1616  if ( mLayer )
1617  {
1618  mLayer->setColor( color );
1619  emit changed();
1620  }
1621 }
1622 
1624 {
1625  if ( mLayer )
1626  {
1627  mLayer->setColor2( color );
1628  emit changed();
1629  }
1630 }
1631 
1632 void QgsShapeburstFillSymbolLayerWidget::colorModeChanged()
1633 {
1634  if ( !mLayer )
1635  {
1636  return;
1637  }
1638 
1639  if ( radioTwoColor->isChecked() )
1640  {
1642  }
1643  else
1644  {
1646  }
1647  emit changed();
1648 }
1649 
1650 void QgsShapeburstFillSymbolLayerWidget::mSpinBlurRadius_valueChanged( int value )
1651 {
1652  if ( mLayer )
1653  {
1654  mLayer->setBlurRadius( value );
1655  emit changed();
1656  }
1657 }
1658 
1659 void QgsShapeburstFillSymbolLayerWidget::mSpinMaxDistance_valueChanged( double value )
1660 {
1661  if ( mLayer )
1662  {
1663  mLayer->setMaxDistance( value );
1664  emit changed();
1665  }
1666 }
1667 
1668 void QgsShapeburstFillSymbolLayerWidget::mDistanceUnitWidget_changed()
1669 {
1670  if ( mLayer )
1671  {
1672  mLayer->setDistanceUnit( mDistanceUnitWidget->unit() );
1673  mLayer->setDistanceMapUnitScale( mDistanceUnitWidget->getMapUnitScale() );
1674  emit changed();
1675  }
1676 }
1677 
1678 void QgsShapeburstFillSymbolLayerWidget::mRadioUseWholeShape_toggled( bool value )
1679 {
1680  if ( mLayer )
1681  {
1682  mLayer->setUseWholeShape( value );
1683  mDistanceUnitWidget->setEnabled( !value );
1684  emit changed();
1685  }
1686 }
1687 
1688 void QgsShapeburstFillSymbolLayerWidget::applyColorRamp()
1689 {
1690  QgsColorRamp *ramp = btnColorRamp->colorRamp();
1691  if ( !ramp )
1692  return;
1693 
1694  mLayer->setColorRamp( ramp );
1695  emit changed();
1696 }
1697 
1698 void QgsShapeburstFillSymbolLayerWidget::offsetChanged()
1699 {
1700  if ( mLayer )
1701  {
1702  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1703  emit changed();
1704  }
1705 }
1706 
1707 void QgsShapeburstFillSymbolLayerWidget::mOffsetUnitWidget_changed()
1708 {
1709  if ( mLayer )
1710  {
1711  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1712  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1713  emit changed();
1714  }
1715 }
1716 
1717 
1718 void QgsShapeburstFillSymbolLayerWidget::mIgnoreRingsCheckBox_stateChanged( int state )
1719 {
1720  bool checked = ( state == Qt::Checked );
1721  mLayer->setIgnoreRings( checked );
1722  emit changed();
1723 }
1724 
1726 
1728  : QgsSymbolLayerWidget( parent, vl )
1729 {
1730  mLayer = nullptr;
1731 
1732  setupUi( this );
1733  connect( mIntervalUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsMarkerLineSymbolLayerWidget::mIntervalUnitWidget_changed );
1734  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsMarkerLineSymbolLayerWidget::mOffsetUnitWidget_changed );
1735  connect( mOffsetAlongLineUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsMarkerLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed );
1736  connect( mAverageAngleUnit, &QgsUnitSelectionWidget::changed, this, &QgsMarkerLineSymbolLayerWidget::averageAngleUnitChanged );
1745 
1746  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconAllRings.svg" ) ), tr( "All Rings" ), QgsLineSymbolLayer::AllRings );
1747  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconExteriorRing.svg" ) ), tr( "Exterior Ring Only" ), QgsLineSymbolLayer::ExteriorRingOnly );
1748  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconInteriorRings.svg" ) ), tr( "Interior Rings Only" ), QgsLineSymbolLayer::InteriorRingsOnly );
1749  connect( mRingFilterComboBox, qgis::overload< int >::of( &QComboBox::currentIndexChanged ), this, [ = ]( int )
1750  {
1751  if ( mLayer )
1752  {
1753  mLayer->setRingFilter( static_cast< QgsLineSymbolLayer::RenderRingFilter >( mRingFilterComboBox->currentData().toInt() ) );
1754  emit changed();
1755  }
1756  } );
1757 
1758  spinOffset->setClearValue( 0.0 );
1759 
1760 
1761  if ( vl && vl->geometryType() != QgsWkbTypes::PolygonGeometry )
1762  {
1763  mRingFilterComboBox->hide();
1764  mRingsLabel->hide();
1765  }
1766 
1767  mSpinAverageAngleLength->setClearValue( 4.0 );
1768 
1769  connect( spinInterval, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsMarkerLineSymbolLayerWidget::setInterval );
1770  connect( mSpinOffsetAlongLine, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsMarkerLineSymbolLayerWidget::setOffsetAlongLine );
1771  connect( chkRotateMarker, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setRotate );
1772  connect( spinOffset, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsMarkerLineSymbolLayerWidget::setOffset );
1773  connect( mSpinAverageAngleLength, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsMarkerLineSymbolLayerWidget::setAverageAngle );
1774  connect( radInterval, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1775  connect( radVertex, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1776  connect( radVertexLast, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1777  connect( radVertexFirst, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1778  connect( radCentralPoint, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1779  connect( radCurvePoint, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1780 }
1781 
1783 {
1784  if ( layer->layerType() != QLatin1String( "MarkerLine" ) )
1785  return;
1786 
1787  // layer type is correct, we can do the cast
1788  mLayer = static_cast<QgsMarkerLineSymbolLayer *>( layer );
1789 
1790  // set values
1791  spinInterval->blockSignals( true );
1792  spinInterval->setValue( mLayer->interval() );
1793  spinInterval->blockSignals( false );
1794  mSpinOffsetAlongLine->blockSignals( true );
1795  mSpinOffsetAlongLine->setValue( mLayer->offsetAlongLine() );
1796  mSpinOffsetAlongLine->blockSignals( false );
1797  chkRotateMarker->blockSignals( true );
1798  chkRotateMarker->setChecked( mLayer->rotateSymbols() );
1799  chkRotateMarker->blockSignals( false );
1800  spinOffset->blockSignals( true );
1801  spinOffset->setValue( mLayer->offset() );
1802  spinOffset->blockSignals( false );
1804  radInterval->setChecked( true );
1806  radVertex->setChecked( true );
1808  radVertexLast->setChecked( true );
1810  radCentralPoint->setChecked( true );
1812  radCurvePoint->setChecked( true );
1813  else
1814  radVertexFirst->setChecked( true );
1815 
1816  // set units
1817  mIntervalUnitWidget->blockSignals( true );
1818  mIntervalUnitWidget->setUnit( mLayer->intervalUnit() );
1819  mIntervalUnitWidget->setMapUnitScale( mLayer->intervalMapUnitScale() );
1820  mIntervalUnitWidget->blockSignals( false );
1821  mOffsetUnitWidget->blockSignals( true );
1822  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1823  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1824  mOffsetUnitWidget->blockSignals( false );
1825  mOffsetAlongLineUnitWidget->blockSignals( true );
1826  mOffsetAlongLineUnitWidget->setUnit( mLayer->offsetAlongLineUnit() );
1827  mOffsetAlongLineUnitWidget->setMapUnitScale( mLayer->offsetAlongLineMapUnitScale() );
1828  mOffsetAlongLineUnitWidget->blockSignals( false );
1829 
1830  whileBlocking( mAverageAngleUnit )->setUnit( mLayer->averageAngleUnit() );
1831  whileBlocking( mAverageAngleUnit )->setMapUnitScale( mLayer->averageAngleMapUnitScale() );
1832  whileBlocking( mSpinAverageAngleLength )->setValue( mLayer->averageAngleLength() );
1833 
1834  whileBlocking( mRingFilterComboBox )->setCurrentIndex( mRingFilterComboBox->findData( mLayer->ringFilter() ) );
1835 
1836  setPlacement(); // update gui
1837 
1843 }
1844 
1846 {
1847  return mLayer;
1848 }
1849 
1851 {
1852  mLayer->setInterval( val );
1853  emit changed();
1854 }
1855 
1857 {
1858  mLayer->setOffsetAlongLine( val );
1859  emit changed();
1860 }
1861 
1862 void QgsMarkerLineSymbolLayerWidget::setRotate()
1863 {
1864  mSpinAverageAngleLength->setEnabled( chkRotateMarker->isChecked() && ( radInterval->isChecked() || radCentralPoint->isChecked() ) );
1865  mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
1866 
1867  mLayer->setRotateSymbols( chkRotateMarker->isChecked() );
1868  emit changed();
1869 }
1870 
1871 void QgsMarkerLineSymbolLayerWidget::setOffset()
1872 {
1873  mLayer->setOffset( spinOffset->value() );
1874  emit changed();
1875 }
1876 
1877 void QgsMarkerLineSymbolLayerWidget::setPlacement()
1878 {
1879  bool interval = radInterval->isChecked();
1880  spinInterval->setEnabled( interval );
1881  mSpinOffsetAlongLine->setEnabled( radInterval->isChecked() || radVertexLast->isChecked() || radVertexFirst->isChecked() );
1882  mOffsetAlongLineUnitWidget->setEnabled( mSpinOffsetAlongLine->isEnabled() );
1883  mSpinAverageAngleLength->setEnabled( chkRotateMarker->isChecked() && ( radInterval->isChecked() || radCentralPoint->isChecked() ) );
1884  mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
1885  //mLayer->setPlacement( interval ? QgsMarkerLineSymbolLayer::Interval : QgsMarkerLineSymbolLayer::Vertex );
1886  if ( radInterval->isChecked() )
1888  else if ( radVertex->isChecked() )
1890  else if ( radVertexLast->isChecked() )
1892  else if ( radVertexFirst->isChecked() )
1894  else if ( radCurvePoint->isChecked() )
1896  else
1898 
1899  emit changed();
1900 }
1901 
1902 void QgsMarkerLineSymbolLayerWidget::mIntervalUnitWidget_changed()
1903 {
1904  if ( mLayer )
1905  {
1906  mLayer->setIntervalUnit( mIntervalUnitWidget->unit() );
1907  mLayer->setIntervalMapUnitScale( mIntervalUnitWidget->getMapUnitScale() );
1908  emit changed();
1909  }
1910 }
1911 
1912 void QgsMarkerLineSymbolLayerWidget::mOffsetUnitWidget_changed()
1913 {
1914  if ( mLayer )
1915  {
1916  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1917  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1918  emit changed();
1919  }
1920 }
1921 
1922 void QgsMarkerLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed()
1923 {
1924  if ( mLayer )
1925  {
1926  mLayer->setOffsetAlongLineUnit( mOffsetAlongLineUnitWidget->unit() );
1927  mLayer->setOffsetAlongLineMapUnitScale( mOffsetAlongLineUnitWidget->getMapUnitScale() );
1928  }
1929  emit changed();
1930 }
1931 
1932 void QgsMarkerLineSymbolLayerWidget::averageAngleUnitChanged()
1933 {
1934  if ( mLayer )
1935  {
1936  mLayer->setAverageAngleUnit( mAverageAngleUnit->unit() );
1937  mLayer->setAverageAngleMapUnitScale( mAverageAngleUnit->getMapUnitScale() );
1938  }
1939  emit changed();
1940 }
1941 
1942 void QgsMarkerLineSymbolLayerWidget::setAverageAngle( double val )
1943 {
1944  if ( mLayer )
1945  {
1946  mLayer->setAverageAngleLength( val );
1947  emit changed();
1948  }
1949 }
1950 
1951 
1953 
1955  : QgsSymbolLayerWidget( parent, vl )
1956 {
1957  mLayer = nullptr;
1958 
1959  setupUi( this );
1960  connect( mIntervalUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::mIntervalUnitWidget_changed );
1961  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::mOffsetUnitWidget_changed );
1962  connect( mOffsetAlongLineUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed );
1963  connect( mAverageAngleUnit, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::averageAngleUnitChanged );
1964  connect( mHashLengthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::hashLengthUnitWidgetChanged );
1975 
1976  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconAllRings.svg" ) ), tr( "All Rings" ), QgsLineSymbolLayer::AllRings );
1977  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconExteriorRing.svg" ) ), tr( "Exterior Ring Only" ), QgsLineSymbolLayer::ExteriorRingOnly );
1978  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconInteriorRings.svg" ) ), tr( "Interior Rings Only" ), QgsLineSymbolLayer::InteriorRingsOnly );
1979  connect( mRingFilterComboBox, qgis::overload< int >::of( &QComboBox::currentIndexChanged ), this, [ = ]( int )
1980  {
1981  if ( mLayer )
1982  {
1983  mLayer->setRingFilter( static_cast< QgsLineSymbolLayer::RenderRingFilter >( mRingFilterComboBox->currentData().toInt() ) );
1984  emit changed();
1985  }
1986  } );
1987 
1988  spinOffset->setClearValue( 0.0 );
1989 
1990 
1991  if ( vl && vl->geometryType() != QgsWkbTypes::PolygonGeometry )
1992  {
1993  mRingFilterComboBox->hide();
1994  mRingsLabel->hide();
1995  }
1996 
1997  mHashRotationSpinBox->setClearValue( 0 );
1998  mSpinAverageAngleLength->setClearValue( 4.0 );
1999 
2000  connect( spinInterval, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setInterval );
2001  connect( mSpinOffsetAlongLine, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setOffsetAlongLine );
2002  connect( mSpinHashLength, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setHashLength );
2003  connect( mHashRotationSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setHashAngle );
2004  connect( chkRotateMarker, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setRotate );
2005  connect( spinOffset, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setOffset );
2006  connect( mSpinAverageAngleLength, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setAverageAngle );
2007  connect( radInterval, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2008  connect( radVertex, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2009  connect( radVertexLast, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2010  connect( radVertexFirst, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2011  connect( radCentralPoint, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2012  connect( radCurvePoint, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2013 }
2014 
2016 {
2017  if ( layer->layerType() != QLatin1String( "HashLine" ) )
2018  return;
2019 
2020  // layer type is correct, we can do the cast
2021  mLayer = static_cast<QgsHashedLineSymbolLayer *>( layer );
2022 
2023  // set values
2024  spinInterval->blockSignals( true );
2025  spinInterval->setValue( mLayer->interval() );
2026  spinInterval->blockSignals( false );
2027  mSpinOffsetAlongLine->blockSignals( true );
2028  mSpinOffsetAlongLine->setValue( mLayer->offsetAlongLine() );
2029  mSpinOffsetAlongLine->blockSignals( false );
2030  whileBlocking( mSpinHashLength )->setValue( mLayer->hashLength() );
2031  whileBlocking( mHashRotationSpinBox )->setValue( mLayer->hashAngle() );
2032  chkRotateMarker->blockSignals( true );
2033  chkRotateMarker->setChecked( mLayer->rotateSymbols() );
2034  chkRotateMarker->blockSignals( false );
2035  spinOffset->blockSignals( true );
2036  spinOffset->setValue( mLayer->offset() );
2037  spinOffset->blockSignals( false );
2039  radInterval->setChecked( true );
2040  else if ( mLayer->placement() == QgsTemplatedLineSymbolLayerBase::Vertex )
2041  radVertex->setChecked( true );
2043  radVertexLast->setChecked( true );
2045  radCentralPoint->setChecked( true );
2047  radCurvePoint->setChecked( true );
2048  else
2049  radVertexFirst->setChecked( true );
2050 
2051  // set units
2052  mIntervalUnitWidget->blockSignals( true );
2053  mIntervalUnitWidget->setUnit( mLayer->intervalUnit() );
2054  mIntervalUnitWidget->setMapUnitScale( mLayer->intervalMapUnitScale() );
2055  mIntervalUnitWidget->blockSignals( false );
2056  mOffsetUnitWidget->blockSignals( true );
2057  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
2058  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
2059  mOffsetUnitWidget->blockSignals( false );
2060  mOffsetAlongLineUnitWidget->blockSignals( true );
2061  mOffsetAlongLineUnitWidget->setUnit( mLayer->offsetAlongLineUnit() );
2062  mOffsetAlongLineUnitWidget->setMapUnitScale( mLayer->offsetAlongLineMapUnitScale() );
2063  mOffsetAlongLineUnitWidget->blockSignals( false );
2064  whileBlocking( mAverageAngleUnit )->setUnit( mLayer->averageAngleUnit() );
2065  whileBlocking( mAverageAngleUnit )->setMapUnitScale( mLayer->averageAngleMapUnitScale() );
2066  whileBlocking( mSpinAverageAngleLength )->setValue( mLayer->averageAngleLength() );
2067  whileBlocking( mHashLengthUnitWidget )->setUnit( mLayer->hashLengthUnit() );
2068  whileBlocking( mHashLengthUnitWidget )->setMapUnitScale( mLayer->hashLengthMapUnitScale() );
2069 
2070  whileBlocking( mRingFilterComboBox )->setCurrentIndex( mRingFilterComboBox->findData( mLayer->ringFilter() ) );
2071 
2072  setPlacement(); // update gui
2073 
2081 }
2082 
2084 {
2085  return mLayer;
2086 }
2087 
2088 void QgsHashedLineSymbolLayerWidget::setInterval( double val )
2089 {
2090  mLayer->setInterval( val );
2091  emit changed();
2092 }
2093 
2094 void QgsHashedLineSymbolLayerWidget::setOffsetAlongLine( double val )
2095 {
2096  mLayer->setOffsetAlongLine( val );
2097  emit changed();
2098 }
2099 
2100 void QgsHashedLineSymbolLayerWidget::setHashLength( double val )
2101 {
2102  mLayer->setHashLength( val );
2103  emit changed();
2104 }
2105 
2106 void QgsHashedLineSymbolLayerWidget::setHashAngle( double val )
2107 {
2108  mLayer->setHashAngle( val );
2109  emit changed();
2110 }
2111 
2112 void QgsHashedLineSymbolLayerWidget::setRotate()
2113 {
2114  mSpinAverageAngleLength->setEnabled( chkRotateMarker->isChecked() && ( radInterval->isChecked() || radCentralPoint->isChecked() ) );
2115  mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
2116 
2117  mLayer->setRotateSymbols( chkRotateMarker->isChecked() );
2118  emit changed();
2119 }
2120 
2121 void QgsHashedLineSymbolLayerWidget::setOffset()
2122 {
2123  mLayer->setOffset( spinOffset->value() );
2124  emit changed();
2125 }
2126 
2127 void QgsHashedLineSymbolLayerWidget::setPlacement()
2128 {
2129  bool interval = radInterval->isChecked();
2130  spinInterval->setEnabled( interval );
2131  mSpinOffsetAlongLine->setEnabled( radInterval->isChecked() || radVertexLast->isChecked() || radVertexFirst->isChecked() );
2132  mOffsetAlongLineUnitWidget->setEnabled( mSpinOffsetAlongLine->isEnabled() );
2133  mSpinAverageAngleLength->setEnabled( chkRotateMarker->isChecked() && ( radInterval->isChecked() || radCentralPoint->isChecked() ) );
2134  mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
2135  //mLayer->setPlacement( interval ? QgsMarkerLineSymbolLayer::Interval : QgsMarkerLineSymbolLayer::Vertex );
2136  if ( radInterval->isChecked() )
2138  else if ( radVertex->isChecked() )
2140  else if ( radVertexLast->isChecked() )
2142  else if ( radVertexFirst->isChecked() )
2144  else if ( radCurvePoint->isChecked() )
2146  else
2148 
2149  emit changed();
2150 }
2151 
2152 void QgsHashedLineSymbolLayerWidget::mIntervalUnitWidget_changed()
2153 {
2154  if ( mLayer )
2155  {
2156  mLayer->setIntervalUnit( mIntervalUnitWidget->unit() );
2157  mLayer->setIntervalMapUnitScale( mIntervalUnitWidget->getMapUnitScale() );
2158  emit changed();
2159  }
2160 }
2161 
2162 void QgsHashedLineSymbolLayerWidget::mOffsetUnitWidget_changed()
2163 {
2164  if ( mLayer )
2165  {
2166  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
2167  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
2168  emit changed();
2169  }
2170 }
2171 
2172 void QgsHashedLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed()
2173 {
2174  if ( mLayer )
2175  {
2176  mLayer->setOffsetAlongLineUnit( mOffsetAlongLineUnitWidget->unit() );
2177  mLayer->setOffsetAlongLineMapUnitScale( mOffsetAlongLineUnitWidget->getMapUnitScale() );
2178  }
2179  emit changed();
2180 }
2181 
2182 void QgsHashedLineSymbolLayerWidget::hashLengthUnitWidgetChanged()
2183 {
2184  if ( mLayer )
2185  {
2186  mLayer->setHashLengthUnit( mHashLengthUnitWidget->unit() );
2187  mLayer->setHashLengthMapUnitScale( mHashLengthUnitWidget->getMapUnitScale() );
2188  }
2189  emit changed();
2190 }
2191 
2192 void QgsHashedLineSymbolLayerWidget::averageAngleUnitChanged()
2193 {
2194  if ( mLayer )
2195  {
2196  mLayer->setAverageAngleUnit( mAverageAngleUnit->unit() );
2197  mLayer->setAverageAngleMapUnitScale( mAverageAngleUnit->getMapUnitScale() );
2198  }
2199  emit changed();
2200 }
2201 
2202 void QgsHashedLineSymbolLayerWidget::setAverageAngle( double val )
2203 {
2204  if ( mLayer )
2205  {
2206  mLayer->setAverageAngleLength( val );
2207  emit changed();
2208  }
2209 }
2210 
2212 
2213 
2215  : QgsSymbolLayerWidget( parent, vl )
2216 {
2217  mLayer = nullptr;
2218 
2219  setupUi( this );
2220 
2221  mSvgSourceLineEdit->setLastPathSettingsKey( QStringLiteral( "/UI/lastSVGMarkerDir" ) );
2222 
2223  connect( mSvgSourceLineEdit, &QgsSvgSourceLineEdit::sourceChanged, this, &QgsSvgMarkerSymbolLayerWidget::svgSourceChanged );
2224  connect( mChangeColorButton, &QgsColorButton::colorChanged, this, &QgsSvgMarkerSymbolLayerWidget::mChangeColorButton_colorChanged );
2225  connect( mChangeStrokeColorButton, &QgsColorButton::colorChanged, this, &QgsSvgMarkerSymbolLayerWidget::mChangeStrokeColorButton_colorChanged );
2226  connect( mStrokeWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
2227  connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
2228  connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
2229  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
2230  connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSvgMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
2231  connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSvgMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
2238  viewGroups->setHeaderHidden( true );
2239  mChangeColorButton->setAllowOpacity( true );
2240  mChangeColorButton->setColorDialogTitle( tr( "Select Fill color" ) );
2241  mChangeColorButton->setContext( QStringLiteral( "symbology" ) );
2242  mChangeStrokeColorButton->setAllowOpacity( true );
2243  mChangeStrokeColorButton->setColorDialogTitle( tr( "Select Stroke Color" ) );
2244  mChangeStrokeColorButton->setContext( QStringLiteral( "symbology" ) );
2245 
2246  mFillColorDDBtn->registerLinkedWidget( mChangeColorButton );
2247  mStrokeColorDDBtn->registerLinkedWidget( mChangeStrokeColorButton );
2248 
2249  spinOffsetX->setClearValue( 0.0 );
2250  spinOffsetY->setClearValue( 0.0 );
2251  spinAngle->setClearValue( 0.0 );
2252 
2253  mIconSize = std::max( 30, static_cast< int >( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().width( QStringLiteral( "XXXX" ) ) ) ) );
2254  viewImages->setGridSize( QSize( mIconSize * 1.2, mIconSize * 1.2 ) );
2255 
2256  populateList();
2257 
2258  connect( viewImages->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsSvgMarkerSymbolLayerWidget::setName );
2259  connect( viewGroups->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsSvgMarkerSymbolLayerWidget::populateIcons );
2260  connect( spinWidth, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setWidth );
2261  connect( spinHeight, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setHeight );
2262  connect( mLockAspectRatio, static_cast < void ( QgsRatioLockButton::* )( bool ) > ( &QgsRatioLockButton::lockChanged ), this, &QgsSvgMarkerSymbolLayerWidget::lockAspectRatioChanged );
2263  connect( spinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setAngle );
2264  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setOffset );
2265  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setOffset );
2266  connect( this, &QgsSymbolLayerWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::updateAssistantSymbol );
2267 
2268 
2269  //make a temporary symbol for the size assistant preview
2270  mAssistantPreviewSymbol.reset( new QgsMarkerSymbol() );
2271 
2272  if ( vectorLayer() )
2273  {
2274  mWidthDDBtn->setSymbol( mAssistantPreviewSymbol );
2275  mHeightDDBtn->setSymbol( mAssistantPreviewSymbol );
2276  }
2277 }
2278 
2279 #include <QTime>
2280 #include <QAbstractListModel>
2281 #include <QPixmapCache>
2282 #include <QStyle>
2283 
2284 
2286 {
2287  QAbstractItemModel *oldModel = viewGroups->model();
2289  viewGroups->setModel( g );
2290  delete oldModel;
2291 
2292  // Set the tree expanded at the first level
2293  int rows = g->rowCount( g->indexFromItem( g->invisibleRootItem() ) );
2294  for ( int i = 0; i < rows; i++ )
2295  {
2296  viewGroups->setExpanded( g->indexFromItem( g->item( i ) ), true );
2297  }
2298 
2299  // Initially load the icons in the List view without any grouping
2300  oldModel = viewImages->model();
2301  QgsSvgSelectorListModel *m = new QgsSvgSelectorListModel( viewImages, mIconSize );
2302  viewImages->setModel( m );
2303  delete oldModel;
2304 }
2305 
2306 void QgsSvgMarkerSymbolLayerWidget::populateIcons( const QModelIndex &idx )
2307 {
2308  QString path = idx.data( Qt::UserRole + 1 ).toString();
2309 
2310  QAbstractItemModel *oldModel = viewImages->model();
2311  QgsSvgSelectorListModel *m = new QgsSvgSelectorListModel( viewImages, path );
2312  viewImages->setModel( m );
2313  delete oldModel;
2314 
2315  connect( viewImages->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsSvgMarkerSymbolLayerWidget::setName );
2316 }
2317 
2319 {
2320  if ( !layer )
2321  {
2322  return;
2323  }
2324 
2325  //activate gui for svg parameters only if supported by the svg file
2326  bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2327  QColor defaultFill, defaultStroke;
2328  double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2329  bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
2330  QgsApplication::svgCache()->containsParams( layer->path(), hasFillParam, hasDefaultFillColor, defaultFill,
2331  hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity,
2332  hasStrokeParam, hasDefaultStrokeColor, defaultStroke,
2333  hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth,
2334  hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
2335  mChangeColorButton->setEnabled( hasFillParam );
2336  mChangeColorButton->setAllowOpacity( hasFillOpacityParam );
2337  mChangeStrokeColorButton->setEnabled( hasStrokeParam );
2338  mChangeStrokeColorButton->setAllowOpacity( hasStrokeOpacityParam );
2339  mStrokeWidthSpinBox->setEnabled( hasStrokeWidthParam );
2340 
2341  if ( hasFillParam )
2342  {
2343  QColor fill = layer->fillColor();
2344  double existingOpacity = hasFillOpacityParam ? fill.alphaF() : 1.0;
2345  if ( hasDefaultFillColor )
2346  {
2347  fill = defaultFill;
2348  }
2349  fill.setAlphaF( hasDefaultFillOpacity ? defaultFillOpacity : existingOpacity );
2350  mChangeColorButton->setColor( fill );
2351  }
2352  if ( hasStrokeParam )
2353  {
2354  QColor stroke = layer->strokeColor();
2355  double existingOpacity = hasStrokeOpacityParam ? stroke.alphaF() : 1.0;
2356  if ( hasDefaultStrokeColor )
2357  {
2358  stroke = defaultStroke;
2359  }
2360  stroke.setAlphaF( hasDefaultStrokeOpacity ? defaultStrokeOpacity : existingOpacity );
2361  mChangeStrokeColorButton->setColor( stroke );
2362  }
2363 
2364  whileBlocking( mSvgSourceLineEdit )->setSource( layer->path() );
2365 
2366  mStrokeWidthSpinBox->blockSignals( true );
2367  mStrokeWidthSpinBox->setValue( hasDefaultStrokeWidth ? defaultStrokeWidth : layer->strokeWidth() );
2368  mStrokeWidthSpinBox->blockSignals( false );
2369 
2370  bool preservedAspectRatio = layer->preservedAspectRatio();
2371  spinHeight->blockSignals( true );
2372  if ( preservedAspectRatio )
2373  {
2374  spinHeight->setValue( layer->size() );
2375  }
2376  else
2377  {
2378  spinHeight->setValue( layer->size() * layer->fixedAspectRatio() );
2379  }
2380  spinHeight->setEnabled( layer->defaultAspectRatio() > 0.0 );
2381  spinHeight->blockSignals( false );
2382  whileBlocking( mLockAspectRatio )->setLocked( preservedAspectRatio );
2383 }
2384 
2385 void QgsSvgMarkerSymbolLayerWidget::updateAssistantSymbol()
2386 {
2387  for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
2388  {
2389  mAssistantPreviewSymbol->deleteSymbolLayer( i );
2390  }
2391  mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
2393  if ( ddSize )
2394  mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
2395 }
2396 
2397 
2399 {
2400  if ( !layer )
2401  {
2402  return;
2403  }
2404 
2405  if ( layer->layerType() != QLatin1String( "SvgMarker" ) )
2406  return;
2407 
2408  // layer type is correct, we can do the cast
2409  mLayer = static_cast<QgsSvgMarkerSymbolLayer *>( layer );
2410 
2411  // set values
2412 
2413  QAbstractItemModel *m = viewImages->model();
2414  QItemSelectionModel *selModel = viewImages->selectionModel();
2415  for ( int i = 0; i < m->rowCount(); i++ )
2416  {
2417  QModelIndex idx( m->index( i, 0 ) );
2418  if ( m->data( idx ).toString() == mLayer->path() )
2419  {
2420  selModel->select( idx, QItemSelectionModel::SelectCurrent );
2421  selModel->setCurrentIndex( idx, QItemSelectionModel::SelectCurrent );
2422  setName( idx );
2423  break;
2424  }
2425  }
2426 
2427  spinWidth->blockSignals( true );
2428  spinWidth->setValue( mLayer->size() );
2429  spinWidth->blockSignals( false );
2430  spinAngle->blockSignals( true );
2431  spinAngle->setValue( mLayer->angle() );
2432  spinAngle->blockSignals( false );
2433 
2434  // without blocking signals the value gets changed because of slot setOffset()
2435  spinOffsetX->blockSignals( true );
2436  spinOffsetX->setValue( mLayer->offset().x() );
2437  spinOffsetX->blockSignals( false );
2438  spinOffsetY->blockSignals( true );
2439  spinOffsetY->setValue( mLayer->offset().y() );
2440  spinOffsetY->blockSignals( false );
2441 
2442  mSizeUnitWidget->blockSignals( true );
2443  mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
2444  mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
2445  mSizeUnitWidget->blockSignals( false );
2446  mStrokeWidthUnitWidget->blockSignals( true );
2447  mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
2448  mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
2449  mStrokeWidthUnitWidget->blockSignals( false );
2450  mOffsetUnitWidget->blockSignals( true );
2451  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
2452  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
2453  mOffsetUnitWidget->blockSignals( false );
2454 
2455  //anchor points
2456  mHorizontalAnchorComboBox->blockSignals( true );
2457  mVerticalAnchorComboBox->blockSignals( true );
2458  mHorizontalAnchorComboBox->setCurrentIndex( mLayer->horizontalAnchorPoint() );
2459  mVerticalAnchorComboBox->setCurrentIndex( mLayer->verticalAnchorPoint() );
2460  mHorizontalAnchorComboBox->blockSignals( false );
2461  mVerticalAnchorComboBox->blockSignals( false );
2462 
2463  setGuiForSvg( mLayer );
2464 
2475 
2476  updateAssistantSymbol();
2477 }
2478 
2480 {
2481  return mLayer;
2482 }
2483 
2485 {
2487  mSvgSourceLineEdit->setMessageBar( context.messageBar() );
2488 }
2489 
2490 void QgsSvgMarkerSymbolLayerWidget::setName( const QModelIndex &idx )
2491 {
2492  QString name = idx.data( Qt::UserRole ).toString();
2493  mLayer->setPath( name );
2494  whileBlocking( mSvgSourceLineEdit )->setSource( name );
2495 
2496  setGuiForSvg( mLayer );
2497  emit changed();
2498 }
2499 
2500 void QgsSvgMarkerSymbolLayerWidget::setWidth()
2501 {
2502  double defaultAspectRatio = mLayer->defaultAspectRatio();
2503  double fixedAspectRatio = 0.0;
2504  spinHeight->blockSignals( true );
2505  if ( defaultAspectRatio <= 0.0 )
2506  {
2507  spinHeight->setValue( spinWidth->value() );
2508  }
2509  else if ( mLockAspectRatio->locked() )
2510  {
2511  spinHeight->setValue( spinWidth->value() * defaultAspectRatio );
2512  }
2513  else
2514  {
2515  fixedAspectRatio = spinHeight->value() / spinWidth->value();
2516  }
2517  spinHeight->blockSignals( false );
2518  mLayer->setSize( spinWidth->value() );
2519  mLayer->setFixedAspectRatio( fixedAspectRatio );
2520  emit changed();
2521 }
2522 
2523 void QgsSvgMarkerSymbolLayerWidget::setHeight()
2524 {
2525  double defaultAspectRatio = mLayer->defaultAspectRatio();
2526  double fixedAspectRatio = 0.0;
2527  spinWidth->blockSignals( true );
2528  if ( defaultAspectRatio <= 0.0 )
2529  {
2530  spinWidth->setValue( spinHeight->value() );
2531  }
2532  else if ( mLockAspectRatio->locked() )
2533  {
2534  spinWidth->setValue( spinHeight->value() / defaultAspectRatio );
2535  }
2536  else
2537  {
2538  fixedAspectRatio = spinHeight->value() / spinWidth->value();
2539  }
2540  spinWidth->blockSignals( false );
2541  mLayer->setSize( spinWidth->value() );
2542  mLayer->setFixedAspectRatio( fixedAspectRatio );
2543  emit changed();
2544 }
2545 
2546 void QgsSvgMarkerSymbolLayerWidget::lockAspectRatioChanged( const bool locked )
2547 {
2548  //spinHeight->setEnabled( !locked );
2549  double defaultAspectRatio = mLayer->defaultAspectRatio();
2550  if ( defaultAspectRatio <= 0.0 )
2551  {
2552  whileBlocking( mLockAspectRatio )->setLocked( true );
2553  }
2554  else if ( locked )
2555  {
2556  mLayer->setFixedAspectRatio( 0.0 );
2557  setWidth();
2558  }
2559  else
2560  {
2561  mLayer->setFixedAspectRatio( spinHeight->value() / spinWidth->value() );
2562  }
2563  //emit changed();
2564 }
2565 
2566 void QgsSvgMarkerSymbolLayerWidget::setAngle()
2567 {
2568  mLayer->setAngle( spinAngle->value() );
2569  emit changed();
2570 }
2571 
2572 void QgsSvgMarkerSymbolLayerWidget::setOffset()
2573 {
2574  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
2575  emit changed();
2576 }
2577 
2578 void QgsSvgMarkerSymbolLayerWidget::svgSourceChanged( const QString &text )
2579 {
2580  mLayer->setPath( text );
2581  setGuiForSvg( mLayer );
2582  emit changed();
2583 }
2584 
2585 void QgsSvgMarkerSymbolLayerWidget::mChangeColorButton_colorChanged( const QColor &color )
2586 {
2587  if ( !mLayer )
2588  {
2589  return;
2590  }
2591 
2592  mLayer->setFillColor( color );
2593  emit changed();
2594 }
2595 
2596 void QgsSvgMarkerSymbolLayerWidget::mChangeStrokeColorButton_colorChanged( const QColor &color )
2597 {
2598  if ( !mLayer )
2599  {
2600  return;
2601  }
2602 
2603  mLayer->setStrokeColor( color );
2604  emit changed();
2605 }
2606 
2607 void QgsSvgMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
2608 {
2609  if ( mLayer )
2610  {
2611  mLayer->setStrokeWidth( d );
2612  emit changed();
2613  }
2614 }
2615 
2616 void QgsSvgMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
2617 {
2618  if ( mLayer )
2619  {
2620  mLayer->setSizeUnit( mSizeUnitWidget->unit() );
2621  mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
2622  emit changed();
2623  }
2624 }
2625 
2626 void QgsSvgMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
2627 {
2628  if ( mLayer )
2629  {
2630  mLayer->setStrokeWidthUnit( mStrokeWidthUnitWidget->unit() );
2631  mLayer->setStrokeWidthMapUnitScale( mStrokeWidthUnitWidget->getMapUnitScale() );
2632  emit changed();
2633  }
2634 }
2635 
2636 void QgsSvgMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
2637 {
2638  if ( mLayer )
2639  {
2640  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
2641  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
2642  emit changed();
2643  }
2644 }
2645 
2646 void QgsSvgMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
2647 {
2648  if ( mLayer )
2649  {
2651  emit changed();
2652  }
2653 }
2654 
2655 void QgsSvgMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
2656 {
2657  if ( mLayer )
2658  {
2660  emit changed();
2661  }
2662 }
2663 
2665 
2667 {
2668  mLayer = nullptr;
2669  setupUi( this );
2670  connect( mTextureWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mTextureWidthSpinBox_valueChanged );
2671  connect( mSvgSourceLineEdit, &QgsSvgSourceLineEdit::sourceChanged, this, &QgsSVGFillSymbolLayerWidget::svgSourceChanged );
2672  connect( mRotationSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mRotationSpinBox_valueChanged );
2673  connect( mChangeColorButton, &QgsColorButton::colorChanged, this, &QgsSVGFillSymbolLayerWidget::mChangeColorButton_colorChanged );
2674  connect( mChangeStrokeColorButton, &QgsColorButton::colorChanged, this, &QgsSVGFillSymbolLayerWidget::mChangeStrokeColorButton_colorChanged );
2675  connect( mStrokeWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
2676  connect( mTextureWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSVGFillSymbolLayerWidget::mTextureWidthUnitWidget_changed );
2677  connect( mSvgStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSVGFillSymbolLayerWidget::mSvgStrokeWidthUnitWidget_changed );
2682  mSvgTreeView->setHeaderHidden( true );
2683  insertIcons();
2684 
2685  mRotationSpinBox->setClearValue( 0.0 );
2686 
2687  mChangeColorButton->setColorDialogTitle( tr( "Select Fill Color" ) );
2688  mChangeColorButton->setContext( QStringLiteral( "symbology" ) );
2689  mChangeStrokeColorButton->setColorDialogTitle( tr( "Select Stroke Color" ) );
2690  mChangeStrokeColorButton->setContext( QStringLiteral( "symbology" ) );
2691 
2692  mFilColorDDBtn->registerLinkedWidget( mChangeColorButton );
2693  mStrokeColorDDBtn->registerLinkedWidget( mChangeStrokeColorButton );
2694 
2695  connect( mSvgListView->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsSVGFillSymbolLayerWidget::setFile );
2696  connect( mSvgTreeView->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsSVGFillSymbolLayerWidget::populateIcons );
2697 }
2698 
2700 {
2701  if ( !layer )
2702  {
2703  return;
2704  }
2705 
2706  if ( layer->layerType() != QLatin1String( "SVGFill" ) )
2707  {
2708  return;
2709  }
2710 
2711  mLayer = dynamic_cast<QgsSVGFillSymbolLayer *>( layer );
2712  if ( mLayer )
2713  {
2714  double width = mLayer->patternWidth();
2715  mTextureWidthSpinBox->blockSignals( true );
2716  mTextureWidthSpinBox->setValue( width );
2717  mTextureWidthSpinBox->blockSignals( false );
2718  whileBlocking( mSvgSourceLineEdit )->setSource( mLayer->svgFilePath() );
2719  mRotationSpinBox->blockSignals( true );
2720  mRotationSpinBox->setValue( mLayer->angle() );
2721  mRotationSpinBox->blockSignals( false );
2722  mTextureWidthUnitWidget->blockSignals( true );
2723  mTextureWidthUnitWidget->setUnit( mLayer->patternWidthUnit() );
2724  mTextureWidthUnitWidget->setMapUnitScale( mLayer->patternWidthMapUnitScale() );
2725  mTextureWidthUnitWidget->blockSignals( false );
2726  mSvgStrokeWidthUnitWidget->blockSignals( true );
2727  mSvgStrokeWidthUnitWidget->setUnit( mLayer->svgStrokeWidthUnit() );
2728  mSvgStrokeWidthUnitWidget->setMapUnitScale( mLayer->svgStrokeWidthMapUnitScale() );
2729  mSvgStrokeWidthUnitWidget->blockSignals( false );
2730  mChangeColorButton->blockSignals( true );
2731  mChangeColorButton->setColor( mLayer->svgFillColor() );
2732  mChangeColorButton->blockSignals( false );
2733  mChangeStrokeColorButton->blockSignals( true );
2734  mChangeStrokeColorButton->setColor( mLayer->svgStrokeColor() );
2735  mChangeStrokeColorButton->blockSignals( false );
2736  mStrokeWidthSpinBox->blockSignals( true );
2737  mStrokeWidthSpinBox->setValue( mLayer->svgStrokeWidth() );
2738  mStrokeWidthSpinBox->blockSignals( false );
2739  }
2740  updateParamGui( false );
2741 
2748 }
2749 
2751 {
2752  return mLayer;
2753 }
2754 
2756 {
2758  mSvgSourceLineEdit->setMessageBar( context.messageBar() );
2759 }
2760 
2761 void QgsSVGFillSymbolLayerWidget::mTextureWidthSpinBox_valueChanged( double d )
2762 {
2763  if ( mLayer )
2764  {
2765  mLayer->setPatternWidth( d );
2766  emit changed();
2767  }
2768 }
2769 
2770 void QgsSVGFillSymbolLayerWidget::svgSourceChanged( const QString &text )
2771 {
2772  if ( !mLayer )
2773  {
2774  return;
2775  }
2776 
2777  mLayer->setSvgFilePath( text );
2778  updateParamGui();
2779  emit changed();
2780 }
2781 
2782 void QgsSVGFillSymbolLayerWidget::setFile( const QModelIndex &item )
2783 {
2784  QString file = item.data( Qt::UserRole ).toString();
2785  mLayer->setSvgFilePath( file );
2786  whileBlocking( mSvgSourceLineEdit )->setSource( file );
2787 
2788  updateParamGui();
2789  emit changed();
2790 }
2791 
2793 {
2794  QAbstractItemModel *oldModel = mSvgTreeView->model();
2795  QgsSvgSelectorGroupsModel *g = new QgsSvgSelectorGroupsModel( mSvgTreeView );
2796  mSvgTreeView->setModel( g );
2797  delete oldModel;
2798 
2799  // Set the tree expanded at the first level
2800  int rows = g->rowCount( g->indexFromItem( g->invisibleRootItem() ) );
2801  for ( int i = 0; i < rows; i++ )
2802  {
2803  mSvgTreeView->setExpanded( g->indexFromItem( g->item( i ) ), true );
2804  }
2805 
2806  oldModel = mSvgListView->model();
2807  QgsSvgSelectorListModel *m = new QgsSvgSelectorListModel( mSvgListView );
2808  mSvgListView->setModel( m );
2809  delete oldModel;
2810 }
2811 
2812 void QgsSVGFillSymbolLayerWidget::populateIcons( const QModelIndex &idx )
2813 {
2814  QString path = idx.data( Qt::UserRole + 1 ).toString();
2815 
2816  QAbstractItemModel *oldModel = mSvgListView->model();
2817  QgsSvgSelectorListModel *m = new QgsSvgSelectorListModel( mSvgListView, path );
2818  mSvgListView->setModel( m );
2819  delete oldModel;
2820 
2821  connect( mSvgListView->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsSVGFillSymbolLayerWidget::setFile );
2822 }
2823 
2824 
2825 void QgsSVGFillSymbolLayerWidget::mRotationSpinBox_valueChanged( double d )
2826 {
2827  if ( mLayer )
2828  {
2829  mLayer->setAngle( d );
2830  emit changed();
2831  }
2832 }
2833 
2835 {
2836  //activate gui for svg parameters only if supported by the svg file
2837  bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2838  QColor defaultFill, defaultStroke;
2839  double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2840  bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
2841  QgsApplication::svgCache()->containsParams( mSvgSourceLineEdit->source(), hasFillParam, hasDefaultFillColor, defaultFill,
2842  hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity,
2843  hasStrokeParam, hasDefaultStrokeColor, defaultStroke,
2844  hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth,
2845  hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
2846  if ( resetValues )
2847  {
2848  QColor fill = mChangeColorButton->color();
2849  double newOpacity = hasFillOpacityParam ? fill.alphaF() : 1.0;
2850  if ( hasDefaultFillColor )
2851  {
2852  fill = defaultFill;
2853  }
2854  fill.setAlphaF( hasDefaultFillOpacity ? defaultFillOpacity : newOpacity );
2855  mChangeColorButton->setColor( fill );
2856  }
2857  mChangeColorButton->setEnabled( hasFillParam );
2858  mChangeColorButton->setAllowOpacity( hasFillOpacityParam );
2859  if ( resetValues )
2860  {
2861  QColor stroke = mChangeStrokeColorButton->color();
2862  double newOpacity = hasStrokeOpacityParam ? stroke.alphaF() : 1.0;
2863  if ( hasDefaultStrokeColor )
2864  {
2865  stroke = defaultStroke;
2866  }
2867  stroke.setAlphaF( hasDefaultStrokeOpacity ? defaultStrokeOpacity : newOpacity );
2868  mChangeStrokeColorButton->setColor( stroke );
2869  }
2870  mChangeStrokeColorButton->setEnabled( hasStrokeParam );
2871  mChangeStrokeColorButton->setAllowOpacity( hasStrokeOpacityParam );
2872  if ( hasDefaultStrokeWidth && resetValues )
2873  {
2874  mStrokeWidthSpinBox->setValue( defaultStrokeWidth );
2875  }
2876  mStrokeWidthSpinBox->setEnabled( hasStrokeWidthParam );
2877 }
2878 
2879 void QgsSVGFillSymbolLayerWidget::mChangeColorButton_colorChanged( const QColor &color )
2880 {
2881  if ( !mLayer )
2882  {
2883  return;
2884  }
2885 
2886  mLayer->setSvgFillColor( color );
2887  emit changed();
2888 }
2889 
2890 void QgsSVGFillSymbolLayerWidget::mChangeStrokeColorButton_colorChanged( const QColor &color )
2891 {
2892  if ( !mLayer )
2893  {
2894  return;
2895  }
2896 
2897  mLayer->setSvgStrokeColor( color );
2898  emit changed();
2899 }
2900 
2901 void QgsSVGFillSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
2902 {
2903  if ( mLayer )
2904  {
2905  mLayer->setSvgStrokeWidth( d );
2906  emit changed();
2907  }
2908 }
2909 
2910 void QgsSVGFillSymbolLayerWidget::mTextureWidthUnitWidget_changed()
2911 {
2912  if ( mLayer )
2913  {
2914  mLayer->setPatternWidthUnit( mTextureWidthUnitWidget->unit() );
2915  mLayer->setPatternWidthMapUnitScale( mTextureWidthUnitWidget->getMapUnitScale() );
2916  emit changed();
2917  }
2918 }
2919 
2920 void QgsSVGFillSymbolLayerWidget::mSvgStrokeWidthUnitWidget_changed()
2921 {
2922  if ( mLayer )
2923  {
2924  mLayer->setSvgStrokeWidthUnit( mSvgStrokeWidthUnitWidget->unit() );
2925  mLayer->setSvgStrokeWidthMapUnitScale( mSvgStrokeWidthUnitWidget->getMapUnitScale() );
2926  emit changed();
2927  }
2928 }
2929 
2931 
2933  QgsSymbolLayerWidget( parent, vl )
2934 {
2935  setupUi( this );
2936  connect( mAngleSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLinePatternFillSymbolLayerWidget::mAngleSpinBox_valueChanged );
2937  connect( mDistanceSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLinePatternFillSymbolLayerWidget::mDistanceSpinBox_valueChanged );
2938  connect( mOffsetSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLinePatternFillSymbolLayerWidget::mOffsetSpinBox_valueChanged );
2939  connect( mDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsLinePatternFillSymbolLayerWidget::mDistanceUnitWidget_changed );
2940  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsLinePatternFillSymbolLayerWidget::mOffsetUnitWidget_changed );
2945  mOffsetSpinBox->setClearValue( 0 );
2946  mAngleSpinBox->setClearValue( 0 );
2947 }
2948 
2950 {
2951  if ( layer->layerType() != QLatin1String( "LinePatternFill" ) )
2952  {
2953  return;
2954  }
2955 
2956  QgsLinePatternFillSymbolLayer *patternLayer = static_cast<QgsLinePatternFillSymbolLayer *>( layer );
2957  if ( patternLayer )
2958  {
2959  mLayer = patternLayer;
2960  mAngleSpinBox->blockSignals( true );
2961  mAngleSpinBox->setValue( mLayer->lineAngle() );
2962  mAngleSpinBox->blockSignals( false );
2963  mDistanceSpinBox->blockSignals( true );
2964  mDistanceSpinBox->setValue( mLayer->distance() );
2965  mDistanceSpinBox->blockSignals( false );
2966  mOffsetSpinBox->blockSignals( true );
2967  mOffsetSpinBox->setValue( mLayer->offset() );
2968  mOffsetSpinBox->blockSignals( false );
2969 
2970  //units
2971  mDistanceUnitWidget->blockSignals( true );
2972  mDistanceUnitWidget->setUnit( mLayer->distanceUnit() );
2973  mDistanceUnitWidget->setMapUnitScale( mLayer->distanceMapUnitScale() );
2974  mDistanceUnitWidget->blockSignals( false );
2975  mOffsetUnitWidget->blockSignals( true );
2976  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
2977  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
2978  mOffsetUnitWidget->blockSignals( false );
2979  }
2980 
2983 }
2984 
2986 {
2987  return mLayer;
2988 }
2989 
2990 void QgsLinePatternFillSymbolLayerWidget::mAngleSpinBox_valueChanged( double d )
2991 {
2992  if ( mLayer )
2993  {
2994  mLayer->setLineAngle( d );
2995  emit changed();
2996  }
2997 }
2998 
2999 void QgsLinePatternFillSymbolLayerWidget::mDistanceSpinBox_valueChanged( double d )
3000 {
3001  if ( mLayer )
3002  {
3003  mLayer->setDistance( d );
3004  emit changed();
3005  }
3006 }
3007 
3008 void QgsLinePatternFillSymbolLayerWidget::mOffsetSpinBox_valueChanged( double d )
3009 {
3010  if ( mLayer )
3011  {
3012  mLayer->setOffset( d );
3013  emit changed();
3014  }
3015 }
3016 
3017 void QgsLinePatternFillSymbolLayerWidget::mDistanceUnitWidget_changed()
3018 {
3019  if ( mLayer )
3020  {
3021  mLayer->setDistanceUnit( mDistanceUnitWidget->unit() );
3022  mLayer->setDistanceMapUnitScale( mDistanceUnitWidget->getMapUnitScale() );
3023  emit changed();
3024  }
3025 }
3026 
3027 void QgsLinePatternFillSymbolLayerWidget::mOffsetUnitWidget_changed()
3028 {
3029  if ( mLayer )
3030  {
3031  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
3032  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
3033  emit changed();
3034  }
3035 }
3036 
3038 
3040  QgsSymbolLayerWidget( parent, vl )
3041 {
3042  setupUi( this );
3043  connect( mHorizontalDistanceSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceSpinBox_valueChanged );
3044  connect( mVerticalDistanceSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceSpinBox_valueChanged );
3045  connect( mHorizontalDisplacementSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementSpinBox_valueChanged );
3046  connect( mVerticalDisplacementSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementSpinBox_valueChanged );
3047  connect( mHorizontalOffsetSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetSpinBox_valueChanged );
3048  connect( mVerticalOffsetSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetSpinBox_valueChanged );
3049  connect( mHorizontalDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceUnitWidget_changed );
3050  connect( mVerticalDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceUnitWidget_changed );
3051  connect( mHorizontalDisplacementUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementUnitWidget_changed );
3052  connect( mVerticalDisplacementUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementUnitWidget_changed );
3053  connect( mHorizontalOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetUnitWidget_changed );
3054  connect( mVerticalOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetUnitWidget_changed );
3067 }
3068 
3069 
3071 {
3072  if ( !layer || layer->layerType() != QLatin1String( "PointPatternFill" ) )
3073  {
3074  return;
3075  }
3076 
3077  mLayer = static_cast<QgsPointPatternFillSymbolLayer *>( layer );
3078  whileBlocking( mHorizontalDistanceSpinBox )->setValue( mLayer->distanceX() );
3079  whileBlocking( mVerticalDistanceSpinBox )->setValue( mLayer->distanceY() );
3080  whileBlocking( mHorizontalDisplacementSpinBox )->setValue( mLayer->displacementX() );
3081  whileBlocking( mVerticalDisplacementSpinBox )->setValue( mLayer->displacementY() );
3082  whileBlocking( mHorizontalOffsetSpinBox )->setValue( mLayer->offsetX() );
3083  whileBlocking( mVerticalOffsetSpinBox )->setValue( mLayer->offsetY() );
3084 
3085  mHorizontalDistanceUnitWidget->blockSignals( true );
3086  mHorizontalDistanceUnitWidget->setUnit( mLayer->distanceXUnit() );
3087  mHorizontalDistanceUnitWidget->setMapUnitScale( mLayer->distanceXMapUnitScale() );
3088  mHorizontalDistanceUnitWidget->blockSignals( false );
3089  mVerticalDistanceUnitWidget->blockSignals( true );
3090  mVerticalDistanceUnitWidget->setUnit( mLayer->distanceYUnit() );
3091  mVerticalDistanceUnitWidget->setMapUnitScale( mLayer->distanceYMapUnitScale() );
3092  mVerticalDistanceUnitWidget->blockSignals( false );
3093  mHorizontalDisplacementUnitWidget->blockSignals( true );
3094  mHorizontalDisplacementUnitWidget->setUnit( mLayer->displacementXUnit() );
3095  mHorizontalDisplacementUnitWidget->setMapUnitScale( mLayer->displacementXMapUnitScale() );
3096  mHorizontalDisplacementUnitWidget->blockSignals( false );
3097  mVerticalDisplacementUnitWidget->blockSignals( true );
3098  mVerticalDisplacementUnitWidget->setUnit( mLayer->displacementYUnit() );
3099  mVerticalDisplacementUnitWidget->setMapUnitScale( mLayer->displacementYMapUnitScale() );
3100  mVerticalDisplacementUnitWidget->blockSignals( false );
3101  mHorizontalOffsetUnitWidget->blockSignals( true );
3102  mHorizontalOffsetUnitWidget->setUnit( mLayer->offsetXUnit() );
3103  mHorizontalOffsetUnitWidget->setMapUnitScale( mLayer->offsetXMapUnitScale() );
3104  mHorizontalOffsetUnitWidget->blockSignals( false );
3105  mVerticalOffsetUnitWidget->blockSignals( true );
3106  mVerticalOffsetUnitWidget->setUnit( mLayer->offsetYUnit() );
3107  mVerticalOffsetUnitWidget->setMapUnitScale( mLayer->offsetYMapUnitScale() );
3108  mVerticalOffsetUnitWidget->blockSignals( false );
3109 
3110  registerDataDefinedButton( mHorizontalDistanceDDBtn, QgsSymbolLayer::PropertyDistanceX );
3112  registerDataDefinedButton( mHorizontalDisplacementDDBtn, QgsSymbolLayer::PropertyDisplacementX );
3116 }
3117 
3119 {
3120  return mLayer;
3121 }
3122 
3123 void QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceSpinBox_valueChanged( double d )
3124 {
3125  if ( mLayer )
3126  {
3127  mLayer->setDistanceX( d );
3128  emit changed();
3129  }
3130 }
3131 
3132 void QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceSpinBox_valueChanged( double d )
3133 {
3134  if ( mLayer )
3135  {
3136  mLayer->setDistanceY( d );
3137  emit changed();
3138  }
3139 }
3140 
3141 void QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementSpinBox_valueChanged( double d )
3142 {
3143  if ( mLayer )
3144  {
3145  mLayer->setDisplacementX( d );
3146  emit changed();
3147  }
3148 }
3149 
3150 void QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementSpinBox_valueChanged( double d )
3151 {
3152  if ( mLayer )
3153  {
3154  mLayer->setDisplacementY( d );
3155  emit changed();
3156  }
3157 }
3158 
3159 void QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetSpinBox_valueChanged( double d )
3160 {
3161  if ( mLayer )
3162  {
3163  mLayer->setOffsetX( d );
3164  emit changed();
3165  }
3166 }
3167 
3168 void QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetSpinBox_valueChanged( double d )
3169 {
3170  if ( mLayer )
3171  {
3172  mLayer->setOffsetY( d );
3173  emit changed();
3174  }
3175 }
3176 
3177 void QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceUnitWidget_changed()
3178 {
3179  if ( mLayer )
3180  {
3181  mLayer->setDistanceXUnit( mHorizontalDistanceUnitWidget->unit() );
3182  mLayer->setDistanceXMapUnitScale( mHorizontalDistanceUnitWidget->getMapUnitScale() );
3183  emit changed();
3184  }
3185 }
3186 
3187 void QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceUnitWidget_changed()
3188 {
3189  if ( mLayer )
3190  {
3191  mLayer->setDistanceYUnit( mVerticalDistanceUnitWidget->unit() );
3192  mLayer->setDistanceYMapUnitScale( mVerticalDistanceUnitWidget->getMapUnitScale() );
3193  emit changed();
3194  }
3195 }
3196 
3197 void QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementUnitWidget_changed()
3198 {
3199  if ( mLayer )
3200  {
3201  mLayer->setDisplacementXUnit( mHorizontalDisplacementUnitWidget->unit() );
3202  mLayer->setDisplacementXMapUnitScale( mHorizontalDisplacementUnitWidget->getMapUnitScale() );
3203  emit changed();
3204  }
3205 }
3206 
3207 void QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementUnitWidget_changed()
3208 {
3209  if ( mLayer )
3210  {
3211  mLayer->setDisplacementYUnit( mVerticalDisplacementUnitWidget->unit() );
3212  mLayer->setDisplacementYMapUnitScale( mVerticalDisplacementUnitWidget->getMapUnitScale() );
3213  emit changed();
3214  }
3215 }
3216 
3217 void QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetUnitWidget_changed()
3218 {
3219  if ( mLayer )
3220  {
3221  mLayer->setOffsetXUnit( mHorizontalOffsetUnitWidget->unit() );
3222  mLayer->setOffsetXMapUnitScale( mHorizontalOffsetUnitWidget->getMapUnitScale() );
3223  emit changed();
3224  }
3225 }
3226 
3227 void QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetUnitWidget_changed()
3228 {
3229  if ( mLayer )
3230  {
3231  mLayer->setOffsetYUnit( mVerticalOffsetUnitWidget->unit() );
3232  mLayer->setOffsetYMapUnitScale( mVerticalOffsetUnitWidget->getMapUnitScale() );
3233  emit changed();
3234  }
3235 }
3236 
3238 
3240  : QgsSymbolLayerWidget( parent, vl )
3241 {
3242  mLayer = nullptr;
3243 
3244  setupUi( this );
3245  connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
3246  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
3247  connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
3248  connect( mStrokeWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
3249  connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
3250  connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
3257 
3258  widgetChar = new CharacterWidget();
3259  scrollArea->setWidget( widgetChar );
3260  scrollArea->setVerticalOnly( true );
3261 
3262  btnColor->setAllowOpacity( true );
3263  btnColor->setColorDialogTitle( tr( "Select Symbol Fill Color" ) );
3264  btnColor->setContext( QStringLiteral( "symbology" ) );
3265  btnStrokeColor->setAllowOpacity( true );
3266  btnStrokeColor->setColorDialogTitle( tr( "Select Symbol Stroke Color" ) );
3267  btnStrokeColor->setContext( QStringLiteral( "symbology" ) );
3268 
3269  mColorDDBtn->registerLinkedWidget( btnColor );
3270  mStrokeColorDDBtn->registerLinkedWidget( btnStrokeColor );
3271 
3272  spinOffsetX->setClearValue( 0.0 );
3273  spinOffsetY->setClearValue( 0.0 );
3274  spinAngle->setClearValue( 0.0 );
3275 
3276  //make a temporary symbol for the size assistant preview
3277  mAssistantPreviewSymbol.reset( new QgsMarkerSymbol() );
3278 
3279  if ( vectorLayer() )
3280  mSizeDDBtn->setSymbol( mAssistantPreviewSymbol );
3281 
3282  connect( cboFont, &QFontComboBox::currentFontChanged, this, &QgsFontMarkerSymbolLayerWidget::setFontFamily );
3283  connect( spinSize, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setSize );
3284  connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::penJoinStyleChanged );
3287  connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::penJoinStyleChanged );
3288  connect( spinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setAngle );
3289  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setOffset );
3290  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setOffset );
3292  connect( mCharLineEdit, &QLineEdit::textChanged, this, &QgsFontMarkerSymbolLayerWidget::setCharacterFromText );
3293 
3294  connect( this, &QgsSymbolLayerWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::updateAssistantSymbol );
3295 }
3296 
3298 {
3299  if ( layer->layerType() != QLatin1String( "FontMarker" ) )
3300  return;
3301 
3302  // layer type is correct, we can do the cast
3303  mLayer = static_cast<QgsFontMarkerSymbolLayer *>( layer );
3304 
3305  QFont layerFont( mLayer->fontFamily() );
3306  // set values
3307  whileBlocking( cboFont )->setCurrentFont( layerFont );
3308  whileBlocking( spinSize )->setValue( mLayer->size() );
3309  whileBlocking( btnColor )->setColor( mLayer->color() );
3310  whileBlocking( btnStrokeColor )->setColor( mLayer->strokeColor() );
3311  whileBlocking( mStrokeWidthSpinBox )->setValue( mLayer->strokeWidth() );
3312  whileBlocking( spinAngle )->setValue( mLayer->angle() );
3313 
3314  widgetChar->blockSignals( true );
3315  widgetChar->setFont( layerFont );
3316  if ( mLayer->character().length() == 1 )
3317  {
3318  widgetChar->setCharacter( mLayer->character().at( 0 ) );
3319  }
3320  widgetChar->blockSignals( false );
3321  whileBlocking( mCharLineEdit )->setText( mLayer->character() );
3322 
3323  //block
3324  whileBlocking( spinOffsetX )->setValue( mLayer->offset().x() );
3325  whileBlocking( spinOffsetY )->setValue( mLayer->offset().y() );
3326 
3327  mSizeUnitWidget->blockSignals( true );
3328  mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
3329  mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
3330  mSizeUnitWidget->blockSignals( false );
3331 
3332  mStrokeWidthUnitWidget->blockSignals( true );
3333  mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
3334  mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
3335  mStrokeWidthUnitWidget->blockSignals( false );
3336 
3337  mOffsetUnitWidget->blockSignals( true );
3338  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
3339  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
3340  mOffsetUnitWidget->blockSignals( false );
3341 
3342  whileBlocking( cboJoinStyle )->setPenJoinStyle( mLayer->penJoinStyle() );
3343 
3344  //anchor points
3345  whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mLayer->horizontalAnchorPoint() );
3346  whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mLayer->verticalAnchorPoint() );
3347 
3358 
3359  updateAssistantSymbol();
3360 }
3361 
3363 {
3364  return mLayer;
3365 }
3366 
3368 {
3369  mLayer->setFontFamily( font.family() );
3370  widgetChar->setFont( font );
3371  emit changed();
3372 }
3373 
3374 void QgsFontMarkerSymbolLayerWidget::setColor( const QColor &color )
3375 {
3376  mLayer->setColor( color );
3377  emit changed();
3378 }
3379 
3381 {
3382  mLayer->setStrokeColor( color );
3383  emit changed();
3384 }
3385 
3387 {
3388  mLayer->setSize( size );
3389  //widgetChar->updateSize(size);
3390  emit changed();
3391 }
3392 
3394 {
3395  mLayer->setAngle( angle );
3396  emit changed();
3397 }
3398 
3400 {
3401  if ( text.isEmpty() )
3402  return;
3403 
3404  // take the last character of a string for a better experience when users cycle through several characters on their keyboard
3405  QString character = text;
3406  if ( text.contains( QRegularExpression( QStringLiteral( "^0x[0-9a-fA-F]{1,4}$" ) ) ) )
3407  {
3408  bool ok = false;
3409  unsigned int value = text.toUInt( &ok, 0 );
3410  if ( ok )
3411  character = QChar( value );
3412  }
3413 
3414  if ( character != mLayer->character() )
3415  {
3416  mLayer->setCharacter( character );
3417  if ( mLayer->character().length() == 1 )
3418  {
3419  whileBlocking( widgetChar )->setCharacter( mLayer->character().at( 0 ) );
3420  }
3421  else
3422  {
3424  }
3425  emit changed();
3426  }
3427 }
3428 
3430 {
3431  mLayer->setCharacter( chr );
3432  whileBlocking( mCharLineEdit )->setText( chr );
3433  emit changed();
3434 }
3435 
3436 void QgsFontMarkerSymbolLayerWidget::setOffset()
3437 {
3438  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
3439  emit changed();
3440 }
3441 
3442 void QgsFontMarkerSymbolLayerWidget::penJoinStyleChanged()
3443 {
3444  mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
3445  emit changed();
3446 }
3447 
3448 void QgsFontMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
3449 {
3450  if ( mLayer )
3451  {
3452  mLayer->setSizeUnit( mSizeUnitWidget->unit() );
3453  mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
3454  emit changed();
3455  }
3456 }
3457 
3458 void QgsFontMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
3459 {
3460  if ( mLayer )
3461  {
3462  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
3463  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
3464  emit changed();
3465  }
3466 }
3467 
3468 void QgsFontMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
3469 {
3470  if ( mLayer )
3471  {
3472  mLayer->setStrokeWidthUnit( mSizeUnitWidget->unit() );
3473  mLayer->setStrokeWidthMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
3474  emit changed();
3475  }
3476 }
3477 
3478 void QgsFontMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
3479 {
3480  if ( mLayer )
3481  {
3483  emit changed();
3484  }
3485 }
3486 
3487 void QgsFontMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
3488 {
3489  if ( mLayer )
3490  {
3492  emit changed();
3493  }
3494 }
3495 
3496 void QgsFontMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
3497 {
3498  if ( mLayer )
3499  {
3500  mLayer->setStrokeWidth( d );
3501  emit changed();
3502  }
3503 }
3504 
3505 void QgsFontMarkerSymbolLayerWidget::updateAssistantSymbol()
3506 {
3507  for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
3508  {
3509  mAssistantPreviewSymbol->deleteSymbolLayer( i );
3510  }
3511  mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
3513  if ( ddSize )
3514  mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
3515 }
3516 
3518 
3519 
3521  : QgsSymbolLayerWidget( parent, vl )
3522 {
3523  mLayer = nullptr;
3524 
3525  setupUi( this );
3526  connect( mDrawInsideCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mDrawInsideCheckBox_stateChanged );
3527  connect( mDrawAllPartsCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mDrawAllPartsCheckBox_stateChanged );
3528 }
3529 
3531 {
3532  if ( layer->layerType() != QLatin1String( "CentroidFill" ) )
3533  return;
3534 
3535  // layer type is correct, we can do the cast
3536  mLayer = static_cast<QgsCentroidFillSymbolLayer *>( layer );
3537 
3538  // set values
3539  whileBlocking( mDrawInsideCheckBox )->setChecked( mLayer->pointOnSurface() );
3540  whileBlocking( mDrawAllPartsCheckBox )->setChecked( mLayer->pointOnAllParts() );
3541 }
3542 
3544 {
3545  return mLayer;
3546 }
3547 
3548 void QgsCentroidFillSymbolLayerWidget::mDrawInsideCheckBox_stateChanged( int state )
3549 {
3550  mLayer->setPointOnSurface( state == Qt::Checked );
3551  emit changed();
3552 }
3553 
3554 void QgsCentroidFillSymbolLayerWidget::mDrawAllPartsCheckBox_stateChanged( int state )
3555 {
3556  mLayer->setPointOnAllParts( state == Qt::Checked );
3557  emit changed();
3558 }
3559 
3561 
3563  : QgsSymbolLayerWidget( parent, vl )
3564 {
3565  mLayer = nullptr;
3566 
3567  setupUi( this );
3568 
3569  mImageSourceLineEdit->setLastPathSettingsKey( QStringLiteral( "/UI/lastRasterMarkerImageDir" ) );
3570 
3571  connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsRasterMarkerSymbolLayerWidget::imageSourceChanged );
3572  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
3573  connect( mRotationSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setAngle );
3574  connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
3575  connect( mWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setWidth );
3576  connect( mHeightSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setHeight );
3577  connect( mLockAspectRatio, static_cast < void ( QgsRatioLockButton::* )( bool ) > ( &QgsRatioLockButton::lockChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setLockAspectRatio );
3578 
3583 
3584  mSpinOffsetX->setClearValue( 0.0 );
3585  mSpinOffsetY->setClearValue( 0.0 );
3586  mRotationSpinBox->setClearValue( 0.0 );
3587 
3588  connect( mSpinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setOffset );
3589  connect( mSpinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setOffset );
3590  connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsRasterMarkerSymbolLayerWidget::setOpacity );
3591 
3592  connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
3593  connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
3594 }
3595 
3597 {
3598  if ( !layer )
3599  {
3600  return;
3601  }
3602 
3603  if ( layer->layerType() != QLatin1String( "RasterMarker" ) )
3604  return;
3605 
3606  // layer type is correct, we can do the cast
3607  mLayer = static_cast<QgsRasterMarkerSymbolLayer *>( layer );
3608 
3609  // set values
3610  whileBlocking( mImageSourceLineEdit )->setSource( mLayer->path() );
3611 
3612  whileBlocking( mWidthSpinBox )->setValue( mLayer->size() );
3613  bool preservedAspectRatio = mLayer->preservedAspectRatio();
3614  mHeightSpinBox->blockSignals( true );
3615  if ( preservedAspectRatio )
3616  {
3617  mHeightSpinBox->setValue( mLayer->size() );
3618  }
3619  else
3620  {
3621  mHeightSpinBox->setValue( mLayer->size() * mLayer->fixedAspectRatio() );
3622  }
3623  mHeightSpinBox->setEnabled( mLayer->defaultAspectRatio() > 0.0 );
3624  mHeightSpinBox->blockSignals( false );
3625  whileBlocking( mLockAspectRatio )->setLocked( preservedAspectRatio );
3626 
3627  whileBlocking( mRotationSpinBox )->setValue( mLayer->angle() );
3628  whileBlocking( mOpacityWidget )->setOpacity( mLayer->opacity() );
3629 
3630  whileBlocking( mSpinOffsetX )->setValue( mLayer->offset().x() );
3631  whileBlocking( mSpinOffsetY )->setValue( mLayer->offset().y() );
3632 
3633  mSizeUnitWidget->blockSignals( true );
3634  mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
3635  mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
3636  mSizeUnitWidget->blockSignals( false );
3637  mOffsetUnitWidget->blockSignals( true );
3638  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
3639  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
3640  mOffsetUnitWidget->blockSignals( false );
3641 
3642  //anchor points
3643  whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mLayer->horizontalAnchorPoint() );
3644  whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mLayer->verticalAnchorPoint() );
3645 
3654 
3655  updatePreviewImage();
3656 }
3657 
3659 {
3660  return mLayer;
3661 }
3662 
3664 {
3666  mImageSourceLineEdit->setMessageBar( context.messageBar() );
3667 }
3668 
3669 void QgsRasterMarkerSymbolLayerWidget::imageSourceChanged( const QString &text )
3670 {
3671  mLayer->setPath( text );
3672  updatePreviewImage();
3673  emit changed();
3674 }
3675 
3676 void QgsRasterMarkerSymbolLayerWidget::updatePreviewImage()
3677 {
3678  bool fitsInCache = false;
3679  QImage image = QgsApplication::imageCache()->pathAsImage( mLayer->path(), QSize( 150, 150 ), true, 1.0, fitsInCache );
3680  if ( image.isNull() )
3681  {
3682  mLabelImagePreview->setPixmap( QPixmap() );
3683  return;
3684  }
3685 
3686  QImage previewImage( 150, 150, QImage::Format_ARGB32 );
3687  previewImage.fill( Qt::transparent );
3688  QRect imageRect( ( 150 - image.width() ) / 2.0, ( 150 - image.height() ) / 2.0, image.width(), image.height() );
3689  QPainter p;
3690  p.begin( &previewImage );
3691  //draw a checkerboard background
3692  uchar pixDataRGB[] = { 150, 150, 150, 150,
3693  100, 100, 100, 150,
3694  100, 100, 100, 150,
3695  150, 150, 150, 150
3696  };
3697  QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
3698  QPixmap pix = QPixmap::fromImage( img.scaled( 8, 8 ) );
3699  QBrush checkerBrush;
3700  checkerBrush.setTexture( pix );
3701  p.fillRect( imageRect, checkerBrush );
3702 
3703  if ( mLayer->opacity() < 1.0 )
3704  {
3705  p.setOpacity( mLayer->opacity() );
3706  }
3707 
3708  p.drawImage( imageRect.left(), imageRect.top(), image );
3709  p.end();
3710  mLabelImagePreview->setPixmap( QPixmap::fromImage( previewImage ) );
3711 }
3712 
3713 void QgsRasterMarkerSymbolLayerWidget::setWidth()
3714 {
3715  double defaultAspectRatio = mLayer->defaultAspectRatio();
3716  double fixedAspectRatio = 0.0;
3717  mHeightSpinBox->blockSignals( true );
3718  if ( defaultAspectRatio <= 0.0 )
3719  {
3720  mHeightSpinBox->setValue( mWidthSpinBox->value() );
3721  }
3722  else if ( mLockAspectRatio->locked() )
3723  {
3724  mHeightSpinBox->setValue( mWidthSpinBox->value() * defaultAspectRatio );
3725  }
3726  else
3727  {
3728  fixedAspectRatio = mHeightSpinBox->value() / mWidthSpinBox->value();
3729  }
3730  mHeightSpinBox->blockSignals( false );
3731  mLayer->setSize( mWidthSpinBox->value() );
3732  mLayer->setFixedAspectRatio( fixedAspectRatio );
3733  emit changed();
3734 }
3735 
3736 void QgsRasterMarkerSymbolLayerWidget::setHeight()
3737 {
3738  double defaultAspectRatio = mLayer->defaultAspectRatio();
3739  double fixedAspectRatio = 0.0;
3740  mWidthSpinBox->blockSignals( true );
3741  if ( defaultAspectRatio <= 0.0 )
3742  {
3743  mWidthSpinBox->setValue( mHeightSpinBox->value() );
3744  }
3745  else if ( mLockAspectRatio->locked() )
3746  {
3747  mWidthSpinBox->setValue( mHeightSpinBox->value() / defaultAspectRatio );
3748  }
3749  else
3750  {
3751  fixedAspectRatio = mHeightSpinBox->value() / mWidthSpinBox->value();
3752  }
3753  mWidthSpinBox->blockSignals( false );
3754  mLayer->setSize( mWidthSpinBox->value() );
3755  mLayer->setFixedAspectRatio( fixedAspectRatio );
3756  emit changed();
3757 }
3758 
3759 void QgsRasterMarkerSymbolLayerWidget::setLockAspectRatio( const bool locked )
3760 {
3761  double defaultAspectRatio = mLayer->defaultAspectRatio();
3762  if ( defaultAspectRatio <= 0.0 )
3763  {
3764  whileBlocking( mLockAspectRatio )->setLocked( true );
3765  }
3766  else if ( locked )
3767  {
3768  mLayer->setFixedAspectRatio( 0.0 );
3769  setWidth();
3770  }
3771  else
3772  {
3773  mLayer->setFixedAspectRatio( mHeightSpinBox->value() / mWidthSpinBox->value() );
3774  }
3775 }
3776 
3777 void QgsRasterMarkerSymbolLayerWidget::setAngle()
3778 {
3779  mLayer->setAngle( mRotationSpinBox->value() );
3780  emit changed();
3781 }
3782 
3783 void QgsRasterMarkerSymbolLayerWidget::setOpacity( double value )
3784 {
3785  mLayer->setOpacity( value );
3786  emit changed();
3787  updatePreviewImage();
3788 }
3789 
3790 void QgsRasterMarkerSymbolLayerWidget::setOffset()
3791 {
3792  mLayer->setOffset( QPointF( mSpinOffsetX->value(), mSpinOffsetY->value() ) );
3793  emit changed();
3794 }
3795 
3796 void QgsRasterMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
3797 {
3798  if ( mLayer )
3799  {
3800  mLayer->setSizeUnit( mSizeUnitWidget->unit() );
3801  mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
3802  emit changed();
3803  }
3804 }
3805 
3806 void QgsRasterMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
3807 {
3808  if ( mLayer )
3809  {
3810  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
3811  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
3812  emit changed();
3813  }
3814 }
3815 
3816 void QgsRasterMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
3817 {
3818  if ( mLayer )
3819  {
3821  emit changed();
3822  }
3823 }
3824 
3825 void QgsRasterMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
3826 {
3827  if ( mLayer )
3828  {
3830  emit changed();
3831  }
3832 }
3833 
3835 
3837  : QgsSymbolLayerWidget( parent, vl )
3838 {
3839  mLayer = nullptr;
3840  setupUi( this );
3841 
3842  mImageSourceLineEdit->setLastPathSettingsKey( QStringLiteral( "/UI/lastRasterMarkerImageDir" ) );
3843  connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsRasterFillSymbolLayerWidget::imageSourceChanged );
3844 
3845  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterFillSymbolLayerWidget::mOffsetUnitWidget_changed );
3846  connect( mRotationSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::mRotationSpinBox_valueChanged );
3847  connect( mWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterFillSymbolLayerWidget::mWidthUnitWidget_changed );
3848  connect( mWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::mWidthSpinBox_valueChanged );
3849 
3854 
3855  mSpinOffsetX->setClearValue( 0.0 );
3856  mSpinOffsetY->setClearValue( 0.0 );
3857  mRotationSpinBox->setClearValue( 0.0 );
3858 
3859  connect( cboCoordinateMode, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterFillSymbolLayerWidget::setCoordinateMode );
3860  connect( mSpinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::offsetChanged );
3861  connect( mSpinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::offsetChanged );
3862  connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsRasterFillSymbolLayerWidget::opacityChanged );
3863 }
3864 
3865 
3867 {
3868  if ( !layer )
3869  {
3870  return;
3871  }
3872 
3873  if ( layer->layerType() != QLatin1String( "RasterFill" ) )
3874  {
3875  return;
3876  }
3877 
3878  mLayer = dynamic_cast<QgsRasterFillSymbolLayer *>( layer );
3879  if ( !mLayer )
3880  {
3881  return;
3882  }
3883 
3884  whileBlocking( mImageSourceLineEdit )->setSource( mLayer->imageFilePath() );
3885 
3886  cboCoordinateMode->blockSignals( true );
3887  switch ( mLayer->coordinateMode() )
3888  {
3890  cboCoordinateMode->setCurrentIndex( 1 );
3891  break;
3893  default:
3894  cboCoordinateMode->setCurrentIndex( 0 );
3895  break;
3896  }
3897  cboCoordinateMode->blockSignals( false );
3898  whileBlocking( mOpacityWidget )->setOpacity( mLayer->opacity() );
3899  whileBlocking( mRotationSpinBox )->setValue( mLayer->angle() );
3900 
3901  whileBlocking( mSpinOffsetX )->setValue( mLayer->offset().x() );
3902  whileBlocking( mSpinOffsetY )->setValue( mLayer->offset().y() );
3903  mOffsetUnitWidget->blockSignals( true );
3904  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
3905  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
3906  mOffsetUnitWidget->blockSignals( false );
3907 
3908  whileBlocking( mWidthSpinBox )->setValue( mLayer->width() );
3909  mWidthUnitWidget->blockSignals( true );
3910  mWidthUnitWidget->setUnit( mLayer->widthUnit() );
3911  mWidthUnitWidget->setMapUnitScale( mLayer->widthMapUnitScale() );
3912  mWidthUnitWidget->blockSignals( false );
3913 
3914  updatePreviewImage();
3915 
3920 }
3921 
3923 {
3924  return mLayer;
3925 }
3926 
3927 void QgsRasterFillSymbolLayerWidget::imageSourceChanged( const QString &text )
3928 {
3929  mLayer->setImageFilePath( text );
3930  updatePreviewImage();
3931  emit changed();
3932 }
3933 
3934 void QgsRasterFillSymbolLayerWidget::setCoordinateMode( int index )
3935 {
3936  switch ( index )
3937  {
3938  case 0:
3939  //feature coordinate mode
3941  break;
3942  case 1:
3943  //viewport coordinate mode
3945  break;
3946  }
3947 
3948  emit changed();
3949 }
3950 
3951 void QgsRasterFillSymbolLayerWidget::opacityChanged( double value )
3952 {
3953  if ( !mLayer )
3954  {
3955  return;
3956  }
3957 
3958  mLayer->setOpacity( value );
3959  emit changed();
3960  updatePreviewImage();
3961 }
3962 
3963 void QgsRasterFillSymbolLayerWidget::offsetChanged()
3964 {
3965  mLayer->setOffset( QPointF( mSpinOffsetX->value(), mSpinOffsetY->value() ) );
3966  emit changed();
3967 }
3968 
3969 void QgsRasterFillSymbolLayerWidget::mOffsetUnitWidget_changed()
3970 {
3971  if ( !mLayer )
3972  {
3973  return;
3974  }
3975  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
3976  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
3977  emit changed();
3978 }
3979 
3980 void QgsRasterFillSymbolLayerWidget::mRotationSpinBox_valueChanged( double d )
3981 {
3982  if ( mLayer )
3983  {
3984  mLayer->setAngle( d );
3985  emit changed();
3986  }
3987 }
3988 
3989 void QgsRasterFillSymbolLayerWidget::mWidthUnitWidget_changed()
3990 {
3991  if ( !mLayer )
3992  {
3993  return;
3994  }
3995  mLayer->setWidthUnit( mWidthUnitWidget->unit() );
3996  mLayer->setWidthMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
3997  emit changed();
3998 }
3999 
4000 void QgsRasterFillSymbolLayerWidget::mWidthSpinBox_valueChanged( double d )
4001 {
4002  if ( !mLayer )
4003  {
4004  return;
4005  }
4006  mLayer->setWidth( d );
4007  emit changed();
4008 }
4009 
4010 void QgsRasterFillSymbolLayerWidget::updatePreviewImage()
4011 {
4012  bool fitsInCache = false;
4013  QImage image = QgsApplication::imageCache()->pathAsImage( mLayer->imageFilePath(), QSize( 150, 150 ), true, 1.0, fitsInCache );
4014  if ( image.isNull() )
4015  {
4016  mLabelImagePreview->setPixmap( QPixmap() );
4017  return;
4018  }
4019 
4020  QImage previewImage( 150, 150, QImage::Format_ARGB32 );
4021  previewImage.fill( Qt::transparent );
4022  QRect imageRect( ( 150 - image.width() ) / 2.0, ( 150 - image.height() ) / 2.0, image.width(), image.height() );
4023  QPainter p;
4024  p.begin( &previewImage );
4025  //draw a checkerboard background
4026  uchar pixDataRGB[] = { 150, 150, 150, 150,
4027  100, 100, 100, 150,
4028  100, 100, 100, 150,
4029  150, 150, 150, 150
4030  };
4031  QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
4032  QPixmap pix = QPixmap::fromImage( img.scaled( 8, 8 ) );
4033  QBrush checkerBrush;
4034  checkerBrush.setTexture( pix );
4035  p.fillRect( imageRect, checkerBrush );
4036 
4037  if ( mLayer->opacity() < 1.0 )
4038  {
4039  p.setOpacity( mLayer->opacity() );
4040  }
4041 
4042  p.drawImage( imageRect.left(), imageRect.top(), image );
4043  p.end();
4044  mLabelImagePreview->setPixmap( QPixmap::fromImage( previewImage ) );
4045 }
4046 
4047 
4049  : QgsSymbolLayerWidget( parent, vl )
4050 
4051 {
4052  setupUi( this );
4053  modificationExpressionSelector->setMultiLine( true );
4054  modificationExpressionSelector->setLayer( const_cast<QgsVectorLayer *>( vl ) );
4055  modificationExpressionSelector->registerExpressionContextGenerator( this );
4056  cbxGeometryType->addItem( QgsApplication::getThemeIcon( QStringLiteral( "/mIconPolygonLayer.svg" ) ), tr( "Polygon / MultiPolygon" ), QgsSymbol::Fill );
4057  cbxGeometryType->addItem( QgsApplication::getThemeIcon( QStringLiteral( "/mIconLineLayer.svg" ) ), tr( "LineString / MultiLineString" ), QgsSymbol::Line );
4058  cbxGeometryType->addItem( QgsApplication::getThemeIcon( QStringLiteral( "/mIconPointLayer.svg" ) ), tr( "Point / MultiPoint" ), QgsSymbol::Marker );
4059  connect( modificationExpressionSelector, &QgsExpressionLineEdit::expressionChanged, this, &QgsGeometryGeneratorSymbolLayerWidget::updateExpression );
4060  connect( cbxGeometryType, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGeometryGeneratorSymbolLayerWidget::updateSymbolType );
4061 }
4062 
4064 {
4065  mLayer = static_cast<QgsGeometryGeneratorSymbolLayer *>( l );
4066  modificationExpressionSelector->setExpression( mLayer->geometryExpression() );
4067  cbxGeometryType->setCurrentIndex( cbxGeometryType->findData( mLayer->symbolType() ) );
4068 }
4069 
4071 {
4072  return mLayer;
4073 }
4074 
4075 void QgsGeometryGeneratorSymbolLayerWidget::updateExpression( const QString &string )
4076 {
4077  mLayer->setGeometryExpression( string );
4078 
4079  emit changed();
4080 }
4081 
4082 void QgsGeometryGeneratorSymbolLayerWidget::updateSymbolType()
4083 {
4084  mLayer->setSymbolType( static_cast<QgsSymbol::SymbolType>( cbxGeometryType->currentData().toInt() ) );
4085 
4086  emit symbolChanged();
4087 }
void setOffset(QPointF offset)
Sets the marker&#39;s offset, which is the horizontal and vertical displacement which the rendered marker...
QColor color2() const
Returns the color used for the endpoint of the shapeburst fill.
const QgsVectorLayer * vectorLayer() const
Returns the vector layer associated with the widget.
void setSvgStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the pattern&#39;s stroke.
static const QString EXPR_ORIGINAL_VALUE
Inbuilt variable name for value original value variable.
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
void setOffsetAlongLine(double offsetAlongLine)
Sets the the offset along the line for the symbol placement.
double hashLength() const
Returns the length of hash symbols.
static QgsExpressionContextScope * updateSymbolScope(const QgsSymbol *symbol, QgsExpressionContextScope *symbolScope=nullptr)
Updates a symbol scope related to a QgsSymbol to an expression context.
static QgsSvgCache * svgCache()
Returns the application&#39;s SVG cache, used for caching SVG images and handling parameter replacement w...
QgsUnitTypes::RenderUnit customDashPatternUnit() const
Returns the units for lengths used in the custom dash pattern.
static const QString EXPR_CLUSTER_COLOR
Inbuilt variable name for cluster color variable.
Place symbols on the first vertex in the line.
Meters value as Map units.
Definition: qgsunittypes.h:120
void setDistance(double d)
Sets the distance between lines in the fill pattern.
Single variable definition for use within a QgsExpressionContextScope.
RenderRingFilter ringFilter() const
Returns the line symbol layer&#39;s ring filter, which controls which rings are rendered when the line sy...
QList< QgsExpressionContextScope * > globalProjectAtlasMapLayerScopes(const QgsMapLayer *layer) const
Returns list of scopes: global, project, atlas, map, layer.
void symbolChanged()
Should be emitted whenever the sub symbol changed on this symbol layer configuration.
Gradient reference point 1 is centroid.
const QgsMapUnitScale & displacementYMapUnitScale() const
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
const QgsMapUnitScale & offsetXMapUnitScale() const
Returns the unit scale for the horizontal offset for rows in the pattern.
QgsMarkerLineSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsMarkerLineSymbolLayerWidget.
void setColorStroke(const QColor &color)
static QIcon symbolLayerPreviewIcon(const QgsSymbolLayer *layer, QgsUnitTypes::RenderUnit u, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale())
Draws a symbol layer preview to an icon.
void setOffsetUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the symbol&#39;s offset.
void setMapUnitScale(const QgsMapUnitScale &scale) override
void setSymbolLayer(QgsSymbolLayer *layer) override
double fixedAspectRatio() const
Returns the marker aspect ratio between width and height to be used in rendering, if the value set is...
void setColorFill(const QColor &color)
void setPenJoinStyle(Qt::PenJoinStyle style)
Sets the marker&#39;s stroke join style (e.g., miter, bevel, etc).
QgsSymbolLayer * symbolLayer() override
QgsGradientFillSymbolLayer * mLayer
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the stroke width map unit scale.
void setColorRamp(QgsColorRamp *ramp)
Sets the color ramp used for the gradient fill.
QgsRasterMarkerSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsRasterMarkerSymbolLayerWidget.
QString svgFilePath() const
Returns the path to the SVG file used to render the fill.
void setPatternWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the width of the SVG images in the pattern.
QColor strokeColor() const override
Gets stroke color.
double defaultAspectRatio() const
Returns the default marker aspect ratio between width and height, 0 if not yet calculated.
QVector< qreal > dashDotVector() const
Returns the dash pattern as a list of numbers.
void setSymbolLayer(QgsSymbolLayer *layer) override
bool dockMode()
Returns the dock mode state.
void setPlacement(Placement placement)
Sets the placement of the symbols.
void setSymbolLayer(QgsSymbolLayer *layer) override
Gradient reference point 1 x.
void setOffsetUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the fill&#39;s offset.
static const QString EXPR_GEOMETRY_POINT_COUNT
Inbuilt variable name for point count variable.
QgsUnitTypes::RenderUnit distanceUnit() const
Returns the units for the distance between lines in the fill pattern.
QgsSymbolLayer * symbolLayer() override
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
void setSvgFillColor(const QColor &c)
Sets the fill color used for rendering the SVG content.
void setPatternWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the pattern&#39;s width.
QString fontFamily() const
Returns the font family name for the associated font which will be used to render the point...
void setUseCustomDashPattern(bool b)
Sets whether the line uses a custom dash pattern.
A model for displaying SVG files with a preview icon.
void setSymbolLayer(QgsSymbolLayer *layer) override
const QgsMapUnitScale & displacementXMapUnitScale() const
static const double UI_SCALE_FACTOR
UI scaling factor.
Definition: qgis.h:139
bool exists(const QgsPropertyDefinition &definition) const
Returns true if the property is stored in the layer already, false otherwise.
QString imageFilePath() const
The path to the raster image used for the fill.
QPointF offset() const
Returns the offset for the shapeburst fill.
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit u)
Sets the unit for the width of the marker&#39;s stroke.
void setSymbolLayer(QgsSymbolLayer *layer) override
void setStrokeStyle(Qt::PenStyle strokeStyle)
Sets the marker&#39;s stroke style (e.g., solid, dashed, etc)
Simple marker symbol layer, consisting of a rendered shape with solid fill color and an stroke...
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units used for the offset of the shapeburst fill.
virtual void setWidth(double width)
Sets the width of the line symbol layer.
GradientCoordinateMode coordinateMode() const
Coordinate mode for gradient. Controls how the gradient stops are positioned.
void colorRampChanged()
Emitted whenever a new color ramp is set for the button.
const QgsMapUnitScale & offsetMapUnitScale() const
Returns the map unit scale for the line&#39;s offset.
QgsFontMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
void setReferencePoint1IsCentroid(bool isCentroid)
Sets the starting point of the gradient to be the feature centroid.
Qt::PenJoinStyle penJoinStyle() const
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units for the line pattern&#39;s offset.
GradientSpread gradientSpread() const
Gradient spread mode. Controls how the gradient behaves outside of the predefined stops...
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units for the fill&#39;s offset.
A symbol fill consisting of repeated parallel lines.
QgsSimpleFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsSimpleFillSymbolLayerWidget.
const QgsMapUnitScale & sizeMapUnitScale() const
Returns the map unit scale for the symbol&#39;s size.
QString geometryExpression() const
Gets the expression to generate this geometry.
void lockChanged(bool locked)
Emitted whenever the lock state changes.
double angle() const
void setOffsetYMapUnitScale(const QgsMapUnitScale &scale)
Sets the unit scale for the vertical offset for rows in the pattern.
QgsLinePatternFillSymbolLayer * mLayer
void setColorRamp(QgsColorRamp *ramp)
Sets the color ramp used to draw the shapeburst fill.
QgsUnitTypes::RenderUnit widthUnit() const
Returns the units for the image&#39;s width.
void setDisplacementYUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the vertical displacement between rows in the pattern.
static QgsImageCache * imageCache()
Returns the application&#39;s image cache, used for caching resampled versions of raster images...
QgsGradientFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsGradientFillSymbolLayerWidget.
A simple line symbol layer, which renders lines using a line in a variety of styles (e...
double averageAngleLength() const
Returns the length of line over which the line&#39;s direction is averaged when calculating individual sy...
void setOffset(QPointF offset)
Sets the offset for the shapeburst fill.
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
QgsUnitTypes::RenderUnit patternWidthUnit() const
Returns the units for the width of the SVG images in the pattern.
Render both exterior and interior rings.
QgsSymbolLayer * symbolLayer() override
void setAngle(double angle)
Abstract base class for color ramps.
Definition: qgscolorramp.h:31
void sourceChanged(const QString &source)
Emitted whenever the file source is changed in the widget.
void setOffsetY(double offset)
Sets the vertical offset values for points in the pattern.
static QIcon symbolPreviewIcon(const QgsSymbol *symbol, QSize size, int padding=0)
Returns an icon preview for a color ramp.
void setSymbolLayer(QgsSymbolLayer *layer) override
void setUseWholeShape(bool useWholeShape)
Sets whether the shapeburst fill should be drawn using the entire shape.
A widget for displaying characters available in a preset font, and allowing users to select an indivi...
void setStrokeColor(const QColor &color) override
Sets the marker&#39;s stroke color.
void setCharacter(QChar character)
Sets the currently selected character in the widget.
void setSymbolLayer(QgsSymbolLayer *layer) override
const QgsMapUnitScale & hashLengthMapUnitScale() const
Returns the map unit scale for the hash length.
void setDistanceUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the maximum distance to shade inside of the shape from the polygon&#39;s boundary...
void setColor(const QColor &color)
const QgsMapUnitScale & strokeWidthMapUnitScale() const
ShapeburstColorType colorType() const
Returns the color mode used for the shapeburst fill.
QgsUnitTypes::RenderUnit averageAngleUnit() const
Returns the unit for the length over which the line&#39;s direction is averaged when calculating individu...
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsUnitTypes::RenderUnit offsetYUnit() const
Returns the units for the vertical offset for rows in the pattern.
QgsWkbTypes::GeometryType geometryType() const
Returns point, line or polygon.
void setStrokeColor(const QColor &c) override
Set stroke color.
void setStrokeWidth(double w)
Sets the width of the marker&#39;s stroke.
void setContext(const QgsSymbolWidgetContext &context) override
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
QgsSymbolLayer * symbolLayer() override
void setDistanceUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the distance between lines in the fill pattern.
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the symbol&#39;s offset.
void setStrokeWidth(double width)
Set&#39;s the marker&#39;s stroke width.
VerticalAnchorPoint verticalAnchorPoint() const
Returns the vertical anchor point for positioning the symbol.
A widget to enter a custom dash space pattern for lines.
void setUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit type used for the dash space pattern (used to update interface labels) ...
bool useWholeShape() const
Returns whether the shapeburst fill is set to cover the entire shape.
void setOffsetUnit(const QgsUnitTypes::RenderUnit unit)
Sets the units for the fill&#39;s offset.
void setDistanceXMapUnitScale(const QgsMapUnitScale &scale)
Base class for any widget that can be shown as a inline panel.
void setDistanceMapUnitScale(const QgsMapUnitScale &scale)
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units for the symbol&#39;s offset.
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units for the line&#39;s offset.
Line symbol.
Definition: qgssymbol.h:86
QColor strokeColor() const override
Returns the marker&#39;s stroke color.
QgsCentroidFillSymbolLayer * mLayer
QColor color2() const
Color for endpoint of gradient, only used if the gradient color type is set to SimpleTwoColor.
Place symbols on every vertex in the line.
void setReferencePoint2IsCentroid(bool isCentroid)
Sets the end point of the gradient to be the feature centroid.
const QgsMapUnitScale & averageAngleMapUnitScale() const
Returns the map unit scale for the length over which the line&#39;s direction is averaged when calculatin...
QgsUnitTypes::RenderUnit intervalUnit() const
Returns the units for the interval between symbols.
QgsSVGFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsSVGFillSymbolLayerWidget.
double interval() const
Returns the interval between individual symbols.
const QgsMapUnitScale & svgStrokeWidthMapUnitScale() const
Returns the map unit scale for the pattern&#39;s stroke.
static QString encodeShape(QgsSimpleMarkerSymbolLayerBase::Shape shape)
Encodes a shape to its string representation.
void setPointOnAllParts(bool pointOnAllParts)
Sets whether a point is drawn for all parts or only on the biggest part of multi-part features...
Qt::PenJoinStyle penJoinStyle() const
Returns the stroke join style.
void setCharacterFromText(const QString &text)
Set the font marker character from a text string.
void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
Tiling is based on complete map viewport.
QList< QgsUnitTypes::RenderUnit > RenderUnitList
List of render units.
Definition: qgsunittypes.h:184
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
Definition: MathUtils.cpp:786
void setInterval(double interval)
Sets the interval between individual symbols.
virtual double width() const
Returns the estimated width for the line symbol layer.
A marker symbol type, for rendering Point and MultiPoint geometries.
Definition: qgssymbol.h:766
Name, eg shape name for simple markers.
void setStrokeWidth(double strokeWidth)
void setPatternWidth(double width)
Sets the width to render the SVG content as within the fill (i.e.
void setWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the line&#39;s width.
A line symbol type, for rendering LineString and MultiLineString geometries.
Definition: qgssymbol.h:966
Gradient reference point 2 y.
static QList< QgsSimpleMarkerSymbolLayerBase::Shape > availableShapes()
Returns a list of all available shape types.
double lineAngle() const
Returns the angle for the parallel lines used to fill the symbol.
QgsShapeburstFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsShapeburstFillSymbolLayerWidget.
QString path() const
Returns the marker SVG path.
void setSymbolLayer(QgsSymbolLayer *layer) override
QColor strokeColor() const override
Gets stroke color.
void setGradientType(GradientType gradientType)
Place symbols at every virtual curve point in the line (used when rendering curved geometry types onl...
void clearCharacter()
Clears the currently selected character in the widget.
void setPenJoinStyle(Qt::PenJoinStyle style)
Sets the stroke join style.
double strokeWidth() const
Returns the width of the marker&#39;s stroke.
const QgsMapUnitScale & offsetMapUnitScale() const
Returns the map unit scale for the pattern&#39;s line offset.
void setPath(const QString &path)
Set the marker SVG path.
void setCustomDashPatternUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for lengths used in the custom dash pattern.
void setOffsetUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the line pattern&#39;s offset.
void setCoordinateMode(FillCoordinateMode mode)
Set the coordinate mode for fill.
virtual void setColor(const QColor &color)
The fill color.
double offsetY() const
Returns the vertical offset values for points in the pattern.
const QgsMapUnitScale & offsetYMapUnitScale() const
Returns the unit scale for the vertical offset between rows in the pattern.
void setOffset(QPointF offset)
void setBlurRadius(int blurRadius)
Sets the blur radius, which controls the amount of blurring applied to the fill.
void setSymbolLayer(QgsSymbolLayer *layer) override
void setAverageAngleUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the length over which the line&#39;s direction is averaged when calculating individual ...
void setSymbolLayer(QgsSymbolLayer *layer) override
void createAuxiliaryField()
Emitted when creating a new auxiliary field.
QgsSymbolLayer * symbolLayer() override
QgsUnitTypes::RenderUnit strokeWidthUnit() const
Returns the stroke width unit.
HorizontalAnchorPoint horizontalAnchorPoint() const
Returns the horizontal anchor point for positioning the symbol.
void setIgnoreRings(bool ignoreRings)
Sets whether the shapeburst fill should ignore polygon rings when calculating the buffered shading...
double offset() const
Returns the offset distance for lines within the fill, which is the distance to offset the parallel l...
A dialog to create a new auxiliary layer.
void setField(const QString &field)
Sets the field name the property references.
void setLineAngle(double a)
Sets the angle for the parallel lines used to fill the symbol.
const QgsMapUnitScale & distanceMapUnitScale() const
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the stroke width.
void setImageFilePath(const QString &imagePath)
Sets the path to the raster image used for the fill.
Raster marker symbol layer class.
A class for filling symbols with a repeated raster image.
void setOffsetAlongLineMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale used for calculating the offset in map units along line for symbols...
void changed()
Should be emitted whenever configuration changes happened on this symbol layer configuration.
A cross platform button subclass used to represent a locked / unlocked ratio state.
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
A dialog to enter a custom dash space pattern for lines.
A button for controlling property overrides which may apply to a widget.
void setIntervalUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the interval between symbols.
void setStrokeColor(const QColor &color) override
Set stroke color.
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
QgsSymbolLayer * symbolLayer() override
QgsMarkerLineSymbolLayer * mLayer
void setColor2(const QColor &color2)
Sets the color for the endpoint of the shapeburst fill.
QgsRasterMarkerSymbolLayer * mLayer
double angle() const
Returns the rotation angle for the marker, in degrees clockwise from north.
QgsSimpleLineSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsSimpleLineSymbolLayerWidget.
void setColor(const QColor &color) override
The fill color.
QgsSimpleFillSymbolLayer * mLayer
void setWidth(const double width)
Sets the width for scaling the image used in the fill.
double offsetX() const
Returns the horizontal offset values for points in the pattern.
QgsUnitTypes::RenderUnit displacementYUnit() const
Returns the units for the vertical displacement between rows in the pattern.
double opacity() const
Returns the marker opacity.
QgsUnitTypes::RenderUnit widthUnit() const
Returns the units for the line&#39;s width.
void setFixedAspectRatio(double ratio)
Set the marker aspect ratio between width and height to be used in rendering, if the value set is low...
void setReferencePoint1(QPointF referencePoint)
Starting point of gradient fill, in the range [0,0] - [1,1].
static QgsPanelWidget * findParentPanel(QWidget *widget)
Traces through the parents of a widget to find if it is contained within a QgsPanelWidget widget...
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map scale for the width of the marker&#39;s stroke.
QVector< qreal > customDashVector() const
Returns the custom dash vector, which is the pattern of alternating drawn/skipped lengths used while ...
Contains settings which reflect the context in which a symbol (or renderer) widget is shown...
void setToProperty(const QgsProperty &property)
Sets the widget to reflect the current state of a QgsProperty.
QgsProperty toProperty() const
Returns a QgsProperty object encapsulating the current state of the widget.
QgsCentroidFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsCentroidFillSymbolLayerWidget.
void setSvgStrokeWidth(double w)
Sets the stroke width used for rendering the SVG content.
const QgsMapUnitScale & strokeWidthMapUnitScale() const
Returns the stroke width map unit scale.
void resizeEvent(QResizeEvent *event) override
void setHashLengthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the hash length.
void registerExpressionContextGenerator(QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
double size() const
Returns the symbol size.
void opacityChanged(double opacity)
Emitted when the opacity is changed in the widget, where opacity ranges from 0.0 (transparent) to 1...
void setOffsetXUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the horizontal offset between rows in the pattern.
bool preservedAspectRatio() const
Returns the preserved aspect ratio value, true if fixed aspect ratio has been lower or equal to 0...
Render the interior rings only.
virtual QgsSymbolLayer * symbolLayer()=0
void setSymbolLayer(QgsSymbolLayer *layer) override
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
const QgsMapUnitScale & strokeWidthMapUnitScale() const
Returns the map scale for the width of the marker&#39;s stroke.
void setWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the image&#39;s width.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer&#39;s property collection, used for data defined overrides...
void setHorizontalAnchorPoint(HorizontalAnchorPoint h)
Sets the horizontal anchor point for positioning the symbol.
Line symbol layer type which draws repeating line sections along a line feature.
const QgsMapUnitScale & offsetMapUnitScale() const
void setSizeMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the symbol&#39;s size.
const QgsMapUnitScale & offsetMapUnitScale() const
Returns the map unit scale for the fill&#39;s offset.
QgsSvgMarkerSymbolLayer * mLayer
QgsSymbolWidgetContext context() const
Returns the context in which the symbol widget is shown, e.g., the associated map canvas and expressi...
QgsShapeburstFillSymbolLayer * mLayer
void setStrokeStyle(Qt::PenStyle strokeStyle)
virtual QColor color() const
The fill color.
QgsSymbolLayer * symbolLayer() override
void setDistanceYMapUnitScale(const QgsMapUnitScale &scale)
static const QString EXPR_SYMBOL_COLOR
Inbuilt variable name for symbol color variable.
QColor fillColor() const override
Gets fill color.
Filename, eg for svg files.
void setRotateSymbols(bool rotate)
Sets whether the repeating symbols should be rotated to match their line segment orientation.
QgsFilledMarkerSymbolLayer * mLayer
void setSymbolType(QgsSymbol::SymbolType symbolType)
Set the type of symbol which should be created.
QgsUnitTypes::RenderUnit offsetXUnit() const
Returns the units for the horizontal offset for rows in the pattern.
QList< QgsSymbolLayer * > QgsSymbolLayerList
Definition: qgssymbol.h:51
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the stroke width unit.
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsUnitTypes::RenderUnit offsetAlongLineUnit() const
Returns the unit used for calculating the offset along line for symbols.
Shapeburst fill from edge distance.
bool ignoreRings() const
Returns whether the shapeburst fill is set to ignore polygon interior rings.
QgsUnitTypes::RenderUnit offsetUnit() const
Qt::PenJoinStyle penJoinStyle() const
Returns the pen join style used to render the line (e.g.
Character, eg for font marker symbol layers.
void setCharacter(QChar chr)
Set the font marker character from char.
double offset() const
Returns the line&#39;s offset.
Qt::PenJoinStyle penJoinStyle() const
Returns the marker&#39;s stroke join style (e.g., miter, bevel, etc).
QgsPointPatternFillSymbolLayer * mLayer
void setPenJoinStyle(Qt::PenJoinStyle style)
bool useCustomDashPattern() const
Returns true if the line uses a custom dash pattern.
QgsSimpleMarkerSymbolLayerBase::Shape shape() const
Returns the shape for the rendered marker symbol.
void setOpacity(double opacity)
Set the marker opacity.
Single scope for storing variables and functions for use within a QgsExpressionContext.
A store for object properties.
Definition: qgsproperty.h:229
QgsUnitTypes::RenderUnit svgStrokeWidthUnit() const
Returns the units for the stroke width.
QColor svgStrokeColor() const
Returns the stroke color used for rendering the SVG content.
QString path() const
Returns the marker raster image path.
QgsRasterFillSymbolLayer * mLayer
void setContext(const QgsSymbolWidgetContext &context) override
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
void setHashAngle(double angle)
Sets the angle to use when drawing the hashed lines sections, in degrees clockwise.
QgsSymbolLayer * symbolLayer() override
Tiling is based on feature bounding box.
void setDisplacementXMapUnitScale(const QgsMapUnitScale &scale)
const QgsMapUnitScale & offsetAlongLineMapUnitScale() const
Returns the map unit scale used for calculating the offset in map units along line for symbols...
QgsAuxiliaryLayer * auxiliaryLayer()
Returns the current auxiliary layer.
void setOffset(QPointF offset)
Sets the offset for the fill.
void setPath(const QString &path)
Set the marker raster image path.
QgsSymbolLayer * symbolLayer() override
void setPenStyle(Qt::PenStyle style)
Sets the pen style used to render the line (e.g.
void widgetChanged()
Emitted when the widget state changes.
void setSymbolLayer(QgsSymbolLayer *layer) override
void setSymbolLayer(QgsSymbolLayer *layer) override
void setMapUnitScale(const QgsMapUnitScale &scale) FINAL
QgsGeometryGeneratorSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsGeometryGeneratorSymbolLayerWidget.
void setColor(const QColor &color)
QgsSvgMarkerSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsSvgMarkerSymbolLayerWidget.
Qt::PenStyle strokeStyle() const
Returns the marker&#39;s stroke style (e.g., solid, dashed, etc)
Definition for a property.
Definition: qgsproperty.h:46
void setHashLengthUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the length of hash symbols.
HorizontalAnchorPoint
Symbol horizontal anchor points.
QString character() const
Returns the character(s) used when rendering points.
void setSvgStrokeWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the stroke width.
Gradient reference point 1 y.
Place symbols at regular intervals.
void setStrokeColor(const QColor &strokeColor) override
Set stroke color.
void setFont(const QFont &font)
Sets the font to show in the widget.
void setOffset(QPointF offset)
Offset for gradient fill.
VerticalAnchorPoint
Symbol vertical anchor points.
void expressionChanged(const QString &expression)
Emitted when the expression is changed.
void setDistanceXUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the horizontal distance between points in the pattern.
void setPenCapStyle(Qt::PenCapStyle style)
Sets the pen cap style used to render the line (e.g.
void containsParams(const QString &path, bool &hasFillParam, QColor &defaultFillColor, bool &hasStrokeParam, QColor &defaultStrokeColor, bool &hasStrokeWidthParam, double &defaultStrokeWidth) const
Tests if an svg file contains parameters for fill, stroke color, stroke width.
void sourceChanged(const QString &source)
Emitted whenever the SVG source is changed in the widget.
QgsSimpleMarkerSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsSimpleMarkerSymbolLayerWidget.
Qt::BrushStyle brushStyle() const
Line angle, or angle of hash lines for hash line symbols.
void setFixedAspectRatio(double ratio)
Set the marker aspect ratio between width and height to be used in rendering, if the value set is low...
GradientType gradientType() const
Type of gradient, e.g., linear or radial.
const QgsMapUnitScale & distanceMapUnitScale() const
Returns the map unit scale for the pattern&#39;s line distance.
void colorChanged(const QColor &color)
Emitted whenever a new color is set for the button.
void changed()
Emitted when property definition changes.
A model for displaying SVG search paths.
QgsMapCanvas * mapCanvas() const
Returns the map canvas associated with the widget.
void registerDataDefinedButton(QgsPropertyOverrideButton *button, QgsSymbolLayer::Property key)
Registers a data defined override button.
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the symbol&#39;s size.
double defaultAspectRatio() const
Returns the default marker aspect ratio between width and height, 0 if not yet calculated.
Marker symbol.
Definition: qgssymbol.h:85
A class for filling symbols with a repeated SVG file.
Stroke style (eg solid, dashed)
QgsUnitTypes::RenderUnit strokeWidthUnit() const
Returns the unit for the width of the marker&#39;s stroke.
QgsExpressionContext * expressionContext() const
Returns the expression context used for the widget, if set.
Fill symbol.
Definition: qgssymbol.h:87
double hashAngle() const
Returns the angle to use when drawing the hashed lines sections, in degrees clockwise.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:212
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the fill&#39;s offset.
QgsSimpleLineSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
void setContext(const QgsSymbolWidgetContext &context) override
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
const QgsMapUnitScale & intervalMapUnitScale() const
Returns the map unit scale for the interval between symbols.
void setShape(QgsSimpleMarkerSymbolLayerBase::Shape shape)
Sets the rendered marker shape.
bool drawInsidePolygon() const
Returns true if the line should only be drawn inside polygons, and any portion of the line which fall...
QgsPointPatternFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsPointPatternFillSymbolLayerWidget.
QgsHashedLineSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsHashedLineSymbolLayerWidget.
void setGeometryExpression(const QString &exp)
Set the expression to generate this geometry.
void setGradientColorType(GradientColorType gradientColorType)
Line symbol layer type which draws repeating marker symbols along a line feature. ...
QgsFilledMarkerSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsFilledMarkerSymbolLayerWidget.
Points (e.g., for font sizes)
Definition: qgsunittypes.h:117
QColor svgFillColor() const
Returns the fill color used for rendering the SVG content.
QImage pathAsImage(const QString &path, const QSize size, const bool keepAspectRatio, const double opacity, bool &fitsInCache)
Returns the specified path rendered as an image.
bool preservedAspectRatio() const
Returns the preserved aspect ratio value, true if fixed aspect ratio has been lower or equal to 0...
void setWidthUnit(const QgsUnitTypes::RenderUnit unit)
Sets the units for the image&#39;s width.
QgsSvgMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
QgsSimpleMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
QgsUnitTypes::RenderUnit distanceXUnit() const
Returns the units for the horizontal distance between points in the pattern.
void updateParamGui(bool resetValues=true)
Enables or disables svg fill color, stroke color and stroke width based on whether the svg file suppo...
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units for the symbol&#39;s size.
void setCustomDashPatternMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for lengths used in the custom dash pattern.
QgsUnitTypes::RenderUnit displacementXUnit() const
Returns the units for the horizontal displacement between rows in the pattern.
const QgsMapUnitScale & distanceXMapUnitScale() const
const QgsMapUnitScale & patternWidthMapUnitScale() const
Returns the map unit scale for the pattern&#39;s width.
void setWidthMapUnitScale(const QgsMapUnitScale &scale)
static QString nameFromProperty(const QgsPropertyDefinition &def, bool joined=false)
Returns the name of the auxiliary field for a property definition.
void setSvgFilePath(const QString &svgPath)
Sets the path to the SVG file to render in the fill.
void setIntervalMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the interval between symbols.