QGIS API Documentation  3.13.0-Master (13337b20cd)
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 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
477  int width = static_cast< int >( Qgis::UI_SCALE_FACTOR * fontMetrics().width( 'X' ) * 23 );
478 #else
479  int width = static_cast< int >( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 23 );
480 #endif
481  int height = static_cast< int >( width / 1.61803398875 ); // golden ratio
482 
483  QPixmap pm = QgsSymbolLayerUtils::symbolPreviewPixmap( previewSymbol.get(), QSize( width, height ), height / 20 );
484  QByteArray data;
485  QBuffer buffer( &data );
486  pm.save( &buffer, "PNG", 100 );
487  mChangePatternButton->setToolTip( QStringLiteral( "<img src='data:image/png;base64, %3'>" ).arg( QString( data.toBase64() ) ) );
488 }
489 
491 {
492  QgsSymbolLayerWidget::resizeEvent( event );
493  // redraw custom dash pattern icon -- the button size has changed
495 }
496 
497 
499 
500 
502  : QgsSymbolLayerWidget( parent, vl )
503 {
504  mLayer = nullptr;
505 
506  setupUi( this );
507  connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
508  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
509  connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
510  connect( mStrokeStyleComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mStrokeStyleComboBox_currentIndexChanged );
511  connect( mStrokeWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
512  connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
513  connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
520 
521  btnChangeColorFill->setAllowOpacity( true );
522  btnChangeColorFill->setColorDialogTitle( tr( "Select Fill Color" ) );
523  btnChangeColorFill->setContext( QStringLiteral( "symbology" ) );
524  btnChangeColorFill->setShowNoColor( true );
525  btnChangeColorFill->setNoColorString( tr( "Transparent Fill" ) );
526  btnChangeColorStroke->setAllowOpacity( true );
527  btnChangeColorStroke->setColorDialogTitle( tr( "Select Stroke Color" ) );
528  btnChangeColorStroke->setContext( QStringLiteral( "symbology" ) );
529  btnChangeColorStroke->setShowNoColor( true );
530  btnChangeColorStroke->setNoColorString( tr( "Transparent Stroke" ) );
531 
532  mFillColorDDBtn->registerLinkedWidget( btnChangeColorFill );
533  mStrokeColorDDBtn->registerLinkedWidget( btnChangeColorStroke );
534 
535  spinOffsetX->setClearValue( 0.0 );
536  spinOffsetY->setClearValue( 0.0 );
537  spinAngle->setClearValue( 0.0 );
538 
539  //make a temporary symbol for the size assistant preview
540  mAssistantPreviewSymbol.reset( new QgsMarkerSymbol() );
541 
542  if ( vectorLayer() )
543  mSizeDDBtn->setSymbol( mAssistantPreviewSymbol );
544 
545  int size = lstNames->iconSize().width();
546 
547 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
548  size = std::max( 30, static_cast< int >( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().width( 'X' ) * 3 ) ) );
549 #else
550  size = std::max( 30, static_cast< int >( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 3 ) ) );
551 #endif
552 
553  lstNames->setGridSize( QSize( size * 1.2, size * 1.2 ) );
554  lstNames->setIconSize( QSize( size, size ) );
555 
556  double markerSize = size * 0.8;
558  for ( QgsSimpleMarkerSymbolLayerBase::Shape shape : shapes )
559  {
560  QgsSimpleMarkerSymbolLayer *lyr = new QgsSimpleMarkerSymbolLayer( shape, markerSize );
562  lyr->setColor( QColor( 200, 200, 200 ) );
563  lyr->setStrokeColor( QColor( 0, 0, 0 ) );
564  QIcon icon = QgsSymbolLayerUtils::symbolLayerPreviewIcon( lyr, QgsUnitTypes::RenderPixels, QSize( size, size ) );
565  QListWidgetItem *item = new QListWidgetItem( icon, QString(), lstNames );
566  item->setData( Qt::UserRole, static_cast< int >( shape ) );
567  item->setToolTip( QgsSimpleMarkerSymbolLayerBase::encodeShape( shape ) );
568  delete lyr;
569  }
570  // show at least 3 rows
571  lstNames->setMinimumHeight( lstNames->gridSize().height() * 3.1 );
572 
573  connect( lstNames, &QListWidget::currentRowChanged, this, &QgsSimpleMarkerSymbolLayerWidget::setShape );
574  connect( btnChangeColorStroke, &QgsColorButton::colorChanged, this, &QgsSimpleMarkerSymbolLayerWidget::setColorStroke );
576  connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::penJoinStyleChanged );
577  connect( spinSize, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setSize );
578  connect( spinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setAngle );
579  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setOffset );
580  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setOffset );
581  connect( this, &QgsSymbolLayerWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::updateAssistantSymbol );
582 }
583 
585 {
586  if ( layer->layerType() != QLatin1String( "SimpleMarker" ) )
587  return;
588 
589  // layer type is correct, we can do the cast
590  mLayer = static_cast<QgsSimpleMarkerSymbolLayer *>( layer );
591 
592  // set values
594  for ( int i = 0; i < lstNames->count(); ++i )
595  {
596  if ( static_cast< QgsSimpleMarkerSymbolLayerBase::Shape >( lstNames->item( i )->data( Qt::UserRole ).toInt() ) == shape )
597  {
598  lstNames->setCurrentRow( i );
599  break;
600  }
601  }
602  btnChangeColorStroke->blockSignals( true );
603  btnChangeColorStroke->setColor( mLayer->strokeColor() );
604  btnChangeColorStroke->blockSignals( false );
605  btnChangeColorFill->blockSignals( true );
606  btnChangeColorFill->setColor( mLayer->fillColor() );
607  btnChangeColorFill->setEnabled( QgsSimpleMarkerSymbolLayerBase::shapeIsFilled( mLayer->shape() ) );
608  btnChangeColorFill->blockSignals( false );
609  spinSize->blockSignals( true );
610  spinSize->setValue( mLayer->size() );
611  spinSize->blockSignals( false );
612  spinAngle->blockSignals( true );
613  spinAngle->setValue( mLayer->angle() );
614  spinAngle->blockSignals( false );
615  mStrokeStyleComboBox->blockSignals( true );
616  mStrokeStyleComboBox->setPenStyle( mLayer->strokeStyle() );
617  mStrokeStyleComboBox->blockSignals( false );
618  mStrokeWidthSpinBox->blockSignals( true );
619  mStrokeWidthSpinBox->setValue( mLayer->strokeWidth() );
620  mStrokeWidthSpinBox->blockSignals( false );
621  cboJoinStyle->blockSignals( true );
622  cboJoinStyle->setPenJoinStyle( mLayer->penJoinStyle() );
623  cboJoinStyle->blockSignals( false );
624 
625  // without blocking signals the value gets changed because of slot setOffset()
626  spinOffsetX->blockSignals( true );
627  spinOffsetX->setValue( mLayer->offset().x() );
628  spinOffsetX->blockSignals( false );
629  spinOffsetY->blockSignals( true );
630  spinOffsetY->setValue( mLayer->offset().y() );
631  spinOffsetY->blockSignals( false );
632 
633  mSizeUnitWidget->blockSignals( true );
634  mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
635  mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
636  mSizeUnitWidget->blockSignals( false );
637  mOffsetUnitWidget->blockSignals( true );
638  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
639  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
640  mOffsetUnitWidget->blockSignals( false );
641  mStrokeWidthUnitWidget->blockSignals( true );
642  mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
643  mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
644  mStrokeWidthUnitWidget->blockSignals( false );
645 
646  //anchor points
647  mHorizontalAnchorComboBox->blockSignals( true );
648  mVerticalAnchorComboBox->blockSignals( true );
649  mHorizontalAnchorComboBox->setCurrentIndex( mLayer->horizontalAnchorPoint() );
650  mVerticalAnchorComboBox->setCurrentIndex( mLayer->verticalAnchorPoint() );
651  mHorizontalAnchorComboBox->blockSignals( false );
652  mVerticalAnchorComboBox->blockSignals( false );
653 
665 
666  updateAssistantSymbol();
667 }
668 
670 {
671  return mLayer;
672 }
673 
674 void QgsSimpleMarkerSymbolLayerWidget::setShape()
675 {
676  mLayer->setShape( static_cast< QgsSimpleMarkerSymbolLayerBase::Shape>( lstNames->currentItem()->data( Qt::UserRole ).toInt() ) );
677  btnChangeColorFill->setEnabled( QgsSimpleMarkerSymbolLayerBase::shapeIsFilled( mLayer->shape() ) );
678  emit changed();
679 }
680 
682 {
683  mLayer->setStrokeColor( color );
684  emit changed();
685 }
686 
688 {
689  mLayer->setColor( color );
690  emit changed();
691 }
692 
693 void QgsSimpleMarkerSymbolLayerWidget::penJoinStyleChanged()
694 {
695  mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
696  emit changed();
697 }
698 
699 void QgsSimpleMarkerSymbolLayerWidget::setSize()
700 {
701  mLayer->setSize( spinSize->value() );
702  emit changed();
703 }
704 
705 void QgsSimpleMarkerSymbolLayerWidget::setAngle()
706 {
707  mLayer->setAngle( spinAngle->value() );
708  emit changed();
709 }
710 
711 void QgsSimpleMarkerSymbolLayerWidget::setOffset()
712 {
713  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
714  emit changed();
715 }
716 
717 void QgsSimpleMarkerSymbolLayerWidget::mStrokeStyleComboBox_currentIndexChanged( int index )
718 {
719  Q_UNUSED( index )
720 
721  if ( mLayer )
722  {
723  mLayer->setStrokeStyle( mStrokeStyleComboBox->penStyle() );
724  emit changed();
725  }
726 }
727 
728 void QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
729 {
730  if ( mLayer )
731  {
732  mLayer->setStrokeWidth( d );
733  emit changed();
734  }
735 }
736 
737 void QgsSimpleMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
738 {
739  if ( mLayer )
740  {
741  mLayer->setSizeUnit( mSizeUnitWidget->unit() );
742  mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
743  emit changed();
744  }
745 }
746 
747 void QgsSimpleMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
748 {
749  if ( mLayer )
750  {
751  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
752  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
753  emit changed();
754  }
755 }
756 
757 void QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
758 {
759  if ( mLayer )
760  {
761  mLayer->setStrokeWidthUnit( mStrokeWidthUnitWidget->unit() );
762  mLayer->setStrokeWidthMapUnitScale( mStrokeWidthUnitWidget->getMapUnitScale() );
763  emit changed();
764  }
765 }
766 
767 void QgsSimpleMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
768 {
769  if ( mLayer )
770  {
772  emit changed();
773  }
774 }
775 
776 void QgsSimpleMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
777 {
778  if ( mLayer )
779  {
781  emit changed();
782  }
783 }
784 
785 void QgsSimpleMarkerSymbolLayerWidget::updateAssistantSymbol()
786 {
787  for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
788  {
789  mAssistantPreviewSymbol->deleteSymbolLayer( i );
790  }
791  mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
793  if ( ddSize )
794  mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
795 }
796 
797 
799 
801  : QgsSymbolLayerWidget( parent, vl )
802 {
803  mLayer = nullptr;
804 
805  setupUi( this );
806  connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleFillSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
807  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleFillSymbolLayerWidget::mOffsetUnitWidget_changed );
812 
813  btnChangeColor->setAllowOpacity( true );
814  btnChangeColor->setColorDialogTitle( tr( "Select Fill Color" ) );
815  btnChangeColor->setContext( QStringLiteral( "symbology" ) );
816  btnChangeColor->setShowNoColor( true );
817  btnChangeColor->setNoColorString( tr( "Transparent Fill" ) );
818  btnChangeStrokeColor->setAllowOpacity( true );
819  btnChangeStrokeColor->setColorDialogTitle( tr( "Select Stroke Color" ) );
820  btnChangeStrokeColor->setContext( QStringLiteral( "symbology" ) );
821  btnChangeStrokeColor->setShowNoColor( true );
822  btnChangeStrokeColor->setNoColorString( tr( "Transparent Stroke" ) );
823 
824  spinOffsetX->setClearValue( 0.0 );
825  spinOffsetY->setClearValue( 0.0 );
826 
828  connect( cboFillStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleFillSymbolLayerWidget::setBrushStyle );
829  connect( btnChangeStrokeColor, &QgsColorButton::colorChanged, this, &QgsSimpleFillSymbolLayerWidget::setStrokeColor );
830  connect( spinStrokeWidth, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleFillSymbolLayerWidget::strokeWidthChanged );
831  connect( cboStrokeStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleFillSymbolLayerWidget::strokeStyleChanged );
832  connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleFillSymbolLayerWidget::strokeStyleChanged );
833  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleFillSymbolLayerWidget::offsetChanged );
834  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleFillSymbolLayerWidget::offsetChanged );
835 
836  mFillColorDDBtn->registerLinkedWidget( btnChangeColor );
837  mStrokeColorDDBtn->registerLinkedWidget( btnChangeStrokeColor );
838 }
839 
841 {
842  if ( layer->layerType() != QLatin1String( "SimpleFill" ) )
843  return;
844 
845  // layer type is correct, we can do the cast
846  mLayer = static_cast<QgsSimpleFillSymbolLayer *>( layer );
847 
848  // set values
849  btnChangeColor->blockSignals( true );
850  btnChangeColor->setColor( mLayer->color() );
851  btnChangeColor->blockSignals( false );
852  cboFillStyle->blockSignals( true );
853  cboFillStyle->setBrushStyle( mLayer->brushStyle() );
854  cboFillStyle->blockSignals( false );
855  btnChangeStrokeColor->blockSignals( true );
856  btnChangeStrokeColor->setColor( mLayer->strokeColor() );
857  btnChangeStrokeColor->blockSignals( false );
858  cboStrokeStyle->blockSignals( true );
859  cboStrokeStyle->setPenStyle( mLayer->strokeStyle() );
860  cboStrokeStyle->blockSignals( false );
861  spinStrokeWidth->blockSignals( true );
862  spinStrokeWidth->setValue( mLayer->strokeWidth() );
863  spinStrokeWidth->blockSignals( false );
864  cboJoinStyle->blockSignals( true );
865  cboJoinStyle->setPenJoinStyle( mLayer->penJoinStyle() );
866  cboJoinStyle->blockSignals( false );
867  spinOffsetX->blockSignals( true );
868  spinOffsetX->setValue( mLayer->offset().x() );
869  spinOffsetX->blockSignals( false );
870  spinOffsetY->blockSignals( true );
871  spinOffsetY->setValue( mLayer->offset().y() );
872  spinOffsetY->blockSignals( false );
873 
874  mStrokeWidthUnitWidget->blockSignals( true );
875  mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
876  mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
877  mStrokeWidthUnitWidget->blockSignals( false );
878  mOffsetUnitWidget->blockSignals( true );
879  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
880  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
881  mOffsetUnitWidget->blockSignals( false );
882 
889 
890 }
891 
893 {
894  return mLayer;
895 }
896 
897 void QgsSimpleFillSymbolLayerWidget::setColor( const QColor &color )
898 {
899  mLayer->setColor( color );
900  emit changed();
901 }
902 
904 {
905  mLayer->setStrokeColor( color );
906  emit changed();
907 }
908 
909 void QgsSimpleFillSymbolLayerWidget::setBrushStyle()
910 {
911  mLayer->setBrushStyle( cboFillStyle->brushStyle() );
912  emit changed();
913 }
914 
915 void QgsSimpleFillSymbolLayerWidget::strokeWidthChanged()
916 {
917  mLayer->setStrokeWidth( spinStrokeWidth->value() );
918  emit changed();
919 }
920 
921 void QgsSimpleFillSymbolLayerWidget::strokeStyleChanged()
922 {
923  mLayer->setStrokeStyle( cboStrokeStyle->penStyle() );
924  mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
925  emit changed();
926 }
927 
928 void QgsSimpleFillSymbolLayerWidget::offsetChanged()
929 {
930  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
931  emit changed();
932 }
933 
934 void QgsSimpleFillSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
935 {
936  if ( mLayer )
937  {
938  mLayer->setStrokeWidthUnit( mStrokeWidthUnitWidget->unit() );
939  mLayer->setStrokeWidthMapUnitScale( mStrokeWidthUnitWidget->getMapUnitScale() );
940  emit changed();
941  }
942 }
943 
944 void QgsSimpleFillSymbolLayerWidget::mOffsetUnitWidget_changed()
945 {
946  if ( mLayer )
947  {
948  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
949  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
950  emit changed();
951  }
952 }
953 
955 
957  : QgsSymbolLayerWidget( parent, vl )
958 {
959  mLayer = nullptr;
960 
961  setupUi( this );
962  connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFilledMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
963  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFilledMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
964  connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFilledMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
965  connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFilledMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
970 
971  spinOffsetX->setClearValue( 0.0 );
972  spinOffsetY->setClearValue( 0.0 );
973  spinAngle->setClearValue( 0.0 );
974 
975  //make a temporary symbol for the size assistant preview
976  mAssistantPreviewSymbol.reset( new QgsMarkerSymbol() );
977 
978  if ( vectorLayer() )
979  mSizeDDBtn->setSymbol( mAssistantPreviewSymbol );
980 
981  int size = lstNames->iconSize().width();
982 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
983  size = std::max( 30, static_cast< int >( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().width( 'X' ) * 3 ) ) );
984 #else
985  size = std::max( 30, static_cast< int >( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 3 ) ) );
986 #endif
987  lstNames->setGridSize( QSize( size * 1.2, size * 1.2 ) );
988  lstNames->setIconSize( QSize( size, size ) );
989 
990  double markerSize = size * 0.8;
992  for ( QgsSimpleMarkerSymbolLayerBase::Shape shape : shapes )
993  {
994  QgsSimpleMarkerSymbolLayer *lyr = new QgsSimpleMarkerSymbolLayer( shape, markerSize );
996  lyr->setColor( QColor( 200, 200, 200 ) );
997  lyr->setStrokeColor( QColor( 0, 0, 0 ) );
998  QIcon icon = QgsSymbolLayerUtils::symbolLayerPreviewIcon( lyr, QgsUnitTypes::RenderPixels, QSize( size, size ) );
999  QListWidgetItem *item = new QListWidgetItem( icon, QString(), lstNames );
1000  item->setData( Qt::UserRole, static_cast< int >( shape ) );
1001  item->setToolTip( QgsSimpleMarkerSymbolLayerBase::encodeShape( shape ) );
1002  delete lyr;
1003  }
1004  // show at least 3 rows
1005  lstNames->setMinimumHeight( lstNames->gridSize().height() * 3.1 );
1006 
1007  connect( lstNames, &QListWidget::currentRowChanged, this, &QgsFilledMarkerSymbolLayerWidget::setShape );
1008  connect( spinSize, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setSize );
1009  connect( spinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setAngle );
1010  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setOffset );
1011  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setOffset );
1012  connect( this, &QgsSymbolLayerWidget::changed, this, &QgsFilledMarkerSymbolLayerWidget::updateAssistantSymbol );
1013 }
1014 
1016 {
1017  if ( layer->layerType() != QLatin1String( "FilledMarker" ) )
1018  return;
1019 
1020  // layer type is correct, we can do the cast
1021  mLayer = static_cast<QgsFilledMarkerSymbolLayer *>( layer );
1022 
1023  // set values
1025  for ( int i = 0; i < lstNames->count(); ++i )
1026  {
1027  if ( static_cast< QgsSimpleMarkerSymbolLayerBase::Shape >( lstNames->item( i )->data( Qt::UserRole ).toInt() ) == shape )
1028  {
1029  lstNames->setCurrentRow( i );
1030  break;
1031  }
1032  }
1033  whileBlocking( spinSize )->setValue( mLayer->size() );
1034  whileBlocking( spinAngle )->setValue( mLayer->angle() );
1035  whileBlocking( spinOffsetX )->setValue( mLayer->offset().x() );
1036  whileBlocking( spinOffsetY )->setValue( mLayer->offset().y() );
1037 
1038  mSizeUnitWidget->blockSignals( true );
1039  mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
1040  mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
1041  mSizeUnitWidget->blockSignals( false );
1042  mOffsetUnitWidget->blockSignals( true );
1043  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1044  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1045  mOffsetUnitWidget->blockSignals( false );
1046 
1047  //anchor points
1048  whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mLayer->horizontalAnchorPoint() );
1049  whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mLayer->verticalAnchorPoint() );
1050 
1057 
1058  updateAssistantSymbol();
1059 }
1060 
1062 {
1063  return mLayer;
1064 }
1065 
1066 void QgsFilledMarkerSymbolLayerWidget::setShape()
1067 {
1068  mLayer->setShape( static_cast< QgsSimpleMarkerSymbolLayerBase::Shape>( lstNames->currentItem()->data( Qt::UserRole ).toInt() ) );
1069  emit changed();
1070 }
1071 
1072 void QgsFilledMarkerSymbolLayerWidget::setSize()
1073 {
1074  mLayer->setSize( spinSize->value() );
1075  emit changed();
1076 }
1077 
1078 void QgsFilledMarkerSymbolLayerWidget::setAngle()
1079 {
1080  mLayer->setAngle( spinAngle->value() );
1081  emit changed();
1082 }
1083 
1084 void QgsFilledMarkerSymbolLayerWidget::setOffset()
1085 {
1086  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1087  emit changed();
1088 }
1089 
1090 void QgsFilledMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
1091 {
1092  if ( mLayer )
1093  {
1094  mLayer->setSizeUnit( mSizeUnitWidget->unit() );
1095  mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
1096  emit changed();
1097  }
1098 }
1099 
1100 void QgsFilledMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
1101 {
1102  if ( mLayer )
1103  {
1104  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1105  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1106  emit changed();
1107  }
1108 }
1109 
1110 void QgsFilledMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
1111 {
1112  if ( mLayer )
1113  {
1115  emit changed();
1116  }
1117 }
1118 
1119 void QgsFilledMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
1120 {
1121  if ( mLayer )
1122  {
1124  emit changed();
1125  }
1126 }
1127 
1128 void QgsFilledMarkerSymbolLayerWidget::updateAssistantSymbol()
1129 {
1130  for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
1131  {
1132  mAssistantPreviewSymbol->deleteSymbolLayer( i );
1133  }
1134  mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
1136  if ( ddSize )
1137  mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
1138 }
1139 
1140 
1142 
1144  : QgsSymbolLayerWidget( parent, vl )
1145 {
1146  mLayer = nullptr;
1147 
1148  setupUi( this );
1149  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsGradientFillSymbolLayerWidget::mOffsetUnitWidget_changed );
1150  connect( mSpinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::mSpinAngle_valueChanged );
1153 
1154  btnColorRamp->setShowGradientOnly( true );
1155 
1156  btnChangeColor->setAllowOpacity( true );
1157  btnChangeColor->setColorDialogTitle( tr( "Select Gradient Color" ) );
1158  btnChangeColor->setContext( QStringLiteral( "symbology" ) );
1159  btnChangeColor->setShowNoColor( true );
1160  btnChangeColor->setNoColorString( tr( "Transparent" ) );
1161  btnChangeColor2->setAllowOpacity( true );
1162  btnChangeColor2->setColorDialogTitle( tr( "Select Gradient Color" ) );
1163  btnChangeColor2->setContext( QStringLiteral( "symbology" ) );
1164  btnChangeColor2->setShowNoColor( true );
1165  btnChangeColor2->setNoColorString( tr( "Transparent" ) );
1166 
1167  mStartColorDDBtn->registerLinkedWidget( btnChangeColor );
1168  mEndColorDDBtn->registerLinkedWidget( btnChangeColor2 );
1169 
1170  spinOffsetX->setClearValue( 0.0 );
1171  spinOffsetY->setClearValue( 0.0 );
1172  mSpinAngle->setClearValue( 0.0 );
1173 
1177  connect( cboGradientType, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGradientFillSymbolLayerWidget::setGradientType );
1178  connect( cboCoordinateMode, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGradientFillSymbolLayerWidget::setCoordinateMode );
1179  connect( cboGradientSpread, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGradientFillSymbolLayerWidget::setGradientSpread );
1180  connect( radioTwoColor, &QAbstractButton::toggled, this, &QgsGradientFillSymbolLayerWidget::colorModeChanged );
1181  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::offsetChanged );
1182  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::offsetChanged );
1183  connect( spinRefPoint1X, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1184  connect( spinRefPoint1Y, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1185  connect( checkRefPoint1Centroid, &QAbstractButton::toggled, this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1186  connect( spinRefPoint2X, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1187  connect( spinRefPoint2Y, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1188  connect( checkRefPoint2Centroid, &QAbstractButton::toggled, this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1189 }
1190 
1192 {
1193  if ( layer->layerType() != QLatin1String( "GradientFill" ) )
1194  return;
1195 
1196  // layer type is correct, we can do the cast
1197  mLayer = static_cast<QgsGradientFillSymbolLayer *>( layer );
1198 
1199  // set values
1200  btnChangeColor->blockSignals( true );
1201  btnChangeColor->setColor( mLayer->color() );
1202  btnChangeColor->blockSignals( false );
1203  btnChangeColor2->blockSignals( true );
1204  btnChangeColor2->setColor( mLayer->color2() );
1205  btnChangeColor2->blockSignals( false );
1206 
1208  {
1209  radioTwoColor->setChecked( true );
1210  btnColorRamp->setEnabled( false );
1211  }
1212  else
1213  {
1214  radioColorRamp->setChecked( true );
1215  btnChangeColor->setEnabled( false );
1216  btnChangeColor2->setEnabled( false );
1217  }
1218 
1219  // set source color ramp
1220  if ( mLayer->colorRamp() )
1221  {
1222  btnColorRamp->blockSignals( true );
1223  btnColorRamp->setColorRamp( mLayer->colorRamp() );
1224  btnColorRamp->blockSignals( false );
1225  }
1226 
1227  cboGradientType->blockSignals( true );
1228  switch ( mLayer->gradientType() )
1229  {
1231  cboGradientType->setCurrentIndex( 0 );
1232  break;
1234  cboGradientType->setCurrentIndex( 1 );
1235  break;
1237  cboGradientType->setCurrentIndex( 2 );
1238  break;
1239  }
1240  cboGradientType->blockSignals( false );
1241 
1242  cboCoordinateMode->blockSignals( true );
1243  switch ( mLayer->coordinateMode() )
1244  {
1246  cboCoordinateMode->setCurrentIndex( 1 );
1247  checkRefPoint1Centroid->setEnabled( false );
1248  checkRefPoint2Centroid->setEnabled( false );
1249  break;
1251  default:
1252  cboCoordinateMode->setCurrentIndex( 0 );
1253  break;
1254  }
1255  cboCoordinateMode->blockSignals( false );
1256 
1257  cboGradientSpread->blockSignals( true );
1258  switch ( mLayer->gradientSpread() )
1259  {
1261  cboGradientSpread->setCurrentIndex( 0 );
1262  break;
1264  cboGradientSpread->setCurrentIndex( 1 );
1265  break;
1267  cboGradientSpread->setCurrentIndex( 2 );
1268  break;
1269  }
1270  cboGradientSpread->blockSignals( false );
1271 
1272  spinRefPoint1X->blockSignals( true );
1273  spinRefPoint1X->setValue( mLayer->referencePoint1().x() );
1274  spinRefPoint1X->blockSignals( false );
1275  spinRefPoint1Y->blockSignals( true );
1276  spinRefPoint1Y->setValue( mLayer->referencePoint1().y() );
1277  spinRefPoint1Y->blockSignals( false );
1278  checkRefPoint1Centroid->blockSignals( true );
1279  checkRefPoint1Centroid->setChecked( mLayer->referencePoint1IsCentroid() );
1281  {
1282  spinRefPoint1X->setEnabled( false );
1283  spinRefPoint1Y->setEnabled( false );
1284  }
1285  checkRefPoint1Centroid->blockSignals( false );
1286  spinRefPoint2X->blockSignals( true );
1287  spinRefPoint2X->setValue( mLayer->referencePoint2().x() );
1288  spinRefPoint2X->blockSignals( false );
1289  spinRefPoint2Y->blockSignals( true );
1290  spinRefPoint2Y->setValue( mLayer->referencePoint2().y() );
1291  spinRefPoint2Y->blockSignals( false );
1292  checkRefPoint2Centroid->blockSignals( true );
1293  checkRefPoint2Centroid->setChecked( mLayer->referencePoint2IsCentroid() );
1295  {
1296  spinRefPoint2X->setEnabled( false );
1297  spinRefPoint2Y->setEnabled( false );
1298  }
1299  checkRefPoint2Centroid->blockSignals( false );
1300 
1301  spinOffsetX->blockSignals( true );
1302  spinOffsetX->setValue( mLayer->offset().x() );
1303  spinOffsetX->blockSignals( false );
1304  spinOffsetY->blockSignals( true );
1305  spinOffsetY->setValue( mLayer->offset().y() );
1306  spinOffsetY->blockSignals( false );
1307  mSpinAngle->blockSignals( true );
1308  mSpinAngle->setValue( mLayer->angle() );
1309  mSpinAngle->blockSignals( false );
1310 
1311  mOffsetUnitWidget->blockSignals( true );
1312  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1313  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1314  mOffsetUnitWidget->blockSignals( false );
1315 
1328 }
1329 
1331 {
1332  return mLayer;
1333 }
1334 
1336 {
1337  mLayer->setColor( color );
1338  emit changed();
1339 }
1340 
1342 {
1343  mLayer->setColor2( color );
1344  emit changed();
1345 }
1346 
1347 void QgsGradientFillSymbolLayerWidget::colorModeChanged()
1348 {
1349  if ( radioTwoColor->isChecked() )
1350  {
1352  }
1353  else
1354  {
1356  }
1357  emit changed();
1358 }
1359 
1361 {
1362  if ( btnColorRamp->isNull() )
1363  return;
1364 
1365  mLayer->setColorRamp( btnColorRamp->colorRamp()->clone() );
1366  emit changed();
1367 }
1368 
1370 {
1371  switch ( index )
1372  {
1373  case 0:
1375  //set sensible default reference points
1376  spinRefPoint1X->setValue( 0.5 );
1377  spinRefPoint1Y->setValue( 0 );
1378  spinRefPoint2X->setValue( 0.5 );
1379  spinRefPoint2Y->setValue( 1 );
1380  break;
1381  case 1:
1383  //set sensible default reference points
1384  spinRefPoint1X->setValue( 0 );
1385  spinRefPoint1Y->setValue( 0 );
1386  spinRefPoint2X->setValue( 1 );
1387  spinRefPoint2Y->setValue( 1 );
1388  break;
1389  case 2:
1391  spinRefPoint1X->setValue( 0.5 );
1392  spinRefPoint1Y->setValue( 0.5 );
1393  spinRefPoint2X->setValue( 1 );
1394  spinRefPoint2Y->setValue( 1 );
1395  break;
1396  }
1397  emit changed();
1398 }
1399 
1401 {
1402 
1403  switch ( index )
1404  {
1405  case 0:
1406  //feature coordinate mode
1408  //allow choice of centroid reference positions
1409  checkRefPoint1Centroid->setEnabled( true );
1410  checkRefPoint2Centroid->setEnabled( true );
1411  break;
1412  case 1:
1413  //viewport coordinate mode
1415  //disable choice of centroid reference positions
1416  checkRefPoint1Centroid->setChecked( Qt::Unchecked );
1417  checkRefPoint1Centroid->setEnabled( false );
1418  checkRefPoint2Centroid->setChecked( Qt::Unchecked );
1419  checkRefPoint2Centroid->setEnabled( false );
1420  break;
1421  }
1422 
1423  emit changed();
1424 }
1425 
1427 {
1428  switch ( index )
1429  {
1430  case 0:
1432  break;
1433  case 1:
1435  break;
1436  case 2:
1438  break;
1439  }
1440 
1441  emit changed();
1442 }
1443 
1444 void QgsGradientFillSymbolLayerWidget::offsetChanged()
1445 {
1446  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1447  emit changed();
1448 }
1449 
1450 void QgsGradientFillSymbolLayerWidget::referencePointChanged()
1451 {
1452  mLayer->setReferencePoint1( QPointF( spinRefPoint1X->value(), spinRefPoint1Y->value() ) );
1453  mLayer->setReferencePoint1IsCentroid( checkRefPoint1Centroid->isChecked() );
1454  mLayer->setReferencePoint2( QPointF( spinRefPoint2X->value(), spinRefPoint2Y->value() ) );
1455  mLayer->setReferencePoint2IsCentroid( checkRefPoint2Centroid->isChecked() );
1456  emit changed();
1457 }
1458 
1459 void QgsGradientFillSymbolLayerWidget::mSpinAngle_valueChanged( double value )
1460 {
1461  mLayer->setAngle( value );
1462  emit changed();
1463 }
1464 
1465 void QgsGradientFillSymbolLayerWidget::mOffsetUnitWidget_changed()
1466 {
1467  if ( mLayer )
1468  {
1469  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1470  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1471  emit changed();
1472  }
1473 }
1474 
1476 
1478  : QgsSymbolLayerWidget( parent, vl )
1479 {
1480  mLayer = nullptr;
1481 
1482  setupUi( this );
1483  connect( mSpinBlurRadius, qgis::overload< int >::of( &QSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::mSpinBlurRadius_valueChanged );
1484  connect( mSpinMaxDistance, qgis::overload< double >::of( &QDoubleSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::mSpinMaxDistance_valueChanged );
1485  connect( mDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsShapeburstFillSymbolLayerWidget::mDistanceUnitWidget_changed );
1486  connect( mRadioUseWholeShape, &QRadioButton::toggled, this, &QgsShapeburstFillSymbolLayerWidget::mRadioUseWholeShape_toggled );
1487  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsShapeburstFillSymbolLayerWidget::mOffsetUnitWidget_changed );
1488  connect( mIgnoreRingsCheckBox, &QCheckBox::stateChanged, this, &QgsShapeburstFillSymbolLayerWidget::mIgnoreRingsCheckBox_stateChanged );
1493 
1494  QButtonGroup *group1 = new QButtonGroup( this );
1495  group1->addButton( radioColorRamp );
1496  group1->addButton( radioTwoColor );
1497  QButtonGroup *group2 = new QButtonGroup( this );
1498  group2->addButton( mRadioUseMaxDistance );
1499  group2->addButton( mRadioUseWholeShape );
1500  btnChangeColor->setAllowOpacity( true );
1501  btnChangeColor->setColorDialogTitle( tr( "Select Gradient Color" ) );
1502  btnChangeColor->setContext( QStringLiteral( "symbology" ) );
1503  btnChangeColor->setShowNoColor( true );
1504  btnChangeColor->setNoColorString( tr( "Transparent" ) );
1505  btnChangeColor2->setAllowOpacity( true );
1506  btnChangeColor2->setColorDialogTitle( tr( "Select Gradient Color" ) );
1507  btnChangeColor2->setContext( QStringLiteral( "symbology" ) );
1508  btnChangeColor2->setShowNoColor( true );
1509  btnChangeColor2->setNoColorString( tr( "Transparent" ) );
1510 
1511  mStartColorDDBtn->registerLinkedWidget( btnChangeColor );
1512  mEndColorDDBtn->registerLinkedWidget( btnChangeColor2 );
1513 
1514  spinOffsetX->setClearValue( 0.0 );
1515  spinOffsetY->setClearValue( 0.0 );
1516 
1517  btnColorRamp->setShowGradientOnly( true );
1518 
1519  connect( btnColorRamp, &QgsColorRampButton::colorRampChanged, this, &QgsShapeburstFillSymbolLayerWidget::applyColorRamp );
1520 
1523  connect( radioTwoColor, &QAbstractButton::toggled, this, &QgsShapeburstFillSymbolLayerWidget::colorModeChanged );
1524  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::offsetChanged );
1525  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::offsetChanged );
1526 
1527  connect( mBlurSlider, &QAbstractSlider::valueChanged, mSpinBlurRadius, &QSpinBox::setValue );
1528  connect( mSpinBlurRadius, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), mBlurSlider, &QAbstractSlider::setValue );
1529 }
1530 
1532 {
1533  if ( layer->layerType() != QLatin1String( "ShapeburstFill" ) )
1534  return;
1535 
1536  // layer type is correct, we can do the cast
1537  mLayer = static_cast<QgsShapeburstFillSymbolLayer *>( layer );
1538 
1539  // set values
1540  btnChangeColor->blockSignals( true );
1541  btnChangeColor->setColor( mLayer->color() );
1542  btnChangeColor->blockSignals( false );
1543  btnChangeColor2->blockSignals( true );
1544  btnChangeColor2->setColor( mLayer->color2() );
1545  btnChangeColor2->blockSignals( false );
1546 
1548  {
1549  radioTwoColor->setChecked( true );
1550  btnColorRamp->setEnabled( false );
1551  }
1552  else
1553  {
1554  radioColorRamp->setChecked( true );
1555  btnChangeColor->setEnabled( false );
1556  btnChangeColor2->setEnabled( false );
1557  }
1558 
1559  mSpinBlurRadius->blockSignals( true );
1560  mBlurSlider->blockSignals( true );
1561  mSpinBlurRadius->setValue( mLayer->blurRadius() );
1562  mBlurSlider->setValue( mLayer->blurRadius() );
1563  mSpinBlurRadius->blockSignals( false );
1564  mBlurSlider->blockSignals( false );
1565 
1566  mSpinMaxDistance->blockSignals( true );
1567  mSpinMaxDistance->setValue( mLayer->maxDistance() );
1568  mSpinMaxDistance->blockSignals( false );
1569 
1570  mRadioUseWholeShape->blockSignals( true );
1571  mRadioUseMaxDistance->blockSignals( true );
1572  if ( mLayer->useWholeShape() )
1573  {
1574  mRadioUseWholeShape->setChecked( true );
1575  mSpinMaxDistance->setEnabled( false );
1576  mDistanceUnitWidget->setEnabled( false );
1577  }
1578  else
1579  {
1580  mRadioUseMaxDistance->setChecked( true );
1581  mSpinMaxDistance->setEnabled( true );
1582  mDistanceUnitWidget->setEnabled( true );
1583  }
1584  mRadioUseWholeShape->blockSignals( false );
1585  mRadioUseMaxDistance->blockSignals( false );
1586 
1587  mDistanceUnitWidget->blockSignals( true );
1588  mDistanceUnitWidget->setUnit( mLayer->distanceUnit() );
1589  mDistanceUnitWidget->setMapUnitScale( mLayer->distanceMapUnitScale() );
1590  mDistanceUnitWidget->blockSignals( false );
1591 
1592  mIgnoreRingsCheckBox->blockSignals( true );
1593  mIgnoreRingsCheckBox->setCheckState( mLayer->ignoreRings() ? Qt::Checked : Qt::Unchecked );
1594  mIgnoreRingsCheckBox->blockSignals( false );
1595 
1596  // set source color ramp
1597  if ( mLayer->colorRamp() )
1598  {
1599  btnColorRamp->blockSignals( true );
1600  btnColorRamp->setColorRamp( mLayer->colorRamp() );
1601  btnColorRamp->blockSignals( false );
1602  }
1603 
1604  spinOffsetX->blockSignals( true );
1605  spinOffsetX->setValue( mLayer->offset().x() );
1606  spinOffsetX->blockSignals( false );
1607  spinOffsetY->blockSignals( true );
1608  spinOffsetY->setValue( mLayer->offset().y() );
1609  spinOffsetY->blockSignals( false );
1610  mOffsetUnitWidget->blockSignals( true );
1611  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1612  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1613  mOffsetUnitWidget->blockSignals( false );
1614 
1621 }
1622 
1624 {
1625  return mLayer;
1626 }
1627 
1629 {
1630  if ( mLayer )
1631  {
1632  mLayer->setColor( color );
1633  emit changed();
1634  }
1635 }
1636 
1638 {
1639  if ( mLayer )
1640  {
1641  mLayer->setColor2( color );
1642  emit changed();
1643  }
1644 }
1645 
1646 void QgsShapeburstFillSymbolLayerWidget::colorModeChanged()
1647 {
1648  if ( !mLayer )
1649  {
1650  return;
1651  }
1652 
1653  if ( radioTwoColor->isChecked() )
1654  {
1656  }
1657  else
1658  {
1660  }
1661  emit changed();
1662 }
1663 
1664 void QgsShapeburstFillSymbolLayerWidget::mSpinBlurRadius_valueChanged( int value )
1665 {
1666  if ( mLayer )
1667  {
1668  mLayer->setBlurRadius( value );
1669  emit changed();
1670  }
1671 }
1672 
1673 void QgsShapeburstFillSymbolLayerWidget::mSpinMaxDistance_valueChanged( double value )
1674 {
1675  if ( mLayer )
1676  {
1677  mLayer->setMaxDistance( value );
1678  emit changed();
1679  }
1680 }
1681 
1682 void QgsShapeburstFillSymbolLayerWidget::mDistanceUnitWidget_changed()
1683 {
1684  if ( mLayer )
1685  {
1686  mLayer->setDistanceUnit( mDistanceUnitWidget->unit() );
1687  mLayer->setDistanceMapUnitScale( mDistanceUnitWidget->getMapUnitScale() );
1688  emit changed();
1689  }
1690 }
1691 
1692 void QgsShapeburstFillSymbolLayerWidget::mRadioUseWholeShape_toggled( bool value )
1693 {
1694  if ( mLayer )
1695  {
1696  mLayer->setUseWholeShape( value );
1697  mDistanceUnitWidget->setEnabled( !value );
1698  emit changed();
1699  }
1700 }
1701 
1702 void QgsShapeburstFillSymbolLayerWidget::applyColorRamp()
1703 {
1704  QgsColorRamp *ramp = btnColorRamp->colorRamp();
1705  if ( !ramp )
1706  return;
1707 
1708  mLayer->setColorRamp( ramp );
1709  emit changed();
1710 }
1711 
1712 void QgsShapeburstFillSymbolLayerWidget::offsetChanged()
1713 {
1714  if ( mLayer )
1715  {
1716  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1717  emit changed();
1718  }
1719 }
1720 
1721 void QgsShapeburstFillSymbolLayerWidget::mOffsetUnitWidget_changed()
1722 {
1723  if ( mLayer )
1724  {
1725  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1726  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1727  emit changed();
1728  }
1729 }
1730 
1731 
1732 void QgsShapeburstFillSymbolLayerWidget::mIgnoreRingsCheckBox_stateChanged( int state )
1733 {
1734  bool checked = ( state == Qt::Checked );
1735  mLayer->setIgnoreRings( checked );
1736  emit changed();
1737 }
1738 
1740 
1742  : QgsSymbolLayerWidget( parent, vl )
1743 {
1744  mLayer = nullptr;
1745 
1746  setupUi( this );
1747  connect( mIntervalUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsMarkerLineSymbolLayerWidget::mIntervalUnitWidget_changed );
1748  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsMarkerLineSymbolLayerWidget::mOffsetUnitWidget_changed );
1749  connect( mOffsetAlongLineUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsMarkerLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed );
1750  connect( mAverageAngleUnit, &QgsUnitSelectionWidget::changed, this, &QgsMarkerLineSymbolLayerWidget::averageAngleUnitChanged );
1759 
1760  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconAllRings.svg" ) ), tr( "All Rings" ), QgsLineSymbolLayer::AllRings );
1761  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconExteriorRing.svg" ) ), tr( "Exterior Ring Only" ), QgsLineSymbolLayer::ExteriorRingOnly );
1762  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconInteriorRings.svg" ) ), tr( "Interior Rings Only" ), QgsLineSymbolLayer::InteriorRingsOnly );
1763  connect( mRingFilterComboBox, qgis::overload< int >::of( &QComboBox::currentIndexChanged ), this, [ = ]( int )
1764  {
1765  if ( mLayer )
1766  {
1767  mLayer->setRingFilter( static_cast< QgsLineSymbolLayer::RenderRingFilter >( mRingFilterComboBox->currentData().toInt() ) );
1768  emit changed();
1769  }
1770  } );
1771 
1772  spinOffset->setClearValue( 0.0 );
1773 
1774 
1775  if ( vl && vl->geometryType() != QgsWkbTypes::PolygonGeometry )
1776  {
1777  mRingFilterComboBox->hide();
1778  mRingsLabel->hide();
1779  }
1780 
1781  mSpinAverageAngleLength->setClearValue( 4.0 );
1782 
1783  connect( spinInterval, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsMarkerLineSymbolLayerWidget::setInterval );
1784  connect( mSpinOffsetAlongLine, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsMarkerLineSymbolLayerWidget::setOffsetAlongLine );
1785  connect( chkRotateMarker, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setRotate );
1786  connect( spinOffset, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsMarkerLineSymbolLayerWidget::setOffset );
1787  connect( mSpinAverageAngleLength, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsMarkerLineSymbolLayerWidget::setAverageAngle );
1788  connect( radInterval, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1789  connect( radVertex, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1790  connect( radVertexLast, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1791  connect( radVertexFirst, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1792  connect( radCentralPoint, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1793  connect( radCurvePoint, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1794  connect( radSegmentCentralPoint, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1795 }
1796 
1798 {
1799  if ( layer->layerType() != QLatin1String( "MarkerLine" ) )
1800  return;
1801 
1802  // layer type is correct, we can do the cast
1803  mLayer = static_cast<QgsMarkerLineSymbolLayer *>( layer );
1804 
1805  // set values
1806  spinInterval->blockSignals( true );
1807  spinInterval->setValue( mLayer->interval() );
1808  spinInterval->blockSignals( false );
1809  mSpinOffsetAlongLine->blockSignals( true );
1810  mSpinOffsetAlongLine->setValue( mLayer->offsetAlongLine() );
1811  mSpinOffsetAlongLine->blockSignals( false );
1812  chkRotateMarker->blockSignals( true );
1813  chkRotateMarker->setChecked( mLayer->rotateSymbols() );
1814  chkRotateMarker->blockSignals( false );
1815  spinOffset->blockSignals( true );
1816  spinOffset->setValue( mLayer->offset() );
1817  spinOffset->blockSignals( false );
1819  radInterval->setChecked( true );
1821  radVertex->setChecked( true );
1823  radVertexLast->setChecked( true );
1825  radCentralPoint->setChecked( true );
1827  radCurvePoint->setChecked( true );
1829  radSegmentCentralPoint->setChecked( true );
1830  else
1831  radVertexFirst->setChecked( true );
1832 
1833  // set units
1834  mIntervalUnitWidget->blockSignals( true );
1835  mIntervalUnitWidget->setUnit( mLayer->intervalUnit() );
1836  mIntervalUnitWidget->setMapUnitScale( mLayer->intervalMapUnitScale() );
1837  mIntervalUnitWidget->blockSignals( false );
1838  mOffsetUnitWidget->blockSignals( true );
1839  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1840  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1841  mOffsetUnitWidget->blockSignals( false );
1842  mOffsetAlongLineUnitWidget->blockSignals( true );
1843  mOffsetAlongLineUnitWidget->setUnit( mLayer->offsetAlongLineUnit() );
1844  mOffsetAlongLineUnitWidget->setMapUnitScale( mLayer->offsetAlongLineMapUnitScale() );
1845  mOffsetAlongLineUnitWidget->blockSignals( false );
1846 
1847  whileBlocking( mAverageAngleUnit )->setUnit( mLayer->averageAngleUnit() );
1848  whileBlocking( mAverageAngleUnit )->setMapUnitScale( mLayer->averageAngleMapUnitScale() );
1849  whileBlocking( mSpinAverageAngleLength )->setValue( mLayer->averageAngleLength() );
1850 
1851  whileBlocking( mRingFilterComboBox )->setCurrentIndex( mRingFilterComboBox->findData( mLayer->ringFilter() ) );
1852 
1853  setPlacement(); // update gui
1854 
1860 }
1861 
1863 {
1864  return mLayer;
1865 }
1866 
1868 {
1869  mLayer->setInterval( val );
1870  emit changed();
1871 }
1872 
1874 {
1875  mLayer->setOffsetAlongLine( val );
1876  emit changed();
1877 }
1878 
1879 void QgsMarkerLineSymbolLayerWidget::setRotate()
1880 {
1881  mSpinAverageAngleLength->setEnabled( chkRotateMarker->isChecked() && ( radInterval->isChecked() || radCentralPoint->isChecked() ) );
1882  mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
1883 
1884  mLayer->setRotateSymbols( chkRotateMarker->isChecked() );
1885  emit changed();
1886 }
1887 
1888 void QgsMarkerLineSymbolLayerWidget::setOffset()
1889 {
1890  mLayer->setOffset( spinOffset->value() );
1891  emit changed();
1892 }
1893 
1894 void QgsMarkerLineSymbolLayerWidget::setPlacement()
1895 {
1896  bool interval = radInterval->isChecked();
1897  spinInterval->setEnabled( interval );
1898  mSpinOffsetAlongLine->setEnabled( radInterval->isChecked() || radVertexLast->isChecked() || radVertexFirst->isChecked() );
1899  mOffsetAlongLineUnitWidget->setEnabled( mSpinOffsetAlongLine->isEnabled() );
1900  mSpinAverageAngleLength->setEnabled( chkRotateMarker->isChecked() && ( radInterval->isChecked() || radCentralPoint->isChecked() ) );
1901  mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
1902  //mLayer->setPlacement( interval ? QgsMarkerLineSymbolLayer::Interval : QgsMarkerLineSymbolLayer::Vertex );
1903  if ( radInterval->isChecked() )
1905  else if ( radVertex->isChecked() )
1907  else if ( radVertexLast->isChecked() )
1909  else if ( radVertexFirst->isChecked() )
1911  else if ( radCurvePoint->isChecked() )
1913  else if ( radSegmentCentralPoint->isChecked() )
1915  else
1917 
1918  emit changed();
1919 }
1920 
1921 void QgsMarkerLineSymbolLayerWidget::mIntervalUnitWidget_changed()
1922 {
1923  if ( mLayer )
1924  {
1925  mLayer->setIntervalUnit( mIntervalUnitWidget->unit() );
1926  mLayer->setIntervalMapUnitScale( mIntervalUnitWidget->getMapUnitScale() );
1927  emit changed();
1928  }
1929 }
1930 
1931 void QgsMarkerLineSymbolLayerWidget::mOffsetUnitWidget_changed()
1932 {
1933  if ( mLayer )
1934  {
1935  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1936  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1937  emit changed();
1938  }
1939 }
1940 
1941 void QgsMarkerLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed()
1942 {
1943  if ( mLayer )
1944  {
1945  mLayer->setOffsetAlongLineUnit( mOffsetAlongLineUnitWidget->unit() );
1946  mLayer->setOffsetAlongLineMapUnitScale( mOffsetAlongLineUnitWidget->getMapUnitScale() );
1947  }
1948  emit changed();
1949 }
1950 
1951 void QgsMarkerLineSymbolLayerWidget::averageAngleUnitChanged()
1952 {
1953  if ( mLayer )
1954  {
1955  mLayer->setAverageAngleUnit( mAverageAngleUnit->unit() );
1956  mLayer->setAverageAngleMapUnitScale( mAverageAngleUnit->getMapUnitScale() );
1957  }
1958  emit changed();
1959 }
1960 
1961 void QgsMarkerLineSymbolLayerWidget::setAverageAngle( double val )
1962 {
1963  if ( mLayer )
1964  {
1965  mLayer->setAverageAngleLength( val );
1966  emit changed();
1967  }
1968 }
1969 
1970 
1972 
1974  : QgsSymbolLayerWidget( parent, vl )
1975 {
1976  mLayer = nullptr;
1977 
1978  setupUi( this );
1979  connect( mIntervalUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::mIntervalUnitWidget_changed );
1980  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::mOffsetUnitWidget_changed );
1981  connect( mOffsetAlongLineUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed );
1982  connect( mAverageAngleUnit, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::averageAngleUnitChanged );
1983  connect( mHashLengthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::hashLengthUnitWidgetChanged );
1994 
1995  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconAllRings.svg" ) ), tr( "All Rings" ), QgsLineSymbolLayer::AllRings );
1996  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconExteriorRing.svg" ) ), tr( "Exterior Ring Only" ), QgsLineSymbolLayer::ExteriorRingOnly );
1997  mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconInteriorRings.svg" ) ), tr( "Interior Rings Only" ), QgsLineSymbolLayer::InteriorRingsOnly );
1998  connect( mRingFilterComboBox, qgis::overload< int >::of( &QComboBox::currentIndexChanged ), this, [ = ]( int )
1999  {
2000  if ( mLayer )
2001  {
2002  mLayer->setRingFilter( static_cast< QgsLineSymbolLayer::RenderRingFilter >( mRingFilterComboBox->currentData().toInt() ) );
2003  emit changed();
2004  }
2005  } );
2006 
2007  spinOffset->setClearValue( 0.0 );
2008 
2009 
2010  if ( vl && vl->geometryType() != QgsWkbTypes::PolygonGeometry )
2011  {
2012  mRingFilterComboBox->hide();
2013  mRingsLabel->hide();
2014  }
2015 
2016  mHashRotationSpinBox->setClearValue( 0 );
2017  mSpinAverageAngleLength->setClearValue( 4.0 );
2018 
2019  connect( spinInterval, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setInterval );
2020  connect( mSpinOffsetAlongLine, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setOffsetAlongLine );
2021  connect( mSpinHashLength, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setHashLength );
2022  connect( mHashRotationSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setHashAngle );
2023  connect( chkRotateMarker, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setRotate );
2024  connect( spinOffset, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setOffset );
2025  connect( mSpinAverageAngleLength, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setAverageAngle );
2026  connect( radInterval, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2027  connect( radVertex, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2028  connect( radVertexLast, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2029  connect( radVertexFirst, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2030  connect( radCentralPoint, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2031  connect( radCurvePoint, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2032  connect( radSegmentCentralPoint, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2033 }
2034 
2036 {
2037  if ( layer->layerType() != QLatin1String( "HashLine" ) )
2038  return;
2039 
2040  // layer type is correct, we can do the cast
2041  mLayer = static_cast<QgsHashedLineSymbolLayer *>( layer );
2042 
2043  // set values
2044  spinInterval->blockSignals( true );
2045  spinInterval->setValue( mLayer->interval() );
2046  spinInterval->blockSignals( false );
2047  mSpinOffsetAlongLine->blockSignals( true );
2048  mSpinOffsetAlongLine->setValue( mLayer->offsetAlongLine() );
2049  mSpinOffsetAlongLine->blockSignals( false );
2050  whileBlocking( mSpinHashLength )->setValue( mLayer->hashLength() );
2051  whileBlocking( mHashRotationSpinBox )->setValue( mLayer->hashAngle() );
2052  chkRotateMarker->blockSignals( true );
2053  chkRotateMarker->setChecked( mLayer->rotateSymbols() );
2054  chkRotateMarker->blockSignals( false );
2055  spinOffset->blockSignals( true );
2056  spinOffset->setValue( mLayer->offset() );
2057  spinOffset->blockSignals( false );
2059  radInterval->setChecked( true );
2060  else if ( mLayer->placement() == QgsTemplatedLineSymbolLayerBase::Vertex )
2061  radVertex->setChecked( true );
2063  radVertexLast->setChecked( true );
2065  radCentralPoint->setChecked( true );
2067  radCurvePoint->setChecked( true );
2069  radSegmentCentralPoint->setChecked( true );
2070  else
2071  radVertexFirst->setChecked( true );
2072 
2073  // set units
2074  mIntervalUnitWidget->blockSignals( true );
2075  mIntervalUnitWidget->setUnit( mLayer->intervalUnit() );
2076  mIntervalUnitWidget->setMapUnitScale( mLayer->intervalMapUnitScale() );
2077  mIntervalUnitWidget->blockSignals( false );
2078  mOffsetUnitWidget->blockSignals( true );
2079  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
2080  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
2081  mOffsetUnitWidget->blockSignals( false );
2082  mOffsetAlongLineUnitWidget->blockSignals( true );
2083  mOffsetAlongLineUnitWidget->setUnit( mLayer->offsetAlongLineUnit() );
2084  mOffsetAlongLineUnitWidget->setMapUnitScale( mLayer->offsetAlongLineMapUnitScale() );
2085  mOffsetAlongLineUnitWidget->blockSignals( false );
2086  whileBlocking( mAverageAngleUnit )->setUnit( mLayer->averageAngleUnit() );
2087  whileBlocking( mAverageAngleUnit )->setMapUnitScale( mLayer->averageAngleMapUnitScale() );
2088  whileBlocking( mSpinAverageAngleLength )->setValue( mLayer->averageAngleLength() );
2089  whileBlocking( mHashLengthUnitWidget )->setUnit( mLayer->hashLengthUnit() );
2090  whileBlocking( mHashLengthUnitWidget )->setMapUnitScale( mLayer->hashLengthMapUnitScale() );
2091 
2092  whileBlocking( mRingFilterComboBox )->setCurrentIndex( mRingFilterComboBox->findData( mLayer->ringFilter() ) );
2093 
2094  setPlacement(); // update gui
2095 
2103 }
2104 
2106 {
2107  return mLayer;
2108 }
2109 
2110 void QgsHashedLineSymbolLayerWidget::setInterval( double val )
2111 {
2112  mLayer->setInterval( val );
2113  emit changed();
2114 }
2115 
2116 void QgsHashedLineSymbolLayerWidget::setOffsetAlongLine( double val )
2117 {
2118  mLayer->setOffsetAlongLine( val );
2119  emit changed();
2120 }
2121 
2122 void QgsHashedLineSymbolLayerWidget::setHashLength( double val )
2123 {
2124  mLayer->setHashLength( val );
2125  emit changed();
2126 }
2127 
2128 void QgsHashedLineSymbolLayerWidget::setHashAngle( double val )
2129 {
2130  mLayer->setHashAngle( val );
2131  emit changed();
2132 }
2133 
2134 void QgsHashedLineSymbolLayerWidget::setRotate()
2135 {
2136  mSpinAverageAngleLength->setEnabled( chkRotateMarker->isChecked() && ( radInterval->isChecked() || radCentralPoint->isChecked() ) );
2137  mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
2138 
2139  mLayer->setRotateSymbols( chkRotateMarker->isChecked() );
2140  emit changed();
2141 }
2142 
2143 void QgsHashedLineSymbolLayerWidget::setOffset()
2144 {
2145  mLayer->setOffset( spinOffset->value() );
2146  emit changed();
2147 }
2148 
2149 void QgsHashedLineSymbolLayerWidget::setPlacement()
2150 {
2151  bool interval = radInterval->isChecked();
2152  spinInterval->setEnabled( interval );
2153  mSpinOffsetAlongLine->setEnabled( radInterval->isChecked() || radVertexLast->isChecked() || radVertexFirst->isChecked() );
2154  mOffsetAlongLineUnitWidget->setEnabled( mSpinOffsetAlongLine->isEnabled() );
2155  mSpinAverageAngleLength->setEnabled( chkRotateMarker->isChecked() && ( radInterval->isChecked() || radCentralPoint->isChecked() ) );
2156  mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
2157  //mLayer->setPlacement( interval ? QgsMarkerLineSymbolLayer::Interval : QgsMarkerLineSymbolLayer::Vertex );
2158  if ( radInterval->isChecked() )
2160  else if ( radVertex->isChecked() )
2162  else if ( radVertexLast->isChecked() )
2164  else if ( radVertexFirst->isChecked() )
2166  else if ( radCurvePoint->isChecked() )
2168  else if ( radSegmentCentralPoint->isChecked() )
2170  else
2172 
2173  emit changed();
2174 }
2175 
2176 void QgsHashedLineSymbolLayerWidget::mIntervalUnitWidget_changed()
2177 {
2178  if ( mLayer )
2179  {
2180  mLayer->setIntervalUnit( mIntervalUnitWidget->unit() );
2181  mLayer->setIntervalMapUnitScale( mIntervalUnitWidget->getMapUnitScale() );
2182  emit changed();
2183  }
2184 }
2185 
2186 void QgsHashedLineSymbolLayerWidget::mOffsetUnitWidget_changed()
2187 {
2188  if ( mLayer )
2189  {
2190  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
2191  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
2192  emit changed();
2193  }
2194 }
2195 
2196 void QgsHashedLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed()
2197 {
2198  if ( mLayer )
2199  {
2200  mLayer->setOffsetAlongLineUnit( mOffsetAlongLineUnitWidget->unit() );
2201  mLayer->setOffsetAlongLineMapUnitScale( mOffsetAlongLineUnitWidget->getMapUnitScale() );
2202  }
2203  emit changed();
2204 }
2205 
2206 void QgsHashedLineSymbolLayerWidget::hashLengthUnitWidgetChanged()
2207 {
2208  if ( mLayer )
2209  {
2210  mLayer->setHashLengthUnit( mHashLengthUnitWidget->unit() );
2211  mLayer->setHashLengthMapUnitScale( mHashLengthUnitWidget->getMapUnitScale() );
2212  }
2213  emit changed();
2214 }
2215 
2216 void QgsHashedLineSymbolLayerWidget::averageAngleUnitChanged()
2217 {
2218  if ( mLayer )
2219  {
2220  mLayer->setAverageAngleUnit( mAverageAngleUnit->unit() );
2221  mLayer->setAverageAngleMapUnitScale( mAverageAngleUnit->getMapUnitScale() );
2222  }
2223  emit changed();
2224 }
2225 
2226 void QgsHashedLineSymbolLayerWidget::setAverageAngle( double val )
2227 {
2228  if ( mLayer )
2229  {
2230  mLayer->setAverageAngleLength( val );
2231  emit changed();
2232  }
2233 }
2234 
2236 
2237 
2239  : QgsSymbolLayerWidget( parent, vl )
2240 {
2241  mLayer = nullptr;
2242 
2243  setupUi( this );
2244 
2245  mSvgSourceLineEdit->setLastPathSettingsKey( QStringLiteral( "/UI/lastSVGMarkerDir" ) );
2246 
2247  connect( mSvgSourceLineEdit, &QgsSvgSourceLineEdit::sourceChanged, this, &QgsSvgMarkerSymbolLayerWidget::svgSourceChanged );
2248  connect( mChangeColorButton, &QgsColorButton::colorChanged, this, &QgsSvgMarkerSymbolLayerWidget::mChangeColorButton_colorChanged );
2249  connect( mChangeStrokeColorButton, &QgsColorButton::colorChanged, this, &QgsSvgMarkerSymbolLayerWidget::mChangeStrokeColorButton_colorChanged );
2250  connect( mStrokeWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
2251  connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
2252  connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
2253  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
2254  connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSvgMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
2255  connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSvgMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
2262  viewGroups->setHeaderHidden( true );
2263  mChangeColorButton->setAllowOpacity( true );
2264  mChangeColorButton->setColorDialogTitle( tr( "Select Fill color" ) );
2265  mChangeColorButton->setContext( QStringLiteral( "symbology" ) );
2266  mChangeStrokeColorButton->setAllowOpacity( true );
2267  mChangeStrokeColorButton->setColorDialogTitle( tr( "Select Stroke Color" ) );
2268  mChangeStrokeColorButton->setContext( QStringLiteral( "symbology" ) );
2269 
2270  mFillColorDDBtn->registerLinkedWidget( mChangeColorButton );
2271  mStrokeColorDDBtn->registerLinkedWidget( mChangeStrokeColorButton );
2272 
2273  spinOffsetX->setClearValue( 0.0 );
2274  spinOffsetY->setClearValue( 0.0 );
2275  spinAngle->setClearValue( 0.0 );
2276 
2277 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
2278  mIconSize = std::max( 30, static_cast< int >( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().width( 'X' ) * 4 ) ) );
2279 #else
2280  mIconSize = std::max( 30, static_cast< int >( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 4 ) ) );
2281 #endif
2282  viewImages->setGridSize( QSize( mIconSize * 1.2, mIconSize * 1.2 ) );
2283 
2284  populateList();
2285 
2286  connect( viewImages->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsSvgMarkerSymbolLayerWidget::setName );
2287  connect( viewGroups->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsSvgMarkerSymbolLayerWidget::populateIcons );
2288  connect( spinWidth, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setWidth );
2289  connect( spinHeight, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setHeight );
2290  connect( mLockAspectRatio, static_cast < void ( QgsRatioLockButton::* )( bool ) > ( &QgsRatioLockButton::lockChanged ), this, &QgsSvgMarkerSymbolLayerWidget::lockAspectRatioChanged );
2291  connect( spinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setAngle );
2292  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setOffset );
2293  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setOffset );
2294  connect( this, &QgsSymbolLayerWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::updateAssistantSymbol );
2295 
2296 
2297  //make a temporary symbol for the size assistant preview
2298  mAssistantPreviewSymbol.reset( new QgsMarkerSymbol() );
2299 
2300  if ( vectorLayer() )
2301  {
2302  mWidthDDBtn->setSymbol( mAssistantPreviewSymbol );
2303  mHeightDDBtn->setSymbol( mAssistantPreviewSymbol );
2304  }
2305 }
2306 
2307 #include <QTime>
2308 #include <QAbstractListModel>
2309 #include <QPixmapCache>
2310 #include <QStyle>
2311 
2312 
2314 {
2315  QAbstractItemModel *oldModel = viewGroups->model();
2317  viewGroups->setModel( g );
2318  delete oldModel;
2319 
2320  // Set the tree expanded at the first level
2321  int rows = g->rowCount( g->indexFromItem( g->invisibleRootItem() ) );
2322  for ( int i = 0; i < rows; i++ )
2323  {
2324  viewGroups->setExpanded( g->indexFromItem( g->item( i ) ), true );
2325  }
2326 
2327  // Initially load the icons in the List view without any grouping
2328  oldModel = viewImages->model();
2329  QgsSvgSelectorListModel *m = new QgsSvgSelectorListModel( viewImages, mIconSize );
2330  viewImages->setModel( m );
2331  delete oldModel;
2332 }
2333 
2334 void QgsSvgMarkerSymbolLayerWidget::populateIcons( const QModelIndex &idx )
2335 {
2336  QString path = idx.data( Qt::UserRole + 1 ).toString();
2337 
2338  QAbstractItemModel *oldModel = viewImages->model();
2339  QgsSvgSelectorListModel *m = new QgsSvgSelectorListModel( viewImages, path );
2340  viewImages->setModel( m );
2341  delete oldModel;
2342 
2343  connect( viewImages->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsSvgMarkerSymbolLayerWidget::setName );
2344 }
2345 
2347 {
2348  if ( !layer )
2349  {
2350  return;
2351  }
2352 
2353  //activate gui for svg parameters only if supported by the svg file
2354  bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2355  QColor defaultFill, defaultStroke;
2356  double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2357  bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
2358  QgsApplication::svgCache()->containsParams( layer->path(), hasFillParam, hasDefaultFillColor, defaultFill,
2359  hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity,
2360  hasStrokeParam, hasDefaultStrokeColor, defaultStroke,
2361  hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth,
2362  hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
2363  mChangeColorButton->setEnabled( hasFillParam );
2364  mChangeColorButton->setAllowOpacity( hasFillOpacityParam );
2365  mChangeStrokeColorButton->setEnabled( hasStrokeParam );
2366  mChangeStrokeColorButton->setAllowOpacity( hasStrokeOpacityParam );
2367  mStrokeWidthSpinBox->setEnabled( hasStrokeWidthParam );
2368 
2369  if ( hasFillParam )
2370  {
2371  QColor fill = layer->fillColor();
2372  double existingOpacity = hasFillOpacityParam ? fill.alphaF() : 1.0;
2373  if ( hasDefaultFillColor )
2374  {
2375  fill = defaultFill;
2376  }
2377  fill.setAlphaF( hasDefaultFillOpacity ? defaultFillOpacity : existingOpacity );
2378  mChangeColorButton->setColor( fill );
2379  }
2380  if ( hasStrokeParam )
2381  {
2382  QColor stroke = layer->strokeColor();
2383  double existingOpacity = hasStrokeOpacityParam ? stroke.alphaF() : 1.0;
2384  if ( hasDefaultStrokeColor )
2385  {
2386  stroke = defaultStroke;
2387  }
2388  stroke.setAlphaF( hasDefaultStrokeOpacity ? defaultStrokeOpacity : existingOpacity );
2389  mChangeStrokeColorButton->setColor( stroke );
2390  }
2391 
2392  whileBlocking( mSvgSourceLineEdit )->setSource( layer->path() );
2393 
2394  mStrokeWidthSpinBox->blockSignals( true );
2395  mStrokeWidthSpinBox->setValue( hasDefaultStrokeWidth ? defaultStrokeWidth : layer->strokeWidth() );
2396  mStrokeWidthSpinBox->blockSignals( false );
2397 
2398  bool preservedAspectRatio = layer->preservedAspectRatio();
2399  spinHeight->blockSignals( true );
2400  if ( preservedAspectRatio )
2401  {
2402  spinHeight->setValue( layer->size() );
2403  }
2404  else
2405  {
2406  spinHeight->setValue( layer->size() * layer->fixedAspectRatio() );
2407  }
2408  spinHeight->setEnabled( layer->defaultAspectRatio() > 0.0 );
2409  spinHeight->blockSignals( false );
2410  whileBlocking( mLockAspectRatio )->setLocked( preservedAspectRatio );
2411 }
2412 
2413 void QgsSvgMarkerSymbolLayerWidget::updateAssistantSymbol()
2414 {
2415  for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
2416  {
2417  mAssistantPreviewSymbol->deleteSymbolLayer( i );
2418  }
2419  mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
2421  if ( ddSize )
2422  mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
2423 }
2424 
2425 
2427 {
2428  if ( !layer )
2429  {
2430  return;
2431  }
2432 
2433  if ( layer->layerType() != QLatin1String( "SvgMarker" ) )
2434  return;
2435 
2436  // layer type is correct, we can do the cast
2437  mLayer = static_cast<QgsSvgMarkerSymbolLayer *>( layer );
2438 
2439  // set values
2440 
2441  QAbstractItemModel *m = viewImages->model();
2442  QItemSelectionModel *selModel = viewImages->selectionModel();
2443  for ( int i = 0; i < m->rowCount(); i++ )
2444  {
2445  QModelIndex idx( m->index( i, 0 ) );
2446  if ( m->data( idx ).toString() == mLayer->path() )
2447  {
2448  selModel->select( idx, QItemSelectionModel::SelectCurrent );
2449  selModel->setCurrentIndex( idx, QItemSelectionModel::SelectCurrent );
2450  setName( idx );
2451  break;
2452  }
2453  }
2454 
2455  spinWidth->blockSignals( true );
2456  spinWidth->setValue( mLayer->size() );
2457  spinWidth->blockSignals( false );
2458  spinAngle->blockSignals( true );
2459  spinAngle->setValue( mLayer->angle() );
2460  spinAngle->blockSignals( false );
2461 
2462  // without blocking signals the value gets changed because of slot setOffset()
2463  spinOffsetX->blockSignals( true );
2464  spinOffsetX->setValue( mLayer->offset().x() );
2465  spinOffsetX->blockSignals( false );
2466  spinOffsetY->blockSignals( true );
2467  spinOffsetY->setValue( mLayer->offset().y() );
2468  spinOffsetY->blockSignals( false );
2469 
2470  mSizeUnitWidget->blockSignals( true );
2471  mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
2472  mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
2473  mSizeUnitWidget->blockSignals( false );
2474  mStrokeWidthUnitWidget->blockSignals( true );
2475  mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
2476  mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
2477  mStrokeWidthUnitWidget->blockSignals( false );
2478  mOffsetUnitWidget->blockSignals( true );
2479  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
2480  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
2481  mOffsetUnitWidget->blockSignals( false );
2482 
2483  //anchor points
2484  mHorizontalAnchorComboBox->blockSignals( true );
2485  mVerticalAnchorComboBox->blockSignals( true );
2486  mHorizontalAnchorComboBox->setCurrentIndex( mLayer->horizontalAnchorPoint() );
2487  mVerticalAnchorComboBox->setCurrentIndex( mLayer->verticalAnchorPoint() );
2488  mHorizontalAnchorComboBox->blockSignals( false );
2489  mVerticalAnchorComboBox->blockSignals( false );
2490 
2491  setGuiForSvg( mLayer );
2492 
2503 
2504  updateAssistantSymbol();
2505 }
2506 
2508 {
2509  return mLayer;
2510 }
2511 
2513 {
2515  mSvgSourceLineEdit->setMessageBar( context.messageBar() );
2516 }
2517 
2518 void QgsSvgMarkerSymbolLayerWidget::setName( const QModelIndex &idx )
2519 {
2520  QString name = idx.data( Qt::UserRole ).toString();
2521  mLayer->setPath( name );
2522  whileBlocking( mSvgSourceLineEdit )->setSource( name );
2523 
2524  setGuiForSvg( mLayer );
2525  emit changed();
2526 }
2527 
2528 void QgsSvgMarkerSymbolLayerWidget::setWidth()
2529 {
2530  double defaultAspectRatio = mLayer->defaultAspectRatio();
2531  double fixedAspectRatio = 0.0;
2532  spinHeight->blockSignals( true );
2533  if ( defaultAspectRatio <= 0.0 )
2534  {
2535  spinHeight->setValue( spinWidth->value() );
2536  }
2537  else if ( mLockAspectRatio->locked() )
2538  {
2539  spinHeight->setValue( spinWidth->value() * defaultAspectRatio );
2540  }
2541  else
2542  {
2543  fixedAspectRatio = spinHeight->value() / spinWidth->value();
2544  }
2545  spinHeight->blockSignals( false );
2546  mLayer->setSize( spinWidth->value() );
2547  mLayer->setFixedAspectRatio( fixedAspectRatio );
2548  emit changed();
2549 }
2550 
2551 void QgsSvgMarkerSymbolLayerWidget::setHeight()
2552 {
2553  double defaultAspectRatio = mLayer->defaultAspectRatio();
2554  double fixedAspectRatio = 0.0;
2555  spinWidth->blockSignals( true );
2556  if ( defaultAspectRatio <= 0.0 )
2557  {
2558  spinWidth->setValue( spinHeight->value() );
2559  }
2560  else if ( mLockAspectRatio->locked() )
2561  {
2562  spinWidth->setValue( spinHeight->value() / defaultAspectRatio );
2563  }
2564  else
2565  {
2566  fixedAspectRatio = spinHeight->value() / spinWidth->value();
2567  }
2568  spinWidth->blockSignals( false );
2569  mLayer->setSize( spinWidth->value() );
2570  mLayer->setFixedAspectRatio( fixedAspectRatio );
2571  emit changed();
2572 }
2573 
2574 void QgsSvgMarkerSymbolLayerWidget::lockAspectRatioChanged( const bool locked )
2575 {
2576  //spinHeight->setEnabled( !locked );
2577  double defaultAspectRatio = mLayer->defaultAspectRatio();
2578  if ( defaultAspectRatio <= 0.0 )
2579  {
2580  whileBlocking( mLockAspectRatio )->setLocked( true );
2581  }
2582  else if ( locked )
2583  {
2584  mLayer->setFixedAspectRatio( 0.0 );
2585  setWidth();
2586  }
2587  else
2588  {
2589  mLayer->setFixedAspectRatio( spinHeight->value() / spinWidth->value() );
2590  }
2591  //emit changed();
2592 }
2593 
2594 void QgsSvgMarkerSymbolLayerWidget::setAngle()
2595 {
2596  mLayer->setAngle( spinAngle->value() );
2597  emit changed();
2598 }
2599 
2600 void QgsSvgMarkerSymbolLayerWidget::setOffset()
2601 {
2602  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
2603  emit changed();
2604 }
2605 
2606 void QgsSvgMarkerSymbolLayerWidget::svgSourceChanged( const QString &text )
2607 {
2608  mLayer->setPath( text );
2609  setGuiForSvg( mLayer );
2610  emit changed();
2611 }
2612 
2613 void QgsSvgMarkerSymbolLayerWidget::mChangeColorButton_colorChanged( const QColor &color )
2614 {
2615  if ( !mLayer )
2616  {
2617  return;
2618  }
2619 
2620  mLayer->setFillColor( color );
2621  emit changed();
2622 }
2623 
2624 void QgsSvgMarkerSymbolLayerWidget::mChangeStrokeColorButton_colorChanged( const QColor &color )
2625 {
2626  if ( !mLayer )
2627  {
2628  return;
2629  }
2630 
2631  mLayer->setStrokeColor( color );
2632  emit changed();
2633 }
2634 
2635 void QgsSvgMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
2636 {
2637  if ( mLayer )
2638  {
2639  mLayer->setStrokeWidth( d );
2640  emit changed();
2641  }
2642 }
2643 
2644 void QgsSvgMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
2645 {
2646  if ( mLayer )
2647  {
2648  mLayer->setSizeUnit( mSizeUnitWidget->unit() );
2649  mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
2650  emit changed();
2651  }
2652 }
2653 
2654 void QgsSvgMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
2655 {
2656  if ( mLayer )
2657  {
2658  mLayer->setStrokeWidthUnit( mStrokeWidthUnitWidget->unit() );
2659  mLayer->setStrokeWidthMapUnitScale( mStrokeWidthUnitWidget->getMapUnitScale() );
2660  emit changed();
2661  }
2662 }
2663 
2664 void QgsSvgMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
2665 {
2666  if ( mLayer )
2667  {
2668  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
2669  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
2670  emit changed();
2671  }
2672 }
2673 
2674 void QgsSvgMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
2675 {
2676  if ( mLayer )
2677  {
2679  emit changed();
2680  }
2681 }
2682 
2683 void QgsSvgMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
2684 {
2685  if ( mLayer )
2686  {
2688  emit changed();
2689  }
2690 }
2691 
2693 
2695 {
2696  mLayer = nullptr;
2697  setupUi( this );
2698  connect( mTextureWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mTextureWidthSpinBox_valueChanged );
2699  connect( mSvgSourceLineEdit, &QgsSvgSourceLineEdit::sourceChanged, this, &QgsSVGFillSymbolLayerWidget::svgSourceChanged );
2700  connect( mRotationSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mRotationSpinBox_valueChanged );
2701  connect( mChangeColorButton, &QgsColorButton::colorChanged, this, &QgsSVGFillSymbolLayerWidget::mChangeColorButton_colorChanged );
2702  connect( mChangeStrokeColorButton, &QgsColorButton::colorChanged, this, &QgsSVGFillSymbolLayerWidget::mChangeStrokeColorButton_colorChanged );
2703  connect( mStrokeWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
2704  connect( mTextureWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSVGFillSymbolLayerWidget::mTextureWidthUnitWidget_changed );
2705  connect( mSvgStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSVGFillSymbolLayerWidget::mSvgStrokeWidthUnitWidget_changed );
2710  mSvgTreeView->setHeaderHidden( true );
2711  insertIcons();
2712 
2713  mRotationSpinBox->setClearValue( 0.0 );
2714 
2715  mChangeColorButton->setColorDialogTitle( tr( "Select Fill Color" ) );
2716  mChangeColorButton->setContext( QStringLiteral( "symbology" ) );
2717  mChangeStrokeColorButton->setColorDialogTitle( tr( "Select Stroke Color" ) );
2718  mChangeStrokeColorButton->setContext( QStringLiteral( "symbology" ) );
2719 
2720  mFilColorDDBtn->registerLinkedWidget( mChangeColorButton );
2721  mStrokeColorDDBtn->registerLinkedWidget( mChangeStrokeColorButton );
2722 
2723  connect( mSvgListView->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsSVGFillSymbolLayerWidget::setFile );
2724  connect( mSvgTreeView->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsSVGFillSymbolLayerWidget::populateIcons );
2725 }
2726 
2728 {
2729  if ( !layer )
2730  {
2731  return;
2732  }
2733 
2734  if ( layer->layerType() != QLatin1String( "SVGFill" ) )
2735  {
2736  return;
2737  }
2738 
2739  mLayer = dynamic_cast<QgsSVGFillSymbolLayer *>( layer );
2740  if ( mLayer )
2741  {
2742  double width = mLayer->patternWidth();
2743  mTextureWidthSpinBox->blockSignals( true );
2744  mTextureWidthSpinBox->setValue( width );
2745  mTextureWidthSpinBox->blockSignals( false );
2746  whileBlocking( mSvgSourceLineEdit )->setSource( mLayer->svgFilePath() );
2747  mRotationSpinBox->blockSignals( true );
2748  mRotationSpinBox->setValue( mLayer->angle() );
2749  mRotationSpinBox->blockSignals( false );
2750  mTextureWidthUnitWidget->blockSignals( true );
2751  mTextureWidthUnitWidget->setUnit( mLayer->patternWidthUnit() );
2752  mTextureWidthUnitWidget->setMapUnitScale( mLayer->patternWidthMapUnitScale() );
2753  mTextureWidthUnitWidget->blockSignals( false );
2754  mSvgStrokeWidthUnitWidget->blockSignals( true );
2755  mSvgStrokeWidthUnitWidget->setUnit( mLayer->svgStrokeWidthUnit() );
2756  mSvgStrokeWidthUnitWidget->setMapUnitScale( mLayer->svgStrokeWidthMapUnitScale() );
2757  mSvgStrokeWidthUnitWidget->blockSignals( false );
2758  mChangeColorButton->blockSignals( true );
2759  mChangeColorButton->setColor( mLayer->svgFillColor() );
2760  mChangeColorButton->blockSignals( false );
2761  mChangeStrokeColorButton->blockSignals( true );
2762  mChangeStrokeColorButton->setColor( mLayer->svgStrokeColor() );
2763  mChangeStrokeColorButton->blockSignals( false );
2764  mStrokeWidthSpinBox->blockSignals( true );
2765  mStrokeWidthSpinBox->setValue( mLayer->svgStrokeWidth() );
2766  mStrokeWidthSpinBox->blockSignals( false );
2767  }
2768  updateParamGui( false );
2769 
2776 }
2777 
2779 {
2780  return mLayer;
2781 }
2782 
2784 {
2786  mSvgSourceLineEdit->setMessageBar( context.messageBar() );
2787 }
2788 
2789 void QgsSVGFillSymbolLayerWidget::mTextureWidthSpinBox_valueChanged( double d )
2790 {
2791  if ( mLayer )
2792  {
2793  mLayer->setPatternWidth( d );
2794  emit changed();
2795  }
2796 }
2797 
2798 void QgsSVGFillSymbolLayerWidget::svgSourceChanged( const QString &text )
2799 {
2800  if ( !mLayer )
2801  {
2802  return;
2803  }
2804 
2805  mLayer->setSvgFilePath( text );
2806  updateParamGui();
2807  emit changed();
2808 }
2809 
2810 void QgsSVGFillSymbolLayerWidget::setFile( const QModelIndex &item )
2811 {
2812  QString file = item.data( Qt::UserRole ).toString();
2813  mLayer->setSvgFilePath( file );
2814  whileBlocking( mSvgSourceLineEdit )->setSource( file );
2815 
2816  updateParamGui();
2817  emit changed();
2818 }
2819 
2821 {
2822  QAbstractItemModel *oldModel = mSvgTreeView->model();
2823  QgsSvgSelectorGroupsModel *g = new QgsSvgSelectorGroupsModel( mSvgTreeView );
2824  mSvgTreeView->setModel( g );
2825  delete oldModel;
2826 
2827  // Set the tree expanded at the first level
2828  int rows = g->rowCount( g->indexFromItem( g->invisibleRootItem() ) );
2829  for ( int i = 0; i < rows; i++ )
2830  {
2831  mSvgTreeView->setExpanded( g->indexFromItem( g->item( i ) ), true );
2832  }
2833 
2834  oldModel = mSvgListView->model();
2835  QgsSvgSelectorListModel *m = new QgsSvgSelectorListModel( mSvgListView );
2836  mSvgListView->setModel( m );
2837  delete oldModel;
2838 }
2839 
2840 void QgsSVGFillSymbolLayerWidget::populateIcons( const QModelIndex &idx )
2841 {
2842  QString path = idx.data( Qt::UserRole + 1 ).toString();
2843 
2844  QAbstractItemModel *oldModel = mSvgListView->model();
2845  QgsSvgSelectorListModel *m = new QgsSvgSelectorListModel( mSvgListView, path );
2846  mSvgListView->setModel( m );
2847  delete oldModel;
2848 
2849  connect( mSvgListView->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsSVGFillSymbolLayerWidget::setFile );
2850 }
2851 
2852 
2853 void QgsSVGFillSymbolLayerWidget::mRotationSpinBox_valueChanged( double d )
2854 {
2855  if ( mLayer )
2856  {
2857  mLayer->setAngle( d );
2858  emit changed();
2859  }
2860 }
2861 
2863 {
2864  //activate gui for svg parameters only if supported by the svg file
2865  bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2866  QColor defaultFill, defaultStroke;
2867  double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2868  bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
2869  QgsApplication::svgCache()->containsParams( mSvgSourceLineEdit->source(), hasFillParam, hasDefaultFillColor, defaultFill,
2870  hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity,
2871  hasStrokeParam, hasDefaultStrokeColor, defaultStroke,
2872  hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth,
2873  hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
2874  if ( resetValues )
2875  {
2876  QColor fill = mChangeColorButton->color();
2877  double newOpacity = hasFillOpacityParam ? fill.alphaF() : 1.0;
2878  if ( hasDefaultFillColor )
2879  {
2880  fill = defaultFill;
2881  }
2882  fill.setAlphaF( hasDefaultFillOpacity ? defaultFillOpacity : newOpacity );
2883  mChangeColorButton->setColor( fill );
2884  }
2885  mChangeColorButton->setEnabled( hasFillParam );
2886  mChangeColorButton->setAllowOpacity( hasFillOpacityParam );
2887  if ( resetValues )
2888  {
2889  QColor stroke = mChangeStrokeColorButton->color();
2890  double newOpacity = hasStrokeOpacityParam ? stroke.alphaF() : 1.0;
2891  if ( hasDefaultStrokeColor )
2892  {
2893  stroke = defaultStroke;
2894  }
2895  stroke.setAlphaF( hasDefaultStrokeOpacity ? defaultStrokeOpacity : newOpacity );
2896  mChangeStrokeColorButton->setColor( stroke );
2897  }
2898  mChangeStrokeColorButton->setEnabled( hasStrokeParam );
2899  mChangeStrokeColorButton->setAllowOpacity( hasStrokeOpacityParam );
2900  if ( hasDefaultStrokeWidth && resetValues )
2901  {
2902  mStrokeWidthSpinBox->setValue( defaultStrokeWidth );
2903  }
2904  mStrokeWidthSpinBox->setEnabled( hasStrokeWidthParam );
2905 }
2906 
2907 void QgsSVGFillSymbolLayerWidget::mChangeColorButton_colorChanged( const QColor &color )
2908 {
2909  if ( !mLayer )
2910  {
2911  return;
2912  }
2913 
2914  mLayer->setSvgFillColor( color );
2915  emit changed();
2916 }
2917 
2918 void QgsSVGFillSymbolLayerWidget::mChangeStrokeColorButton_colorChanged( const QColor &color )
2919 {
2920  if ( !mLayer )
2921  {
2922  return;
2923  }
2924 
2925  mLayer->setSvgStrokeColor( color );
2926  emit changed();
2927 }
2928 
2929 void QgsSVGFillSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
2930 {
2931  if ( mLayer )
2932  {
2933  mLayer->setSvgStrokeWidth( d );
2934  emit changed();
2935  }
2936 }
2937 
2938 void QgsSVGFillSymbolLayerWidget::mTextureWidthUnitWidget_changed()
2939 {
2940  if ( mLayer )
2941  {
2942  mLayer->setPatternWidthUnit( mTextureWidthUnitWidget->unit() );
2943  mLayer->setPatternWidthMapUnitScale( mTextureWidthUnitWidget->getMapUnitScale() );
2944  emit changed();
2945  }
2946 }
2947 
2948 void QgsSVGFillSymbolLayerWidget::mSvgStrokeWidthUnitWidget_changed()
2949 {
2950  if ( mLayer )
2951  {
2952  mLayer->setSvgStrokeWidthUnit( mSvgStrokeWidthUnitWidget->unit() );
2953  mLayer->setSvgStrokeWidthMapUnitScale( mSvgStrokeWidthUnitWidget->getMapUnitScale() );
2954  emit changed();
2955  }
2956 }
2957 
2959 
2961  QgsSymbolLayerWidget( parent, vl )
2962 {
2963  setupUi( this );
2964  connect( mAngleSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLinePatternFillSymbolLayerWidget::mAngleSpinBox_valueChanged );
2965  connect( mDistanceSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLinePatternFillSymbolLayerWidget::mDistanceSpinBox_valueChanged );
2966  connect( mOffsetSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLinePatternFillSymbolLayerWidget::mOffsetSpinBox_valueChanged );
2967  connect( mDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsLinePatternFillSymbolLayerWidget::mDistanceUnitWidget_changed );
2968  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsLinePatternFillSymbolLayerWidget::mOffsetUnitWidget_changed );
2973  mOffsetSpinBox->setClearValue( 0 );
2974  mAngleSpinBox->setClearValue( 0 );
2975 }
2976 
2978 {
2979  if ( layer->layerType() != QLatin1String( "LinePatternFill" ) )
2980  {
2981  return;
2982  }
2983 
2984  QgsLinePatternFillSymbolLayer *patternLayer = static_cast<QgsLinePatternFillSymbolLayer *>( layer );
2985  if ( patternLayer )
2986  {
2987  mLayer = patternLayer;
2988  mAngleSpinBox->blockSignals( true );
2989  mAngleSpinBox->setValue( mLayer->lineAngle() );
2990  mAngleSpinBox->blockSignals( false );
2991  mDistanceSpinBox->blockSignals( true );
2992  mDistanceSpinBox->setValue( mLayer->distance() );
2993  mDistanceSpinBox->blockSignals( false );
2994  mOffsetSpinBox->blockSignals( true );
2995  mOffsetSpinBox->setValue( mLayer->offset() );
2996  mOffsetSpinBox->blockSignals( false );
2997 
2998  //units
2999  mDistanceUnitWidget->blockSignals( true );
3000  mDistanceUnitWidget->setUnit( mLayer->distanceUnit() );
3001  mDistanceUnitWidget->setMapUnitScale( mLayer->distanceMapUnitScale() );
3002  mDistanceUnitWidget->blockSignals( false );
3003  mOffsetUnitWidget->blockSignals( true );
3004  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
3005  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
3006  mOffsetUnitWidget->blockSignals( false );
3007  }
3008 
3011 }
3012 
3014 {
3015  return mLayer;
3016 }
3017 
3018 void QgsLinePatternFillSymbolLayerWidget::mAngleSpinBox_valueChanged( double d )
3019 {
3020  if ( mLayer )
3021  {
3022  mLayer->setLineAngle( d );
3023  emit changed();
3024  }
3025 }
3026 
3027 void QgsLinePatternFillSymbolLayerWidget::mDistanceSpinBox_valueChanged( double d )
3028 {
3029  if ( mLayer )
3030  {
3031  mLayer->setDistance( d );
3032  emit changed();
3033  }
3034 }
3035 
3036 void QgsLinePatternFillSymbolLayerWidget::mOffsetSpinBox_valueChanged( double d )
3037 {
3038  if ( mLayer )
3039  {
3040  mLayer->setOffset( d );
3041  emit changed();
3042  }
3043 }
3044 
3045 void QgsLinePatternFillSymbolLayerWidget::mDistanceUnitWidget_changed()
3046 {
3047  if ( mLayer )
3048  {
3049  mLayer->setDistanceUnit( mDistanceUnitWidget->unit() );
3050  mLayer->setDistanceMapUnitScale( mDistanceUnitWidget->getMapUnitScale() );
3051  emit changed();
3052  }
3053 }
3054 
3055 void QgsLinePatternFillSymbolLayerWidget::mOffsetUnitWidget_changed()
3056 {
3057  if ( mLayer )
3058  {
3059  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
3060  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
3061  emit changed();
3062  }
3063 }
3064 
3066 
3068  QgsSymbolLayerWidget( parent, vl )
3069 {
3070  setupUi( this );
3071  connect( mHorizontalDistanceSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceSpinBox_valueChanged );
3072  connect( mVerticalDistanceSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceSpinBox_valueChanged );
3073  connect( mHorizontalDisplacementSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementSpinBox_valueChanged );
3074  connect( mVerticalDisplacementSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementSpinBox_valueChanged );
3075  connect( mHorizontalOffsetSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetSpinBox_valueChanged );
3076  connect( mVerticalOffsetSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetSpinBox_valueChanged );
3077  connect( mHorizontalDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceUnitWidget_changed );
3078  connect( mVerticalDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceUnitWidget_changed );
3079  connect( mHorizontalDisplacementUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementUnitWidget_changed );
3080  connect( mVerticalDisplacementUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementUnitWidget_changed );
3081  connect( mHorizontalOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetUnitWidget_changed );
3082  connect( mVerticalOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetUnitWidget_changed );
3095 }
3096 
3097 
3099 {
3100  if ( !layer || layer->layerType() != QLatin1String( "PointPatternFill" ) )
3101  {
3102  return;
3103  }
3104 
3105  mLayer = static_cast<QgsPointPatternFillSymbolLayer *>( layer );
3106  whileBlocking( mHorizontalDistanceSpinBox )->setValue( mLayer->distanceX() );
3107  whileBlocking( mVerticalDistanceSpinBox )->setValue( mLayer->distanceY() );
3108  whileBlocking( mHorizontalDisplacementSpinBox )->setValue( mLayer->displacementX() );
3109  whileBlocking( mVerticalDisplacementSpinBox )->setValue( mLayer->displacementY() );
3110  whileBlocking( mHorizontalOffsetSpinBox )->setValue( mLayer->offsetX() );
3111  whileBlocking( mVerticalOffsetSpinBox )->setValue( mLayer->offsetY() );
3112 
3113  mHorizontalDistanceUnitWidget->blockSignals( true );
3114  mHorizontalDistanceUnitWidget->setUnit( mLayer->distanceXUnit() );
3115  mHorizontalDistanceUnitWidget->setMapUnitScale( mLayer->distanceXMapUnitScale() );
3116  mHorizontalDistanceUnitWidget->blockSignals( false );
3117  mVerticalDistanceUnitWidget->blockSignals( true );
3118  mVerticalDistanceUnitWidget->setUnit( mLayer->distanceYUnit() );
3119  mVerticalDistanceUnitWidget->setMapUnitScale( mLayer->distanceYMapUnitScale() );
3120  mVerticalDistanceUnitWidget->blockSignals( false );
3121  mHorizontalDisplacementUnitWidget->blockSignals( true );
3122  mHorizontalDisplacementUnitWidget->setUnit( mLayer->displacementXUnit() );
3123  mHorizontalDisplacementUnitWidget->setMapUnitScale( mLayer->displacementXMapUnitScale() );
3124  mHorizontalDisplacementUnitWidget->blockSignals( false );
3125  mVerticalDisplacementUnitWidget->blockSignals( true );
3126  mVerticalDisplacementUnitWidget->setUnit( mLayer->displacementYUnit() );
3127  mVerticalDisplacementUnitWidget->setMapUnitScale( mLayer->displacementYMapUnitScale() );
3128  mVerticalDisplacementUnitWidget->blockSignals( false );
3129  mHorizontalOffsetUnitWidget->blockSignals( true );
3130  mHorizontalOffsetUnitWidget->setUnit( mLayer->offsetXUnit() );
3131  mHorizontalOffsetUnitWidget->setMapUnitScale( mLayer->offsetXMapUnitScale() );
3132  mHorizontalOffsetUnitWidget->blockSignals( false );
3133  mVerticalOffsetUnitWidget->blockSignals( true );
3134  mVerticalOffsetUnitWidget->setUnit( mLayer->offsetYUnit() );
3135  mVerticalOffsetUnitWidget->setMapUnitScale( mLayer->offsetYMapUnitScale() );
3136  mVerticalOffsetUnitWidget->blockSignals( false );
3137 
3138  registerDataDefinedButton( mHorizontalDistanceDDBtn, QgsSymbolLayer::PropertyDistanceX );
3140  registerDataDefinedButton( mHorizontalDisplacementDDBtn, QgsSymbolLayer::PropertyDisplacementX );
3144 }
3145 
3147 {
3148  return mLayer;
3149 }
3150 
3151 void QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceSpinBox_valueChanged( double d )
3152 {
3153  if ( mLayer )
3154  {
3155  mLayer->setDistanceX( d );
3156  emit changed();
3157  }
3158 }
3159 
3160 void QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceSpinBox_valueChanged( double d )
3161 {
3162  if ( mLayer )
3163  {
3164  mLayer->setDistanceY( d );
3165  emit changed();
3166  }
3167 }
3168 
3169 void QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementSpinBox_valueChanged( double d )
3170 {
3171  if ( mLayer )
3172  {
3173  mLayer->setDisplacementX( d );
3174  emit changed();
3175  }
3176 }
3177 
3178 void QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementSpinBox_valueChanged( double d )
3179 {
3180  if ( mLayer )
3181  {
3182  mLayer->setDisplacementY( d );
3183  emit changed();
3184  }
3185 }
3186 
3187 void QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetSpinBox_valueChanged( double d )
3188 {
3189  if ( mLayer )
3190  {
3191  mLayer->setOffsetX( d );
3192  emit changed();
3193  }
3194 }
3195 
3196 void QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetSpinBox_valueChanged( double d )
3197 {
3198  if ( mLayer )
3199  {
3200  mLayer->setOffsetY( d );
3201  emit changed();
3202  }
3203 }
3204 
3205 void QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceUnitWidget_changed()
3206 {
3207  if ( mLayer )
3208  {
3209  mLayer->setDistanceXUnit( mHorizontalDistanceUnitWidget->unit() );
3210  mLayer->setDistanceXMapUnitScale( mHorizontalDistanceUnitWidget->getMapUnitScale() );
3211  emit changed();
3212  }
3213 }
3214 
3215 void QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceUnitWidget_changed()
3216 {
3217  if ( mLayer )
3218  {
3219  mLayer->setDistanceYUnit( mVerticalDistanceUnitWidget->unit() );
3220  mLayer->setDistanceYMapUnitScale( mVerticalDistanceUnitWidget->getMapUnitScale() );
3221  emit changed();
3222  }
3223 }
3224 
3225 void QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementUnitWidget_changed()
3226 {
3227  if ( mLayer )
3228  {
3229  mLayer->setDisplacementXUnit( mHorizontalDisplacementUnitWidget->unit() );
3230  mLayer->setDisplacementXMapUnitScale( mHorizontalDisplacementUnitWidget->getMapUnitScale() );
3231  emit changed();
3232  }
3233 }
3234 
3235 void QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementUnitWidget_changed()
3236 {
3237  if ( mLayer )
3238  {
3239  mLayer->setDisplacementYUnit( mVerticalDisplacementUnitWidget->unit() );
3240  mLayer->setDisplacementYMapUnitScale( mVerticalDisplacementUnitWidget->getMapUnitScale() );
3241  emit changed();
3242  }
3243 }
3244 
3245 void QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetUnitWidget_changed()
3246 {
3247  if ( mLayer )
3248  {
3249  mLayer->setOffsetXUnit( mHorizontalOffsetUnitWidget->unit() );
3250  mLayer->setOffsetXMapUnitScale( mHorizontalOffsetUnitWidget->getMapUnitScale() );
3251  emit changed();
3252  }
3253 }
3254 
3255 void QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetUnitWidget_changed()
3256 {
3257  if ( mLayer )
3258  {
3259  mLayer->setOffsetYUnit( mVerticalOffsetUnitWidget->unit() );
3260  mLayer->setOffsetYMapUnitScale( mVerticalOffsetUnitWidget->getMapUnitScale() );
3261  emit changed();
3262  }
3263 }
3264 
3266 
3268  : QgsSymbolLayerWidget( parent, vl )
3269 {
3270  mLayer = nullptr;
3271 
3272  setupUi( this );
3273  connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
3274  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
3275  connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
3276  connect( mStrokeWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
3277  connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
3278  connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
3285 
3286  widgetChar = new CharacterWidget();
3287  scrollArea->setWidget( widgetChar );
3288  scrollArea->setVerticalOnly( true );
3289 
3290  btnColor->setAllowOpacity( true );
3291  btnColor->setColorDialogTitle( tr( "Select Symbol Fill Color" ) );
3292  btnColor->setContext( QStringLiteral( "symbology" ) );
3293  btnStrokeColor->setAllowOpacity( true );
3294  btnStrokeColor->setColorDialogTitle( tr( "Select Symbol Stroke Color" ) );
3295  btnStrokeColor->setContext( QStringLiteral( "symbology" ) );
3296 
3297  mColorDDBtn->registerLinkedWidget( btnColor );
3298  mStrokeColorDDBtn->registerLinkedWidget( btnStrokeColor );
3299 
3300  spinOffsetX->setClearValue( 0.0 );
3301  spinOffsetY->setClearValue( 0.0 );
3302  spinAngle->setClearValue( 0.0 );
3303 
3304  //make a temporary symbol for the size assistant preview
3305  mAssistantPreviewSymbol.reset( new QgsMarkerSymbol() );
3306 
3307  if ( vectorLayer() )
3308  mSizeDDBtn->setSymbol( mAssistantPreviewSymbol );
3309 
3310  connect( cboFont, &QFontComboBox::currentFontChanged, this, &QgsFontMarkerSymbolLayerWidget::setFontFamily );
3311  connect( spinSize, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setSize );
3312  connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::penJoinStyleChanged );
3315  connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::penJoinStyleChanged );
3316  connect( spinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setAngle );
3317  connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setOffset );
3318  connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setOffset );
3320  connect( mCharLineEdit, &QLineEdit::textChanged, this, &QgsFontMarkerSymbolLayerWidget::setCharacterFromText );
3321 
3322  connect( this, &QgsSymbolLayerWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::updateAssistantSymbol );
3323 }
3324 
3326 {
3327  if ( layer->layerType() != QLatin1String( "FontMarker" ) )
3328  return;
3329 
3330  // layer type is correct, we can do the cast
3331  mLayer = static_cast<QgsFontMarkerSymbolLayer *>( layer );
3332 
3333  QFont layerFont( mLayer->fontFamily() );
3334  // set values
3335  whileBlocking( cboFont )->setCurrentFont( layerFont );
3336  whileBlocking( spinSize )->setValue( mLayer->size() );
3337  whileBlocking( btnColor )->setColor( mLayer->color() );
3338  whileBlocking( btnStrokeColor )->setColor( mLayer->strokeColor() );
3339  whileBlocking( mStrokeWidthSpinBox )->setValue( mLayer->strokeWidth() );
3340  whileBlocking( spinAngle )->setValue( mLayer->angle() );
3341 
3342  widgetChar->blockSignals( true );
3343  widgetChar->setFont( layerFont );
3344  if ( mLayer->character().length() == 1 )
3345  {
3346  widgetChar->setCharacter( mLayer->character().at( 0 ) );
3347  }
3348  widgetChar->blockSignals( false );
3349  whileBlocking( mCharLineEdit )->setText( mLayer->character() );
3350  mCharPreview->setFont( layerFont );
3351 
3352  //block
3353  whileBlocking( spinOffsetX )->setValue( mLayer->offset().x() );
3354  whileBlocking( spinOffsetY )->setValue( mLayer->offset().y() );
3355 
3356  mSizeUnitWidget->blockSignals( true );
3357  mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
3358  mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
3359  mSizeUnitWidget->blockSignals( false );
3360 
3361  mStrokeWidthUnitWidget->blockSignals( true );
3362  mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
3363  mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
3364  mStrokeWidthUnitWidget->blockSignals( false );
3365 
3366  mOffsetUnitWidget->blockSignals( true );
3367  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
3368  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
3369  mOffsetUnitWidget->blockSignals( false );
3370 
3371  whileBlocking( cboJoinStyle )->setPenJoinStyle( mLayer->penJoinStyle() );
3372 
3373  //anchor points
3374  whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mLayer->horizontalAnchorPoint() );
3375  whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mLayer->verticalAnchorPoint() );
3376 
3387 
3388  updateAssistantSymbol();
3389 }
3390 
3392 {
3393  return mLayer;
3394 }
3395 
3397 {
3398  mLayer->setFontFamily( font.family() );
3399  widgetChar->setFont( font );
3400  mCharPreview->setFont( font );
3401  emit changed();
3402 }
3403 
3404 void QgsFontMarkerSymbolLayerWidget::setColor( const QColor &color )
3405 {
3406  mLayer->setColor( color );
3407  emit changed();
3408 }
3409 
3411 {
3412  mLayer->setStrokeColor( color );
3413  emit changed();
3414 }
3415 
3417 {
3418  mLayer->setSize( size );
3419  //widgetChar->updateSize(size);
3420  emit changed();
3421 }
3422 
3424 {
3425  mLayer->setAngle( angle );
3426  emit changed();
3427 }
3428 
3430 {
3431  mCharPreview->setText( text );
3432 
3433  if ( text.isEmpty() )
3434  return;
3435 
3436  // take the last character of a string for a better experience when users cycle through several characters on their keyboard
3437  QString character = text;
3438  if ( text.contains( QRegularExpression( QStringLiteral( "^0x[0-9a-fA-F]{1,4}$" ) ) ) )
3439  {
3440  bool ok = false;
3441  unsigned int value = text.toUInt( &ok, 0 );
3442  if ( ok )
3443  {
3444  character = QChar( value );
3445  mCharPreview->setText( character );
3446  }
3447  }
3448 
3449  if ( character != mLayer->character() )
3450  {
3451  mLayer->setCharacter( character );
3452  if ( mLayer->character().length() == 1 )
3453  {
3454  whileBlocking( widgetChar )->setCharacter( mLayer->character().at( 0 ) );
3455  }
3456  else
3457  {
3459  }
3460  emit changed();
3461  }
3462 }
3463 
3465 {
3466  if ( mLayer->character().length() > 1 || QGuiApplication::keyboardModifiers() & Qt::ControlModifier )
3467  {
3468  mCharLineEdit->insert( chr );
3469  return;
3470  }
3471 
3472  mLayer->setCharacter( chr );
3473  whileBlocking( mCharLineEdit )->setText( chr );
3474  mCharPreview->setText( chr );
3475  emit changed();
3476 }
3477 
3478 void QgsFontMarkerSymbolLayerWidget::setOffset()
3479 {
3480  mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
3481  emit changed();
3482 }
3483 
3484 void QgsFontMarkerSymbolLayerWidget::penJoinStyleChanged()
3485 {
3486  mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
3487  emit changed();
3488 }
3489 
3490 void QgsFontMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
3491 {
3492  if ( mLayer )
3493  {
3494  mLayer->setSizeUnit( mSizeUnitWidget->unit() );
3495  mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
3496  emit changed();
3497  }
3498 }
3499 
3500 void QgsFontMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
3501 {
3502  if ( mLayer )
3503  {
3504  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
3505  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
3506  emit changed();
3507  }
3508 }
3509 
3510 void QgsFontMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
3511 {
3512  if ( mLayer )
3513  {
3514  mLayer->setStrokeWidthUnit( mSizeUnitWidget->unit() );
3515  mLayer->setStrokeWidthMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
3516  emit changed();
3517  }
3518 }
3519 
3520 void QgsFontMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
3521 {
3522  if ( mLayer )
3523  {
3525  emit changed();
3526  }
3527 }
3528 
3529 void QgsFontMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
3530 {
3531  if ( mLayer )
3532  {
3534  emit changed();
3535  }
3536 }
3537 
3538 void QgsFontMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
3539 {
3540  if ( mLayer )
3541  {
3542  mLayer->setStrokeWidth( d );
3543  emit changed();
3544  }
3545 }
3546 
3547 void QgsFontMarkerSymbolLayerWidget::updateAssistantSymbol()
3548 {
3549  for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
3550  {
3551  mAssistantPreviewSymbol->deleteSymbolLayer( i );
3552  }
3553  mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
3555  if ( ddSize )
3556  mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
3557 }
3558 
3560 
3561 
3563  : QgsSymbolLayerWidget( parent, vl )
3564 {
3565  mLayer = nullptr;
3566 
3567  setupUi( this );
3568  connect( mDrawInsideCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mDrawInsideCheckBox_stateChanged );
3569  connect( mDrawAllPartsCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mDrawAllPartsCheckBox_stateChanged );
3570 }
3571 
3573 {
3574  if ( layer->layerType() != QLatin1String( "CentroidFill" ) )
3575  return;
3576 
3577  // layer type is correct, we can do the cast
3578  mLayer = static_cast<QgsCentroidFillSymbolLayer *>( layer );
3579 
3580  // set values
3581  whileBlocking( mDrawInsideCheckBox )->setChecked( mLayer->pointOnSurface() );
3582  whileBlocking( mDrawAllPartsCheckBox )->setChecked( mLayer->pointOnAllParts() );
3583 }
3584 
3586 {
3587  return mLayer;
3588 }
3589 
3590 void QgsCentroidFillSymbolLayerWidget::mDrawInsideCheckBox_stateChanged( int state )
3591 {
3592  mLayer->setPointOnSurface( state == Qt::Checked );
3593  emit changed();
3594 }
3595 
3596 void QgsCentroidFillSymbolLayerWidget::mDrawAllPartsCheckBox_stateChanged( int state )
3597 {
3598  mLayer->setPointOnAllParts( state == Qt::Checked );
3599  emit changed();
3600 }
3601 
3603 
3605  : QgsSymbolLayerWidget( parent, vl )
3606 {
3607  mLayer = nullptr;
3608 
3609  setupUi( this );
3610 
3611  mImageSourceLineEdit->setLastPathSettingsKey( QStringLiteral( "/UI/lastRasterMarkerImageDir" ) );
3612 
3613  connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsRasterMarkerSymbolLayerWidget::imageSourceChanged );
3614  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
3615  connect( mRotationSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setAngle );
3616  connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
3617  connect( mWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setWidth );
3618  connect( mHeightSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setHeight );
3619  connect( mLockAspectRatio, static_cast < void ( QgsRatioLockButton::* )( bool ) > ( &QgsRatioLockButton::lockChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setLockAspectRatio );
3620 
3625 
3626  mSpinOffsetX->setClearValue( 0.0 );
3627  mSpinOffsetY->setClearValue( 0.0 );
3628  mRotationSpinBox->setClearValue( 0.0 );
3629 
3630  connect( mSpinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setOffset );
3631  connect( mSpinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setOffset );
3632  connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsRasterMarkerSymbolLayerWidget::setOpacity );
3633 
3634  connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
3635  connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
3636 }
3637 
3639 {
3640  if ( !layer )
3641  {
3642  return;
3643  }
3644 
3645  if ( layer->layerType() != QLatin1String( "RasterMarker" ) )
3646  return;
3647 
3648  // layer type is correct, we can do the cast
3649  mLayer = static_cast<QgsRasterMarkerSymbolLayer *>( layer );
3650 
3651  // set values
3652  whileBlocking( mImageSourceLineEdit )->setSource( mLayer->path() );
3653 
3654  whileBlocking( mWidthSpinBox )->setValue( mLayer->size() );
3655  bool preservedAspectRatio = mLayer->preservedAspectRatio();
3656  mHeightSpinBox->blockSignals( true );
3657  if ( preservedAspectRatio )
3658  {
3659  mHeightSpinBox->setValue( mLayer->size() );
3660  }
3661  else
3662  {
3663  mHeightSpinBox->setValue( mLayer->size() * mLayer->fixedAspectRatio() );
3664  }
3665  mHeightSpinBox->setEnabled( mLayer->defaultAspectRatio() > 0.0 );
3666  mHeightSpinBox->blockSignals( false );
3667  whileBlocking( mLockAspectRatio )->setLocked( preservedAspectRatio );
3668 
3669  whileBlocking( mRotationSpinBox )->setValue( mLayer->angle() );
3670  whileBlocking( mOpacityWidget )->setOpacity( mLayer->opacity() );
3671 
3672  whileBlocking( mSpinOffsetX )->setValue( mLayer->offset().x() );
3673  whileBlocking( mSpinOffsetY )->setValue( mLayer->offset().y() );
3674 
3675  mSizeUnitWidget->blockSignals( true );
3676  mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
3677  mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
3678  mSizeUnitWidget->blockSignals( false );
3679  mOffsetUnitWidget->blockSignals( true );
3680  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
3681  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
3682  mOffsetUnitWidget->blockSignals( false );
3683 
3684  //anchor points
3685  whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mLayer->horizontalAnchorPoint() );
3686  whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mLayer->verticalAnchorPoint() );
3687 
3696 
3697  updatePreviewImage();
3698 }
3699 
3701 {
3702  return mLayer;
3703 }
3704 
3706 {
3708  mImageSourceLineEdit->setMessageBar( context.messageBar() );
3709 }
3710 
3711 void QgsRasterMarkerSymbolLayerWidget::imageSourceChanged( const QString &text )
3712 {
3713  mLayer->setPath( text );
3714  updatePreviewImage();
3715  emit changed();
3716 }
3717 
3718 void QgsRasterMarkerSymbolLayerWidget::updatePreviewImage()
3719 {
3720  bool fitsInCache = false;
3721  QImage image = QgsApplication::imageCache()->pathAsImage( mLayer->path(), QSize( 150, 150 ), true, 1.0, fitsInCache );
3722  if ( image.isNull() )
3723  {
3724  mLabelImagePreview->setPixmap( QPixmap() );
3725  return;
3726  }
3727 
3728  QImage previewImage( 150, 150, QImage::Format_ARGB32 );
3729  previewImage.fill( Qt::transparent );
3730  QRect imageRect( ( 150 - image.width() ) / 2.0, ( 150 - image.height() ) / 2.0, image.width(), image.height() );
3731  QPainter p;
3732  p.begin( &previewImage );
3733  //draw a checkerboard background
3734  uchar pixDataRGB[] = { 150, 150, 150, 150,
3735  100, 100, 100, 150,
3736  100, 100, 100, 150,
3737  150, 150, 150, 150
3738  };
3739  QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
3740  QPixmap pix = QPixmap::fromImage( img.scaled( 8, 8 ) );
3741  QBrush checkerBrush;
3742  checkerBrush.setTexture( pix );
3743  p.fillRect( imageRect, checkerBrush );
3744 
3745  if ( mLayer->opacity() < 1.0 )
3746  {
3747  p.setOpacity( mLayer->opacity() );
3748  }
3749 
3750  p.drawImage( imageRect.left(), imageRect.top(), image );
3751  p.end();
3752  mLabelImagePreview->setPixmap( QPixmap::fromImage( previewImage ) );
3753 }
3754 
3755 void QgsRasterMarkerSymbolLayerWidget::setWidth()
3756 {
3757  double defaultAspectRatio = mLayer->defaultAspectRatio();
3758  double fixedAspectRatio = 0.0;
3759  mHeightSpinBox->blockSignals( true );
3760  if ( defaultAspectRatio <= 0.0 )
3761  {
3762  mHeightSpinBox->setValue( mWidthSpinBox->value() );
3763  }
3764  else if ( mLockAspectRatio->locked() )
3765  {
3766  mHeightSpinBox->setValue( mWidthSpinBox->value() * defaultAspectRatio );
3767  }
3768  else
3769  {
3770  fixedAspectRatio = mHeightSpinBox->value() / mWidthSpinBox->value();
3771  }
3772  mHeightSpinBox->blockSignals( false );
3773  mLayer->setSize( mWidthSpinBox->value() );
3774  mLayer->setFixedAspectRatio( fixedAspectRatio );
3775  emit changed();
3776 }
3777 
3778 void QgsRasterMarkerSymbolLayerWidget::setHeight()
3779 {
3780  double defaultAspectRatio = mLayer->defaultAspectRatio();
3781  double fixedAspectRatio = 0.0;
3782  mWidthSpinBox->blockSignals( true );
3783  if ( defaultAspectRatio <= 0.0 )
3784  {
3785  mWidthSpinBox->setValue( mHeightSpinBox->value() );
3786  }
3787  else if ( mLockAspectRatio->locked() )
3788  {
3789  mWidthSpinBox->setValue( mHeightSpinBox->value() / defaultAspectRatio );
3790  }
3791  else
3792  {
3793  fixedAspectRatio = mHeightSpinBox->value() / mWidthSpinBox->value();
3794  }
3795  mWidthSpinBox->blockSignals( false );
3796  mLayer->setSize( mWidthSpinBox->value() );
3797  mLayer->setFixedAspectRatio( fixedAspectRatio );
3798  emit changed();
3799 }
3800 
3801 void QgsRasterMarkerSymbolLayerWidget::setLockAspectRatio( const bool locked )
3802 {
3803  double defaultAspectRatio = mLayer->defaultAspectRatio();
3804  if ( defaultAspectRatio <= 0.0 )
3805  {
3806  whileBlocking( mLockAspectRatio )->setLocked( true );
3807  }
3808  else if ( locked )
3809  {
3810  mLayer->setFixedAspectRatio( 0.0 );
3811  setWidth();
3812  }
3813  else
3814  {
3815  mLayer->setFixedAspectRatio( mHeightSpinBox->value() / mWidthSpinBox->value() );
3816  }
3817 }
3818 
3819 void QgsRasterMarkerSymbolLayerWidget::setAngle()
3820 {
3821  mLayer->setAngle( mRotationSpinBox->value() );
3822  emit changed();
3823 }
3824 
3825 void QgsRasterMarkerSymbolLayerWidget::setOpacity( double value )
3826 {
3827  mLayer->setOpacity( value );
3828  emit changed();
3829  updatePreviewImage();
3830 }
3831 
3832 void QgsRasterMarkerSymbolLayerWidget::setOffset()
3833 {
3834  mLayer->setOffset( QPointF( mSpinOffsetX->value(), mSpinOffsetY->value() ) );
3835  emit changed();
3836 }
3837 
3838 void QgsRasterMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
3839 {
3840  if ( mLayer )
3841  {
3842  mLayer->setSizeUnit( mSizeUnitWidget->unit() );
3843  mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
3844  emit changed();
3845  }
3846 }
3847 
3848 void QgsRasterMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
3849 {
3850  if ( mLayer )
3851  {
3852  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
3853  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
3854  emit changed();
3855  }
3856 }
3857 
3858 void QgsRasterMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
3859 {
3860  if ( mLayer )
3861  {
3863  emit changed();
3864  }
3865 }
3866 
3867 void QgsRasterMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
3868 {
3869  if ( mLayer )
3870  {
3872  emit changed();
3873  }
3874 }
3875 
3877 
3879  : QgsSymbolLayerWidget( parent, vl )
3880 {
3881  mLayer = nullptr;
3882  setupUi( this );
3883 
3884  mImageSourceLineEdit->setLastPathSettingsKey( QStringLiteral( "/UI/lastRasterMarkerImageDir" ) );
3885  connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsRasterFillSymbolLayerWidget::imageSourceChanged );
3886 
3887  connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterFillSymbolLayerWidget::mOffsetUnitWidget_changed );
3888  connect( mRotationSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::mRotationSpinBox_valueChanged );
3889  connect( mWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterFillSymbolLayerWidget::mWidthUnitWidget_changed );
3890  connect( mWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::mWidthSpinBox_valueChanged );
3891 
3896 
3897  mSpinOffsetX->setClearValue( 0.0 );
3898  mSpinOffsetY->setClearValue( 0.0 );
3899  mRotationSpinBox->setClearValue( 0.0 );
3900 
3901  connect( cboCoordinateMode, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterFillSymbolLayerWidget::setCoordinateMode );
3902  connect( mSpinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::offsetChanged );
3903  connect( mSpinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::offsetChanged );
3904  connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsRasterFillSymbolLayerWidget::opacityChanged );
3905 }
3906 
3907 
3909 {
3910  if ( !layer )
3911  {
3912  return;
3913  }
3914 
3915  if ( layer->layerType() != QLatin1String( "RasterFill" ) )
3916  {
3917  return;
3918  }
3919 
3920  mLayer = dynamic_cast<QgsRasterFillSymbolLayer *>( layer );
3921  if ( !mLayer )
3922  {
3923  return;
3924  }
3925 
3926  whileBlocking( mImageSourceLineEdit )->setSource( mLayer->imageFilePath() );
3927 
3928  cboCoordinateMode->blockSignals( true );
3929  switch ( mLayer->coordinateMode() )
3930  {
3932  cboCoordinateMode->setCurrentIndex( 1 );
3933  break;
3935  default:
3936  cboCoordinateMode->setCurrentIndex( 0 );
3937  break;
3938  }
3939  cboCoordinateMode->blockSignals( false );
3940  whileBlocking( mOpacityWidget )->setOpacity( mLayer->opacity() );
3941  whileBlocking( mRotationSpinBox )->setValue( mLayer->angle() );
3942 
3943  whileBlocking( mSpinOffsetX )->setValue( mLayer->offset().x() );
3944  whileBlocking( mSpinOffsetY )->setValue( mLayer->offset().y() );
3945  mOffsetUnitWidget->blockSignals( true );
3946  mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
3947  mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
3948  mOffsetUnitWidget->blockSignals( false );
3949 
3950  whileBlocking( mWidthSpinBox )->setValue( mLayer->width() );
3951  mWidthUnitWidget->blockSignals( true );
3952  mWidthUnitWidget->setUnit( mLayer->widthUnit() );
3953  mWidthUnitWidget->setMapUnitScale( mLayer->widthMapUnitScale() );
3954  mWidthUnitWidget->blockSignals( false );
3955 
3956  updatePreviewImage();
3957 
3962 }
3963 
3965 {
3966  return mLayer;
3967 }
3968 
3969 void QgsRasterFillSymbolLayerWidget::imageSourceChanged( const QString &text )
3970 {
3971  mLayer->setImageFilePath( text );
3972  updatePreviewImage();
3973  emit changed();
3974 }
3975 
3976 void QgsRasterFillSymbolLayerWidget::setCoordinateMode( int index )
3977 {
3978  switch ( index )
3979  {
3980  case 0:
3981  //feature coordinate mode
3983  break;
3984  case 1:
3985  //viewport coordinate mode
3987  break;
3988  }
3989 
3990  emit changed();
3991 }
3992 
3993 void QgsRasterFillSymbolLayerWidget::opacityChanged( double value )
3994 {
3995  if ( !mLayer )
3996  {
3997  return;
3998  }
3999 
4000  mLayer->setOpacity( value );
4001  emit changed();
4002  updatePreviewImage();
4003 }
4004 
4005 void QgsRasterFillSymbolLayerWidget::offsetChanged()
4006 {
4007  mLayer->setOffset( QPointF( mSpinOffsetX->value(), mSpinOffsetY->value() ) );
4008  emit changed();
4009 }
4010 
4011 void QgsRasterFillSymbolLayerWidget::mOffsetUnitWidget_changed()
4012 {
4013  if ( !mLayer )
4014  {
4015  return;
4016  }
4017  mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
4018  mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
4019  emit changed();
4020 }
4021 
4022 void QgsRasterFillSymbolLayerWidget::mRotationSpinBox_valueChanged( double d )
4023 {
4024  if ( mLayer )
4025  {
4026  mLayer->setAngle( d );
4027  emit changed();
4028  }
4029 }
4030 
4031 void QgsRasterFillSymbolLayerWidget::mWidthUnitWidget_changed()
4032 {
4033  if ( !mLayer )
4034  {
4035  return;
4036  }
4037  mLayer->setWidthUnit( mWidthUnitWidget->unit() );
4038  mLayer->setWidthMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
4039  emit changed();
4040 }
4041 
4042 void QgsRasterFillSymbolLayerWidget::mWidthSpinBox_valueChanged( double d )
4043 {
4044  if ( !mLayer )
4045  {
4046  return;
4047  }
4048  mLayer->setWidth( d );
4049  emit changed();
4050 }
4051 
4052 void QgsRasterFillSymbolLayerWidget::updatePreviewImage()
4053 {
4054  bool fitsInCache = false;
4055  QImage image = QgsApplication::imageCache()->pathAsImage( mLayer->imageFilePath(), QSize( 150, 150 ), true, 1.0, fitsInCache );
4056  if ( image.isNull() )
4057  {
4058  mLabelImagePreview->setPixmap( QPixmap() );
4059  return;
4060  }
4061 
4062  QImage previewImage( 150, 150, QImage::Format_ARGB32 );
4063  previewImage.fill( Qt::transparent );
4064  QRect imageRect( ( 150 - image.width() ) / 2.0, ( 150 - image.height() ) / 2.0, image.width(), image.height() );
4065  QPainter p;
4066  p.begin( &previewImage );
4067  //draw a checkerboard background
4068  uchar pixDataRGB[] = { 150, 150, 150, 150,
4069  100, 100, 100, 150,
4070  100, 100, 100, 150,
4071  150, 150, 150, 150
4072  };
4073  QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
4074  QPixmap pix = QPixmap::fromImage( img.scaled( 8, 8 ) );
4075  QBrush checkerBrush;
4076  checkerBrush.setTexture( pix );
4077  p.fillRect( imageRect, checkerBrush );
4078 
4079  if ( mLayer->opacity() < 1.0 )
4080  {
4081  p.setOpacity( mLayer->opacity() );
4082  }
4083 
4084  p.drawImage( imageRect.left(), imageRect.top(), image );
4085  p.end();
4086  mLabelImagePreview->setPixmap( QPixmap::fromImage( previewImage ) );
4087 }
4088 
4089 
4091  : QgsSymbolLayerWidget( parent, vl )
4092 
4093 {
4094  setupUi( this );
4095  modificationExpressionSelector->setMultiLine( true );
4096  modificationExpressionSelector->setLayer( const_cast<QgsVectorLayer *>( vl ) );
4097  modificationExpressionSelector->registerExpressionContextGenerator( this );
4098  cbxGeometryType->addItem( QgsApplication::getThemeIcon( QStringLiteral( "/mIconPolygonLayer.svg" ) ), tr( "Polygon / MultiPolygon" ), QgsSymbol::Fill );
4099  cbxGeometryType->addItem( QgsApplication::getThemeIcon( QStringLiteral( "/mIconLineLayer.svg" ) ), tr( "LineString / MultiLineString" ), QgsSymbol::Line );
4100  cbxGeometryType->addItem( QgsApplication::getThemeIcon( QStringLiteral( "/mIconPointLayer.svg" ) ), tr( "Point / MultiPoint" ), QgsSymbol::Marker );
4101  connect( modificationExpressionSelector, &QgsExpressionLineEdit::expressionChanged, this, &QgsGeometryGeneratorSymbolLayerWidget::updateExpression );
4102  connect( cbxGeometryType, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGeometryGeneratorSymbolLayerWidget::updateSymbolType );
4103 }
4104 
4106 {
4107  mLayer = static_cast<QgsGeometryGeneratorSymbolLayer *>( l );
4108  modificationExpressionSelector->setExpression( mLayer->geometryExpression() );
4109  cbxGeometryType->setCurrentIndex( cbxGeometryType->findData( mLayer->symbolType() ) );
4110 }
4111 
4113 {
4114  return mLayer;
4115 }
4116 
4117 void QgsGeometryGeneratorSymbolLayerWidget::updateExpression( const QString &string )
4118 {
4119  mLayer->setGeometryExpression( string );
4120 
4121  emit changed();
4122 }
4123 
4124 void QgsGeometryGeneratorSymbolLayerWidget::updateSymbolType()
4125 {
4126  mLayer->setSymbolType( static_cast<QgsSymbol::SymbolType>( cbxGeometryType->currentData().toInt() ) );
4127 
4128  emit symbolChanged();
4129 }
4130 
4131 //
4132 // QgsRandomMarkerFillSymbolLayerWidget
4133 //
4134 
4135 
4137  QgsSymbolLayerWidget( parent, vl )
4138 {
4139  setupUi( this );
4140 
4141  mCountMethodComboBox->addItem( tr( "Absolute Count" ), QgsRandomMarkerFillSymbolLayer::AbsoluteCount );
4142  mCountMethodComboBox->addItem( tr( "Density-based Count" ), QgsRandomMarkerFillSymbolLayer::DensityBasedCount );
4143 
4144  mPointCountSpinBox->setShowClearButton( true );
4145  mPointCountSpinBox->setClearValue( 100 );
4146  mSeedSpinBox->setShowClearButton( true );
4147  mSeedSpinBox->setClearValue( 0 );
4148 
4149  connect( mCountMethodComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRandomMarkerFillSymbolLayerWidget::countMethodChanged );
4150  connect( mPointCountSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsRandomMarkerFillSymbolLayerWidget::countChanged );
4151  connect( mDensityAreaSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRandomMarkerFillSymbolLayerWidget::densityAreaChanged );
4152  connect( mSeedSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsRandomMarkerFillSymbolLayerWidget::seedChanged );
4153  connect( mClipPointsCheckBox, &QCheckBox::toggled, this, [ = ]( bool checked )
4154  {
4155  if ( mLayer )
4156  {
4157  mLayer->setClipPoints( checked );
4158  emit changed();
4159  }
4160  } );
4161 
4164 
4165  connect( mDensityAreaUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRandomMarkerFillSymbolLayerWidget::densityAreaUnitChanged );
4166 }
4167 
4169 {
4170  if ( !layer || layer->layerType() != QLatin1String( "RandomMarkerFill" ) )
4171  {
4172  return;
4173  }
4174 
4175  mLayer = static_cast<QgsRandomMarkerFillSymbolLayer *>( layer );
4176  whileBlocking( mPointCountSpinBox )->setValue( mLayer->pointCount() );
4177  whileBlocking( mSeedSpinBox )->setValue( mLayer->seed() );
4178  whileBlocking( mClipPointsCheckBox )->setChecked( mLayer->clipPoints() );
4179 
4180  bool showDensityBasedCountWidgets = false;
4181  switch ( mLayer->countMethod() )
4182  {
4184  showDensityBasedCountWidgets = true;
4185  break;
4187  break;
4188  }
4189  mDensityAreaLabel->setVisible( showDensityBasedCountWidgets );
4190  mDensityAreaSpinBox->setVisible( showDensityBasedCountWidgets );
4191  mDensityAreaUnitWidget->setVisible( showDensityBasedCountWidgets );
4192  mDensityAreaDdbtn->setVisible( showDensityBasedCountWidgets );
4193 
4194  whileBlocking( mCountMethodComboBox )->setCurrentIndex( mCountMethodComboBox->findData( mLayer->countMethod() ) );
4195  whileBlocking( mDensityAreaSpinBox )->setValue( mLayer->densityArea() );
4196  mDensityAreaUnitWidget->blockSignals( true );
4197  mDensityAreaUnitWidget->setUnit( mLayer->densityAreaUnit() );
4198  mDensityAreaUnitWidget->setMapUnitScale( mLayer->densityAreaUnitScale() );
4199  mDensityAreaUnitWidget->blockSignals( false );
4200 
4205 }
4206 
4208 {
4209  return mLayer;
4210 }
4211 
4212 void QgsRandomMarkerFillSymbolLayerWidget::countMethodChanged( int )
4213 {
4214 
4215  bool showDensityBasedCountWidgets = false;
4216  switch ( static_cast< QgsRandomMarkerFillSymbolLayer::CountMethod >( mCountMethodComboBox->currentData().toInt() ) )
4217  {
4219  showDensityBasedCountWidgets = true;
4220  break;
4222  break;
4223  }
4224  mDensityAreaLabel->setVisible( showDensityBasedCountWidgets );
4225  mDensityAreaSpinBox->setVisible( showDensityBasedCountWidgets );
4226  mDensityAreaUnitWidget->setVisible( showDensityBasedCountWidgets );
4227  mDensityAreaDdbtn->setVisible( showDensityBasedCountWidgets );
4228 
4229  if ( mLayer )
4230  {
4231  mLayer->setCountMethod( static_cast< QgsRandomMarkerFillSymbolLayer::CountMethod >( mCountMethodComboBox->currentData().toInt() ) );
4232  emit changed();
4233  }
4234 }
4235 
4236 void QgsRandomMarkerFillSymbolLayerWidget::countChanged( int d )
4237 {
4238  if ( mLayer )
4239  {
4240  mLayer->setPointCount( d );
4241  emit changed();
4242  }
4243 }
4244 
4245 void QgsRandomMarkerFillSymbolLayerWidget::densityAreaChanged( double d )
4246 {
4247  if ( mLayer )
4248  {
4249  mLayer->setDensityArea( d );
4250  emit changed();
4251  }
4252 }
4253 
4254 void QgsRandomMarkerFillSymbolLayerWidget::densityAreaUnitChanged()
4255 {
4256  if ( mLayer )
4257  {
4258  mLayer->setDensityAreaUnit( mDensityAreaUnitWidget->unit() );
4259  mLayer->setDensityAreaUnitScale( mDensityAreaUnitWidget->getMapUnitScale() );
4260  emit changed();
4261  }
4262 }
4263 
4264 void QgsRandomMarkerFillSymbolLayerWidget::seedChanged( int d )
4265 {
4266  if ( mLayer )
4267  {
4268  mLayer->setSeed( d );
4269  emit changed();
4270  }
4271 }
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:154
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 setPointCount(int count)
Sets the count of random points to render in the fill.
void setPenJoinStyle(Qt::PenJoinStyle style)
Sets the marker&#39;s stroke join style (e.g., miter, bevel, etc).
QgsSymbolLayer * symbolLayer() override
QgsGradientFillSymbolLayer * mLayer
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:182
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.
void containsParams(const QString &path, bool &hasFillParam, QColor &defaultFillColor, bool &hasStrokeParam, QColor &defaultStrokeColor, bool &hasStrokeWidthParam, double &defaultStrokeWidth, bool blocking=false) const
Tests if an svg file contains parameters for fill, stroke color, stroke width.
double angle() const
void setOffsetYMapUnitScale(const QgsMapUnitScale &scale)
Sets the unit scale for the vertical offset for rows in the pattern.
QgsLinePatternFillSymbolLayer * mLayer
void setColorRamp(QgsColorRamp *ramp)
Sets the color ramp used to draw the shapeburst fill.
QgsUnitTypes::RenderUnit widthUnit() const
Returns the units for the image&#39;s width.
void setDisplacementYUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the vertical displacement between rows in the pattern.
static QgsImageCache * imageCache()
Returns the application&#39;s image cache, used for caching resampled versions of raster images...
QgsGradientFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsGradientFillSymbolLayerWidget.
A simple line symbol layer, which renders lines using a line in a variety of styles (e...
double averageAngleLength() const
Returns the length of line over which the line&#39;s direction is averaged when calculating individual sy...
void setOffset(QPointF offset)
Sets the offset for the shapeburst fill.
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
QgsUnitTypes::RenderUnit patternWidthUnit() const
Returns the units for the width of the SVG images in the pattern.
Render both exterior and interior rings.
QgsSymbolLayer * symbolLayer() override
void setAngle(double angle)
Abstract base class for color ramps.
Definition: qgscolorramp.h:31
void sourceChanged(const QString &source)
Emitted whenever the file source is changed in the widget.
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.
Whether markers should be clipped to polygon boundaries.
void setCharacter(QChar character)
Sets the currently selected character in the widget.
void setSymbolLayer(QgsSymbolLayer *layer) override
const QgsMapUnitScale & hashLengthMapUnitScale() const
Returns the map unit scale for the hash length.
void setDistanceUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the maximum distance to shade inside of the shape from the polygon&#39;s boundary...
void setColor(const QColor &color)
const QgsMapUnitScale & strokeWidthMapUnitScale() const
ShapeburstColorType colorType() const
Returns the color mode used for the shapeburst fill.
QgsUnitTypes::RenderUnit averageAngleUnit() const
Returns the unit for the length over which the line&#39;s direction is averaged when calculating individu...
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsUnitTypes::RenderUnit offsetYUnit() const
Returns the units for the vertical offset for rows in the pattern.
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.
void setDensityAreaUnitScale(const QgsMapUnitScale &scale)
Sets the map scale for the density area.
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units for the line&#39;s offset.
Line symbol.
Definition: qgssymbol.h:87
QColor strokeColor() const override
Returns the marker&#39;s stroke color.
A fill symbol layer which places markers at random locations within polygons.
QgsCentroidFillSymbolLayer * mLayer
QColor color2() const
Color for endpoint of gradient, only used if the gradient color type is set to SimpleTwoColor.
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:218
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:895
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:1095
Gradient reference point 2 y.
static QList< QgsSimpleMarkerSymbolLayerBase::Shape > availableShapes()
Returns a list of all available shape types.
double lineAngle() const
Returns the angle for the parallel lines used to fill the symbol.
QgsShapeburstFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsShapeburstFillSymbolLayerWidget.
QgsUnitTypes::RenderUnit densityAreaUnit() const
Returns the units for the density area.
QString path() const
Returns the marker SVG path.
void setSymbolLayer(QgsSymbolLayer *layer) override
QColor strokeColor() const override
Gets stroke color.
void setGradientType(GradientType gradientType)
Place symbols at every virtual curve point in the line (used when rendering curved geometry types onl...
void clearCharacter()
Clears the currently selected character in the widget.
void setPenJoinStyle(Qt::PenJoinStyle style)
Sets the stroke join style.
double strokeWidth() const
Returns the width of the marker&#39;s stroke.
const QgsMapUnitScale & offsetMapUnitScale() const
Returns the map unit scale for the pattern&#39;s line offset.
void setPath(const QString &path)
Set the marker SVG path.
void setCustomDashPatternUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for lengths used in the custom dash pattern.
void setOffsetUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the line pattern&#39;s offset.
void setCoordinateMode(FillCoordinateMode mode)
Set the coordinate mode for fill.
virtual void setColor(const QColor &color)
The fill color.
double offsetY() const
Returns the vertical offset values for points in the pattern.
const QgsMapUnitScale & offsetYMapUnitScale() const
Returns the unit scale for the vertical offset between rows in the pattern.
Place symbols at the center of every line segment.
void setOffset(QPointF offset)
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.
CountMethod countMethod() const
Returns the count method used to randomly fill the polygon.
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.
void setCountMethod(CountMethod method)
Sets the count method used to randomly fill the polygon.
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].
bool clipPoints() const
Returns true if point markers should be clipped to the polygon boundary.
static QgsPanelWidget * findParentPanel(QWidget *widget)
Traces through the parents of a widget to find if it is contained within a QgsPanelWidget widget...
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map scale for the width of the marker&#39;s stroke.
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.
QgsRandomMarkerFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsRandomMarkerFillSymbolLayerWidget.
const QgsMapUnitScale & strokeWidthMapUnitScale() const
Returns the stroke width map unit scale.
void setDensityArea(double area)
Sets the density area used to count the number of points to randomly fill the polygon.
void resizeEvent(QResizeEvent *event) override
void setHashLengthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the hash length.
void registerExpressionContextGenerator(QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
double size() const
Returns the symbol size.
void opacityChanged(double opacity)
Emitted when the opacity is changed in the widget, where opacity ranges from 0.0 (transparent) to 1...
void setOffsetXUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the horizontal offset between rows in the pattern.
bool preservedAspectRatio() const
Returns the preserved aspect ratio value, true if fixed aspect ratio has been lower or equal to 0...
Render the interior rings only.
virtual QgsSymbolLayer * symbolLayer()=0
void setSymbolLayer(QgsSymbolLayer *layer) override
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
double densityArea() const
Returns the density area used to count the number of points to randomly fill the polygon.
const QgsMapUnitScale & strokeWidthMapUnitScale() const
Returns the map scale for the width of the marker&#39;s stroke.
void setWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the image&#39;s width.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer&#39;s property collection, used for data defined overrides...
void setHorizontalAnchorPoint(HorizontalAnchorPoint h)
Sets the horizontal anchor point for positioning the symbol.
Line symbol layer type which draws repeating line sections along a line feature.
const QgsMapUnitScale & offsetMapUnitScale() const
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:52
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.
void setSeed(unsigned long seed)
Sets the random number seed to use when generating points, or 0 if a truly random sequence will be us...
QgsSymbolLayer * symbolLayer() override
void setPenStyle(Qt::PenStyle style)
Sets the pen style used to render the line (e.g.
int pointCount() const
Returns the count of random points to render in the fill.
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.