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