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