QGIS API Documentation 3.27.0-Master (a46f227e17)
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
18
19#include "qgslinesymbollayer.h"
21#include "qgsfillsymbollayer.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"
41#include "qgslogger.h"
42#include "qgssettings.h"
45#include "qgsauxiliarystorage.h"
46#include "qgsimagecache.h"
47#include "qgslinesymbol.h"
48#include "qgsmarkersymbol.h"
49#include "qgsfillsymbol.h"
50#include "qgsiconutils.h"
51
52#include <QAbstractButton>
53#include <QButtonGroup>
54#include <QColorDialog>
55#include <QCursor>
56#include <QDir>
57#include <QFileDialog>
58#include <QPainter>
59#include <QStandardItemModel>
60#include <QSvgRenderer>
61#include <QMessageBox>
62#include <QMenu>
63#include <QAction>
64#include <QInputDialog>
65#include <QBuffer>
66#include <QRegularExpression>
67#include <QMovie>
68
70{
71 if ( auto *lExpressionContext = mContext.expressionContext() )
72 return *lExpressionContext;
73
75
77 if ( const QgsSymbolLayer *symbolLayer = const_cast< QgsSymbolLayerWidget * >( this )->symbolLayer() )
78 {
79 //cheat a bit - set the symbol color variable to match the symbol layer's color (when we should really be using the *symbols*
80 //color, but that's not accessible here). 99% of the time these will be the same anyway
82 }
83 expContext << symbolScope;
89 expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "symbol_layer_count" ), 1, true ) );
90 expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "symbol_layer_index" ), 1, true ) );
91 expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "symbol_marker_row" ), 1, true ) );
92 expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "symbol_marker_column" ), 1, true ) );
93 expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "symbol_frame" ), 1, true ) );
94
95 // additional scopes
96 const auto constAdditionalExpressionContextScopes = mContext.additionalExpressionContextScopes();
97 for ( const QgsExpressionContextScope &scope : constAdditionalExpressionContextScopes )
98 {
99 expContext.appendScope( new QgsExpressionContextScope( scope ) );
100 }
101
102 //TODO - show actual value
103 expContext.setOriginalValueVariable( QVariant() );
104
105 QStringList highlights;
111 << QStringLiteral( "symbol_layer_count" ) << QStringLiteral( "symbol_layer_index" ) << QStringLiteral( "symbol_frame" );
112
113
114 if ( expContext.hasVariable( QStringLiteral( "zoom_level" ) ) )
115 {
116 highlights << QStringLiteral( "zoom_level" );
117 }
118 if ( expContext.hasVariable( QStringLiteral( "vector_tile_zoom" ) ) )
119 {
120 highlights << QStringLiteral( "vector_tile_zoom" );
121 }
122
123 expContext.setHighlightedVariables( highlights );
124
125 return expContext;
126}
127
129{
130 mContext = context;
131 const auto unitSelectionWidgets = findChildren<QgsUnitSelectionWidget *>();
132 for ( QgsUnitSelectionWidget *unitWidget : unitSelectionWidgets )
133 {
134 unitWidget->setMapCanvas( mContext.mapCanvas() );
135 }
136}
137
139{
140 return mContext;
141}
142
144{
145 button->init( key, symbolLayer()->dataDefinedProperties(), QgsSymbolLayer::propertyDefinitions(), mVectorLayer, true );
147 connect( button, &QgsPropertyOverrideButton::createAuxiliaryField, this, &QgsSymbolLayerWidget::createAuxiliaryField );
148
150}
151
152void QgsSymbolLayerWidget::createAuxiliaryField()
153{
154 // try to create an auxiliary layer if not yet created
155 if ( !mVectorLayer->auxiliaryLayer() )
156 {
157 QgsNewAuxiliaryLayerDialog dlg( mVectorLayer, this );
158 dlg.exec();
159 }
160
161 // return if still not exists
162 if ( !mVectorLayer->auxiliaryLayer() )
163 return;
164
165 QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
166 const QgsSymbolLayer::Property key = static_cast< QgsSymbolLayer::Property >( button->propertyKey() );
168
169 // create property in auxiliary storage if necessary
170 if ( !mVectorLayer->auxiliaryLayer()->exists( def ) )
171 {
172 QgsNewAuxiliaryFieldDialog dlg( def, mVectorLayer, true, this );
173 if ( dlg.exec() == QDialog::Accepted )
174 def = dlg.propertyDefinition();
175 }
176
177 // return if still not exist
178 if ( !mVectorLayer->auxiliaryLayer()->exists( def ) )
179 return;
180
181 // update property with join field name from auxiliary storage
182 QgsProperty property = button->toProperty();
183 property.setField( QgsAuxiliaryLayer::nameFromProperty( def, true ) );
184 property.setActive( true );
185 button->updateFieldLists();
186 button->setToProperty( property );
187 symbolLayer()->setDataDefinedProperty( key, button->toProperty() );
188
189 emit changed();
190}
191
193{
194 QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
195 const QgsSymbolLayer::Property key = static_cast< QgsSymbolLayer::Property >( button->propertyKey() );
196 symbolLayer()->setDataDefinedProperty( key, button->toProperty() );
197 emit changed();
198}
199
201 : QgsSymbolLayerWidget( parent, vl )
202{
203 mLayer = nullptr;
204
205 setupUi( this );
206 connect( mCustomCheckBox, &QCheckBox::stateChanged, this, &QgsSimpleLineSymbolLayerWidget::mCustomCheckBox_stateChanged );
207 connect( mChangePatternButton, &QPushButton::clicked, this, &QgsSimpleLineSymbolLayerWidget::mChangePatternButton_clicked );
208 connect( mPenWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::mPenWidthUnitWidget_changed );
209 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::mOffsetUnitWidget_changed );
210 connect( mDashPatternUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::mDashPatternUnitWidget_changed );
211 connect( mDrawInsideCheckBox, &QCheckBox::stateChanged, this, &QgsSimpleLineSymbolLayerWidget::mDrawInsideCheckBox_stateChanged );
212 connect( mPatternOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::patternOffsetUnitChanged );
213 connect( mCheckAlignDash, &QCheckBox::toggled, this, [ = ]
214 {
215 mCheckDashCorners->setEnabled( mCheckAlignDash->isChecked() );
216 if ( !mCheckAlignDash->isChecked() )
217 mCheckDashCorners->setChecked( false );
218
219 if ( mLayer )
220 {
221 mLayer->setAlignDashPattern( mCheckAlignDash->isChecked() );
222 emit changed();
223 }
224 } );
225 connect( mCheckDashCorners, &QCheckBox::toggled, this, [ = ]
226 {
227 if ( mLayer )
228 {
229 mLayer->setTweakDashPatternOnCorners( mCheckDashCorners->isChecked() );
230 emit changed();
231 }
232 } );
233
246
247 btnChangeColor->setAllowOpacity( true );
248 btnChangeColor->setColorDialogTitle( tr( "Select Line Color" ) );
249 btnChangeColor->setContext( QStringLiteral( "symbology" ) );
250
251 mColorDDBtn->registerLinkedWidget( btnChangeColor );
252
253 mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconAllRings.svg" ) ), tr( "All Rings" ), QgsLineSymbolLayer::AllRings );
254 mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconExteriorRing.svg" ) ), tr( "Exterior Ring Only" ), QgsLineSymbolLayer::ExteriorRingOnly );
255 mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconInteriorRings.svg" ) ), tr( "Interior Rings Only" ), QgsLineSymbolLayer::InteriorRingsOnly );
256 connect( mRingFilterComboBox, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]( int )
257 {
258 if ( mLayer )
259 {
260 mLayer->setRingFilter( static_cast< QgsLineSymbolLayer::RenderRingFilter >( mRingFilterComboBox->currentData().toInt() ) );
261 emit changed();
262 }
263 } );
264
265 spinOffset->setClearValue( 0.0 );
266 spinPatternOffset->setClearValue( 0.0 );
267
268 mTrimStartDistanceSpin->setClearValue( 0.0 );
269 mTrimDistanceEndSpin->setClearValue( 0.0 );
270
271 //make a temporary symbol for the size assistant preview
272 mAssistantPreviewSymbol.reset( new QgsLineSymbol() );
273
274 if ( vectorLayer() )
275 mPenWidthDDBtn->setSymbol( mAssistantPreviewSymbol );
276
277 connect( spinWidth, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleLineSymbolLayerWidget::penWidthChanged );
278 connect( btnChangeColor, &QgsColorButton::colorChanged, this, &QgsSimpleLineSymbolLayerWidget::colorChanged );
279 connect( cboPenStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleLineSymbolLayerWidget::penStyleChanged );
280 connect( spinOffset, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleLineSymbolLayerWidget::offsetChanged );
281 connect( cboCapStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleLineSymbolLayerWidget::penStyleChanged );
282 connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleLineSymbolLayerWidget::penStyleChanged );
283 connect( spinPatternOffset, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleLineSymbolLayerWidget::patternOffsetChanged );
284
285 connect( mTrimStartDistanceSpin, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value )
286 {
287 if ( !mLayer )
288 return;
289
291 emit changed();
292 } );
293 connect( mTrimDistanceStartUnitWidget, &QgsUnitSelectionWidget::changed, this, [ = ]
294 {
295 if ( !mLayer )
296 return;
297
298 mLayer->setTrimDistanceStartUnit( mTrimDistanceStartUnitWidget->unit() );
299 mLayer->setTrimDistanceStartMapUnitScale( mTrimDistanceStartUnitWidget->getMapUnitScale() );
300 emit changed();
301 } );
302 connect( mTrimDistanceEndSpin, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value )
303 {
304 if ( !mLayer )
305 return;
306
307 mLayer->setTrimDistanceEnd( value );
308 emit changed();
309 } );
310 connect( mTrimDistanceEndUnitWidget, &QgsUnitSelectionWidget::changed, this, [ = ]
311 {
312 if ( !mLayer )
313 return;
314
315 mLayer->setTrimDistanceEndUnit( mTrimDistanceEndUnitWidget->unit() );
316 mLayer->setTrimDistanceEndMapUnitScale( mTrimDistanceEndUnitWidget->getMapUnitScale() );
317 emit changed();
318 } );
319
320
322
323 connect( this, &QgsSymbolLayerWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::updateAssistantSymbol );
324}
325
327
328void QgsSimpleLineSymbolLayerWidget::updateAssistantSymbol()
329{
330 for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
331 {
332 mAssistantPreviewSymbol->deleteSymbolLayer( i );
333 }
334 mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
336 if ( ddWidth )
337 mAssistantPreviewSymbol->setDataDefinedWidth( ddWidth );
338}
339
340
342{
343 if ( !layer || layer->layerType() != QLatin1String( "SimpleLine" ) )
344 return;
345
346 // layer type is correct, we can do the cast
347 mLayer = static_cast<QgsSimpleLineSymbolLayer *>( layer );
348
349 // set units
350 mPenWidthUnitWidget->blockSignals( true );
351 mPenWidthUnitWidget->setUnit( mLayer->widthUnit() );
352 mPenWidthUnitWidget->setMapUnitScale( mLayer->widthMapUnitScale() );
353 mPenWidthUnitWidget->blockSignals( false );
354 mOffsetUnitWidget->blockSignals( true );
355 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
356 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
357 mOffsetUnitWidget->blockSignals( false );
358 mDashPatternUnitWidget->blockSignals( true );
359 mDashPatternUnitWidget->setUnit( mLayer->customDashPatternUnit() );
360 mDashPatternUnitWidget->setMapUnitScale( mLayer->customDashPatternMapUnitScale() );
361 mDashPatternUnitWidget->blockSignals( false );
362
363 whileBlocking( mPatternOffsetUnitWidget )->setUnit( mLayer->dashPatternOffsetUnit() );
364 whileBlocking( mPatternOffsetUnitWidget )->setMapUnitScale( mLayer->dashPatternOffsetMapUnitScale() );
365 whileBlocking( mTrimDistanceStartUnitWidget )->setUnit( mLayer->trimDistanceStartUnit() );
366 whileBlocking( mTrimDistanceStartUnitWidget )->setMapUnitScale( mLayer->trimDistanceStartMapUnitScale() );
367 whileBlocking( mTrimDistanceEndUnitWidget )->setUnit( mLayer->trimDistanceEndUnit() );
368 whileBlocking( mTrimDistanceEndUnitWidget )->setMapUnitScale( mLayer->trimDistanceEndMapUnitScale() );
369
370 // set values
371 spinWidth->blockSignals( true );
372 spinWidth->setValue( mLayer->width() );
373 spinWidth->blockSignals( false );
374 btnChangeColor->blockSignals( true );
375 btnChangeColor->setColor( mLayer->color() );
376 btnChangeColor->blockSignals( false );
377 spinOffset->blockSignals( true );
378 spinOffset->setValue( mLayer->offset() );
379 spinOffset->blockSignals( false );
380 cboPenStyle->blockSignals( true );
381 cboJoinStyle->blockSignals( true );
382 cboCapStyle->blockSignals( true );
383 cboPenStyle->setPenStyle( mLayer->penStyle() );
384 cboJoinStyle->setPenJoinStyle( mLayer->penJoinStyle() );
385 cboCapStyle->setPenCapStyle( mLayer->penCapStyle() );
386 cboPenStyle->blockSignals( false );
387 cboJoinStyle->blockSignals( false );
388 cboCapStyle->blockSignals( false );
389 whileBlocking( spinPatternOffset )->setValue( mLayer->dashPatternOffset() );
390 whileBlocking( mTrimStartDistanceSpin )->setValue( mLayer->trimDistanceStart() );
391 whileBlocking( mTrimDistanceEndSpin )->setValue( mLayer->trimDistanceEnd() );
392
393 //use a custom dash pattern?
394 const bool useCustomDashPattern = mLayer->useCustomDashPattern();
395 mChangePatternButton->setEnabled( useCustomDashPattern );
396 label_3->setEnabled( !useCustomDashPattern );
397 cboPenStyle->setEnabled( !useCustomDashPattern );
398 mCustomCheckBox->blockSignals( true );
399 mCustomCheckBox->setCheckState( useCustomDashPattern ? Qt::Checked : Qt::Unchecked );
400 mCustomCheckBox->blockSignals( false );
401
402 //make sure height of custom dash button looks good under different platforms
403 const QSize size = mChangePatternButton->minimumSizeHint();
404 const int fontHeight = static_cast< int >( Qgis::UI_SCALE_FACTOR * fontMetrics().height() * 1.4 );
405 mChangePatternButton->setMinimumSize( QSize( size.width(), std::max( size.height(), fontHeight ) ) );
406
407 //draw inside polygon?
408 const bool drawInsidePolygon = mLayer->drawInsidePolygon();
409 whileBlocking( mDrawInsideCheckBox )->setCheckState( drawInsidePolygon ? Qt::Checked : Qt::Unchecked );
410
411 whileBlocking( mRingFilterComboBox )->setCurrentIndex( mRingFilterComboBox->findData( mLayer->ringFilter() ) );
412
413 whileBlocking( mCheckAlignDash )->setChecked( mLayer->alignDashPattern() );
414 mCheckDashCorners->setEnabled( mLayer->alignDashPattern() );
415 whileBlocking( mCheckDashCorners )->setChecked( mLayer->tweakDashPatternOnCorners() && mLayer->alignDashPattern() );
416
418
429
430 updateAssistantSymbol();
431}
432
434{
435 return mLayer;
436}
437
439{
441
442 switch ( context.symbolType() )
443 {
446 //these settings only have an effect when the symbol layers is part of a fill symbol
447 mDrawInsideCheckBox->hide();
448 mRingFilterComboBox->hide();
449 mRingsLabel->hide();
450 break;
451
454 break;
455 }
456}
457
458void QgsSimpleLineSymbolLayerWidget::penWidthChanged()
459{
460 mLayer->setWidth( spinWidth->value() );
462 emit changed();
463}
464
465void QgsSimpleLineSymbolLayerWidget::colorChanged( const QColor &color )
466{
467 mLayer->setColor( color );
468 emit changed();
469}
470
471void QgsSimpleLineSymbolLayerWidget::penStyleChanged()
472{
473 mLayer->setPenStyle( cboPenStyle->penStyle() );
474 mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
475 mLayer->setPenCapStyle( cboCapStyle->penCapStyle() );
477 emit changed();
478}
479
480void QgsSimpleLineSymbolLayerWidget::offsetChanged()
481{
482 mLayer->setOffset( spinOffset->value() );
484 emit changed();
485}
486
487void QgsSimpleLineSymbolLayerWidget::patternOffsetChanged()
488{
489 mLayer->setDashPatternOffset( spinPatternOffset->value() );
491 emit changed();
492}
493
494void QgsSimpleLineSymbolLayerWidget::mCustomCheckBox_stateChanged( int state )
495{
496 const bool checked = ( state == Qt::Checked );
497 mChangePatternButton->setEnabled( checked );
498 label_3->setEnabled( !checked );
499 cboPenStyle->setEnabled( !checked );
500
502 emit changed();
503}
504
505void QgsSimpleLineSymbolLayerWidget::mChangePatternButton_clicked()
506{
508 if ( panel && panel->dockMode() )
509 {
511 widget->setPanelTitle( tr( "Custom Dash Pattern" ) );
512 widget->setUnit( mDashPatternUnitWidget->unit() );
513 connect( widget, &QgsPanelWidget::widgetChanged, this, [ this, widget ]()
514 {
517 } );
519 panel->openPanel( widget );
520 return;
521 }
522
524 d.setUnit( mDashPatternUnitWidget->unit() );
525 if ( d.exec() == QDialog::Accepted )
526 {
527 mLayer->setCustomDashVector( d.dashDotVector() );
529 emit changed();
530 }
531}
532
533void QgsSimpleLineSymbolLayerWidget::mPenWidthUnitWidget_changed()
534{
535 if ( mLayer )
536 {
537 mLayer->setWidthUnit( mPenWidthUnitWidget->unit() );
538 mLayer->setWidthMapUnitScale( mPenWidthUnitWidget->getMapUnitScale() );
540 emit changed();
541 }
542}
543
544void QgsSimpleLineSymbolLayerWidget::mOffsetUnitWidget_changed()
545{
546 if ( mLayer )
547 {
548 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
549 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
550 emit changed();
551 }
552}
553
554void QgsSimpleLineSymbolLayerWidget::mDashPatternUnitWidget_changed()
555{
556 if ( mLayer )
557 {
558 mLayer->setCustomDashPatternUnit( mDashPatternUnitWidget->unit() );
559 mLayer->setCustomDashPatternMapUnitScale( mDashPatternUnitWidget->getMapUnitScale() );
561 emit changed();
562 }
563}
564
565void QgsSimpleLineSymbolLayerWidget::mDrawInsideCheckBox_stateChanged( int state )
566{
567 const bool checked = ( state == Qt::Checked );
568 mLayer->setDrawInsidePolygon( checked );
569 emit changed();
570}
571
572void QgsSimpleLineSymbolLayerWidget::patternOffsetUnitChanged()
573{
574 if ( mLayer )
575 {
576 mLayer->setDashPatternOffsetUnit( mPatternOffsetUnitWidget->unit() );
577 mLayer->setDashPatternOffsetMapUnitScale( mPatternOffsetUnitWidget->getMapUnitScale() );
579 emit changed();
580 }
581}
582
584{
585 if ( !mLayer )
586 {
587 return;
588 }
589 std::unique_ptr< QgsSimpleLineSymbolLayer > layerCopy( mLayer->clone() );
590 if ( !layerCopy )
591 {
592 return;
593 }
594 const QColor color = qApp->palette().color( QPalette::WindowText );
595 layerCopy->setColor( color );
596 // reset offset, we don't want to show that in the preview
597 layerCopy->setOffset( 0 );
598 layerCopy->setUseCustomDashPattern( true );
599
600 QSize currentIconSize;
601 //icon size is button size with a small margin
602#ifdef Q_OS_WIN
603 currentIconSize = QSize( mChangePatternButton->width() - 10, mChangePatternButton->height() - 6 );
604#else
605 currentIconSize = QSize( mChangePatternButton->width() - 10, mChangePatternButton->height() - 12 );
606#endif
607
608 if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 )
609 {
610 return;
611 }
612
613 //create an icon pixmap
614 const std::unique_ptr< QgsLineSymbol > previewSymbol = std::make_unique< QgsLineSymbol >( QgsSymbolLayerList() << layerCopy.release() );
615 const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( previewSymbol.get(), currentIconSize );
616 mChangePatternButton->setIconSize( currentIconSize );
617 mChangePatternButton->setIcon( icon );
618
619 // set tooltip
620 // create very large preview image
621 const int width = static_cast< int >( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 23 );
622 const int height = static_cast< int >( width / 1.61803398875 ); // golden ratio
623
624 const QPixmap pm = QgsSymbolLayerUtils::symbolPreviewPixmap( previewSymbol.get(), QSize( width, height ), height / 20 );
625 QByteArray data;
626 QBuffer buffer( &data );
627 pm.save( &buffer, "PNG", 100 );
628 mChangePatternButton->setToolTip( QStringLiteral( "<img src='data:image/png;base64, %3'>" ).arg( QString( data.toBase64() ) ) );
629}
630
632{
633 QgsSymbolLayerWidget::resizeEvent( event );
634 // redraw custom dash pattern icon -- the button size has changed
636}
637
638
640
641
643 : QgsSymbolLayerWidget( parent, vl )
644{
645 mLayer = nullptr;
646
647 setupUi( this );
648 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
649 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
650 connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
651 connect( mStrokeStyleComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mStrokeStyleComboBox_currentIndexChanged );
652 connect( mStrokeWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
653 connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
654 connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
661
662 btnChangeColorFill->setAllowOpacity( true );
663 btnChangeColorFill->setColorDialogTitle( tr( "Select Fill Color" ) );
664 btnChangeColorFill->setContext( QStringLiteral( "symbology" ) );
665 btnChangeColorFill->setShowNoColor( true );
666 btnChangeColorFill->setNoColorString( tr( "Transparent Fill" ) );
667 btnChangeColorStroke->setAllowOpacity( true );
668 btnChangeColorStroke->setColorDialogTitle( tr( "Select Stroke Color" ) );
669 btnChangeColorStroke->setContext( QStringLiteral( "symbology" ) );
670 btnChangeColorStroke->setShowNoColor( true );
671 btnChangeColorStroke->setNoColorString( tr( "Transparent Stroke" ) );
672
673 mFillColorDDBtn->registerLinkedWidget( btnChangeColorFill );
674 mStrokeColorDDBtn->registerLinkedWidget( btnChangeColorStroke );
675
676 spinOffsetX->setClearValue( 0.0 );
677 spinOffsetY->setClearValue( 0.0 );
678 spinAngle->setClearValue( 0.0 );
679
680 //make a temporary symbol for the size assistant preview
681 mAssistantPreviewSymbol.reset( new QgsMarkerSymbol() );
682
683 if ( vectorLayer() )
684 mSizeDDBtn->setSymbol( mAssistantPreviewSymbol );
685
686 int size = lstNames->iconSize().width();
687
688 size = std::max( 30, static_cast< int >( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 3 ) ) );
689
690 lstNames->setGridSize( QSize( size * 1.2, size * 1.2 ) );
691 lstNames->setIconSize( QSize( size, size ) );
692
693 const double markerSize = size * 0.8;
695 for ( const Qgis::MarkerShape shape : shapes )
696 {
697 QgsSimpleMarkerSymbolLayer *lyr = new QgsSimpleMarkerSymbolLayer( shape, markerSize );
699 lyr->setColor( QColor( 200, 200, 200 ) );
700 lyr->setStrokeColor( QColor( 0, 0, 0 ) );
701 const QIcon icon = QgsSymbolLayerUtils::symbolLayerPreviewIcon( lyr, QgsUnitTypes::RenderPixels, QSize( size, size ) );
702 QListWidgetItem *item = new QListWidgetItem( icon, QString(), lstNames );
703 item->setData( Qt::UserRole, static_cast< int >( shape ) );
704 item->setToolTip( QgsSimpleMarkerSymbolLayerBase::encodeShape( shape ) );
705 delete lyr;
706 }
707 // show at least 3 rows
708 lstNames->setMinimumHeight( lstNames->gridSize().height() * 3.1 );
709
710 connect( lstNames, &QListWidget::currentRowChanged, this, &QgsSimpleMarkerSymbolLayerWidget::setShape );
713 connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::penJoinStyleChanged );
714 connect( cboCapStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::penCapStyleChanged );
715 connect( spinSize, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setSize );
716 connect( spinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setAngle );
717 connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setOffset );
718 connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setOffset );
719 connect( this, &QgsSymbolLayerWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::updateAssistantSymbol );
720}
721
723
725{
726 if ( layer->layerType() != QLatin1String( "SimpleMarker" ) )
727 return;
728
729 // layer type is correct, we can do the cast
730 mLayer = static_cast<QgsSimpleMarkerSymbolLayer *>( layer );
731
732 // set values
733 const Qgis::MarkerShape shape = mLayer->shape();
734 for ( int i = 0; i < lstNames->count(); ++i )
735 {
736 if ( static_cast< Qgis::MarkerShape >( lstNames->item( i )->data( Qt::UserRole ).toInt() ) == shape )
737 {
738 lstNames->setCurrentRow( i );
739 break;
740 }
741 }
742 btnChangeColorStroke->blockSignals( true );
743 btnChangeColorStroke->setColor( mLayer->strokeColor() );
744 btnChangeColorStroke->blockSignals( false );
745 btnChangeColorFill->blockSignals( true );
746 btnChangeColorFill->setColor( mLayer->fillColor() );
747 btnChangeColorFill->setEnabled( QgsSimpleMarkerSymbolLayerBase::shapeIsFilled( mLayer->shape() ) );
748 btnChangeColorFill->blockSignals( false );
749 spinSize->blockSignals( true );
750 spinSize->setValue( mLayer->size() );
751 spinSize->blockSignals( false );
752 spinAngle->blockSignals( true );
753 spinAngle->setValue( mLayer->angle() );
754 spinAngle->blockSignals( false );
755 mStrokeStyleComboBox->blockSignals( true );
756 mStrokeStyleComboBox->setPenStyle( mLayer->strokeStyle() );
757 mStrokeStyleComboBox->blockSignals( false );
758 mStrokeWidthSpinBox->blockSignals( true );
759 mStrokeWidthSpinBox->setValue( mLayer->strokeWidth() );
760 mStrokeWidthSpinBox->blockSignals( false );
761 cboJoinStyle->blockSignals( true );
762 cboJoinStyle->setPenJoinStyle( mLayer->penJoinStyle() );
763 cboJoinStyle->blockSignals( false );
764 cboCapStyle->blockSignals( true );
765 cboCapStyle->setPenCapStyle( mLayer->penCapStyle() );
766 cboCapStyle->blockSignals( false );
767
768 // without blocking signals the value gets changed because of slot setOffset()
769 spinOffsetX->blockSignals( true );
770 spinOffsetX->setValue( mLayer->offset().x() );
771 spinOffsetX->blockSignals( false );
772 spinOffsetY->blockSignals( true );
773 spinOffsetY->setValue( mLayer->offset().y() );
774 spinOffsetY->blockSignals( false );
775
776 mSizeUnitWidget->blockSignals( true );
777 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
778 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
779 mSizeUnitWidget->blockSignals( false );
780 mOffsetUnitWidget->blockSignals( true );
781 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
782 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
783 mOffsetUnitWidget->blockSignals( false );
784 mStrokeWidthUnitWidget->blockSignals( true );
785 mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
786 mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
787 mStrokeWidthUnitWidget->blockSignals( false );
788
789 //anchor points
790 mHorizontalAnchorComboBox->blockSignals( true );
791 mVerticalAnchorComboBox->blockSignals( true );
792 mHorizontalAnchorComboBox->setCurrentIndex( mLayer->horizontalAnchorPoint() );
793 mVerticalAnchorComboBox->setCurrentIndex( mLayer->verticalAnchorPoint() );
794 mHorizontalAnchorComboBox->blockSignals( false );
795 mVerticalAnchorComboBox->blockSignals( false );
796
809
810 updateAssistantSymbol();
811}
812
814{
815 return mLayer;
816}
817
818void QgsSimpleMarkerSymbolLayerWidget::setShape()
819{
820 mLayer->setShape( static_cast< Qgis::MarkerShape >( lstNames->currentItem()->data( Qt::UserRole ).toInt() ) );
821 btnChangeColorFill->setEnabled( QgsSimpleMarkerSymbolLayerBase::shapeIsFilled( mLayer->shape() ) );
822 emit changed();
823}
824
826{
827 mLayer->setStrokeColor( color );
828 emit changed();
829}
830
832{
833 mLayer->setColor( color );
834 emit changed();
835}
836
837void QgsSimpleMarkerSymbolLayerWidget::penJoinStyleChanged()
838{
839 mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
840 emit changed();
841}
842
843void QgsSimpleMarkerSymbolLayerWidget::penCapStyleChanged()
844{
845 mLayer->setPenCapStyle( cboCapStyle->penCapStyle() );
846 emit changed();
847}
848
849void QgsSimpleMarkerSymbolLayerWidget::setSize()
850{
851 mLayer->setSize( spinSize->value() );
852 emit changed();
853}
854
855void QgsSimpleMarkerSymbolLayerWidget::setAngle()
856{
857 mLayer->setAngle( spinAngle->value() );
858 emit changed();
859}
860
861void QgsSimpleMarkerSymbolLayerWidget::setOffset()
862{
863 mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
864 emit changed();
865}
866
867void QgsSimpleMarkerSymbolLayerWidget::mStrokeStyleComboBox_currentIndexChanged( int index )
868{
869 Q_UNUSED( index )
870
871 if ( mLayer )
872 {
873 mLayer->setStrokeStyle( mStrokeStyleComboBox->penStyle() );
874 emit changed();
875 }
876}
877
878void QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
879{
880 if ( mLayer )
881 {
883 emit changed();
884 }
885}
886
887void QgsSimpleMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
888{
889 if ( mLayer )
890 {
891 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
892 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
893 emit changed();
894 }
895}
896
897void QgsSimpleMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
898{
899 if ( mLayer )
900 {
901 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
902 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
903 emit changed();
904 }
905}
906
907void QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
908{
909 if ( mLayer )
910 {
911 mLayer->setStrokeWidthUnit( mStrokeWidthUnitWidget->unit() );
912 mLayer->setStrokeWidthMapUnitScale( mStrokeWidthUnitWidget->getMapUnitScale() );
913 emit changed();
914 }
915}
916
917void QgsSimpleMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
918{
919 if ( mLayer )
920 {
922 emit changed();
923 }
924}
925
926void QgsSimpleMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
927{
928 if ( mLayer )
929 {
931 emit changed();
932 }
933}
934
935void QgsSimpleMarkerSymbolLayerWidget::updateAssistantSymbol()
936{
937 for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
938 {
939 mAssistantPreviewSymbol->deleteSymbolLayer( i );
940 }
941 mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
943 if ( ddSize )
944 mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
945}
946
947
949
951 : QgsSymbolLayerWidget( parent, vl )
952{
953 mLayer = nullptr;
954
955 setupUi( this );
956 connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleFillSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
957 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleFillSymbolLayerWidget::mOffsetUnitWidget_changed );
962
963 btnChangeColor->setAllowOpacity( true );
964 btnChangeColor->setColorDialogTitle( tr( "Select Fill Color" ) );
965 btnChangeColor->setContext( QStringLiteral( "symbology" ) );
966 btnChangeColor->setShowNoColor( true );
967 btnChangeColor->setNoColorString( tr( "Transparent Fill" ) );
968 btnChangeStrokeColor->setAllowOpacity( true );
969 btnChangeStrokeColor->setColorDialogTitle( tr( "Select Stroke Color" ) );
970 btnChangeStrokeColor->setContext( QStringLiteral( "symbology" ) );
971 btnChangeStrokeColor->setShowNoColor( true );
972 btnChangeStrokeColor->setNoColorString( tr( "Transparent Stroke" ) );
973
974 spinOffsetX->setClearValue( 0.0 );
975 spinOffsetY->setClearValue( 0.0 );
976
978 connect( cboFillStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleFillSymbolLayerWidget::setBrushStyle );
980 connect( spinStrokeWidth, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleFillSymbolLayerWidget::strokeWidthChanged );
981 connect( cboStrokeStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleFillSymbolLayerWidget::strokeStyleChanged );
982 connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleFillSymbolLayerWidget::strokeStyleChanged );
983 connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleFillSymbolLayerWidget::offsetChanged );
984 connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleFillSymbolLayerWidget::offsetChanged );
985
986 mFillColorDDBtn->registerLinkedWidget( btnChangeColor );
987 mStrokeColorDDBtn->registerLinkedWidget( btnChangeStrokeColor );
988}
989
991{
992 if ( layer->layerType() != QLatin1String( "SimpleFill" ) )
993 return;
994
995 // layer type is correct, we can do the cast
996 mLayer = static_cast<QgsSimpleFillSymbolLayer *>( layer );
997
998 // set values
999 btnChangeColor->blockSignals( true );
1000 btnChangeColor->setColor( mLayer->color() );
1001 btnChangeColor->blockSignals( false );
1002 cboFillStyle->blockSignals( true );
1003 cboFillStyle->setBrushStyle( mLayer->brushStyle() );
1004 cboFillStyle->blockSignals( false );
1005 btnChangeStrokeColor->blockSignals( true );
1006 btnChangeStrokeColor->setColor( mLayer->strokeColor() );
1007 btnChangeStrokeColor->blockSignals( false );
1008 cboStrokeStyle->blockSignals( true );
1009 cboStrokeStyle->setPenStyle( mLayer->strokeStyle() );
1010 cboStrokeStyle->blockSignals( false );
1011 spinStrokeWidth->blockSignals( true );
1012 spinStrokeWidth->setValue( mLayer->strokeWidth() );
1013 spinStrokeWidth->blockSignals( false );
1014 cboJoinStyle->blockSignals( true );
1015 cboJoinStyle->setPenJoinStyle( mLayer->penJoinStyle() );
1016 cboJoinStyle->blockSignals( false );
1017 spinOffsetX->blockSignals( true );
1018 spinOffsetX->setValue( mLayer->offset().x() );
1019 spinOffsetX->blockSignals( false );
1020 spinOffsetY->blockSignals( true );
1021 spinOffsetY->setValue( mLayer->offset().y() );
1022 spinOffsetY->blockSignals( false );
1023
1024 mStrokeWidthUnitWidget->blockSignals( true );
1025 mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
1026 mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
1027 mStrokeWidthUnitWidget->blockSignals( false );
1028 mOffsetUnitWidget->blockSignals( true );
1029 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1030 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1031 mOffsetUnitWidget->blockSignals( false );
1032
1040}
1041
1043{
1044 return mLayer;
1045}
1046
1048{
1049 mLayer->setColor( color );
1050 emit changed();
1051}
1052
1054{
1055 mLayer->setStrokeColor( color );
1056 emit changed();
1057}
1058
1059void QgsSimpleFillSymbolLayerWidget::setBrushStyle()
1060{
1061 mLayer->setBrushStyle( cboFillStyle->brushStyle() );
1062 emit changed();
1063}
1064
1065void QgsSimpleFillSymbolLayerWidget::strokeWidthChanged()
1066{
1067 mLayer->setStrokeWidth( spinStrokeWidth->value() );
1068 emit changed();
1069}
1070
1071void QgsSimpleFillSymbolLayerWidget::strokeStyleChanged()
1072{
1073 mLayer->setStrokeStyle( cboStrokeStyle->penStyle() );
1074 mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
1075 emit changed();
1076}
1077
1078void QgsSimpleFillSymbolLayerWidget::offsetChanged()
1079{
1080 mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1081 emit changed();
1082}
1083
1084void QgsSimpleFillSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
1085{
1086 if ( mLayer )
1087 {
1088 mLayer->setStrokeWidthUnit( mStrokeWidthUnitWidget->unit() );
1089 mLayer->setStrokeWidthMapUnitScale( mStrokeWidthUnitWidget->getMapUnitScale() );
1090 emit changed();
1091 }
1092}
1093
1094void QgsSimpleFillSymbolLayerWidget::mOffsetUnitWidget_changed()
1095{
1096 if ( mLayer )
1097 {
1098 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1099 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1100 emit changed();
1101 }
1102}
1103
1105
1107 : QgsSymbolLayerWidget( parent, vl )
1108{
1109 mLayer = nullptr;
1110
1111 setupUi( this );
1112 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFilledMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
1113 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFilledMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
1114 connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFilledMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
1115 connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFilledMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
1120
1121 spinOffsetX->setClearValue( 0.0 );
1122 spinOffsetY->setClearValue( 0.0 );
1123 spinAngle->setClearValue( 0.0 );
1124
1125 //make a temporary symbol for the size assistant preview
1126 mAssistantPreviewSymbol.reset( new QgsMarkerSymbol() );
1127
1128 if ( vectorLayer() )
1129 mSizeDDBtn->setSymbol( mAssistantPreviewSymbol );
1130
1131 int size = lstNames->iconSize().width();
1132 size = std::max( 30, static_cast< int >( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 3 ) ) );
1133 lstNames->setGridSize( QSize( size * 1.2, size * 1.2 ) );
1134 lstNames->setIconSize( QSize( size, size ) );
1135
1136 const double markerSize = size * 0.8;
1138 for ( const Qgis::MarkerShape shape : shapes )
1139 {
1140 QgsSimpleMarkerSymbolLayer *lyr = new QgsSimpleMarkerSymbolLayer( shape, markerSize );
1142 lyr->setColor( QColor( 200, 200, 200 ) );
1143 lyr->setStrokeColor( QColor( 0, 0, 0 ) );
1144 const QIcon icon = QgsSymbolLayerUtils::symbolLayerPreviewIcon( lyr, QgsUnitTypes::RenderPixels, QSize( size, size ) );
1145 QListWidgetItem *item = new QListWidgetItem( icon, QString(), lstNames );
1146 item->setData( Qt::UserRole, static_cast< int >( shape ) );
1147 item->setToolTip( QgsSimpleMarkerSymbolLayerBase::encodeShape( shape ) );
1148 delete lyr;
1149 }
1150 // show at least 3 rows
1151 lstNames->setMinimumHeight( lstNames->gridSize().height() * 3.1 );
1152
1153 connect( lstNames, &QListWidget::currentRowChanged, this, &QgsFilledMarkerSymbolLayerWidget::setShape );
1154 connect( spinSize, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setSize );
1155 connect( spinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setAngle );
1156 connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setOffset );
1157 connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setOffset );
1158 connect( this, &QgsSymbolLayerWidget::changed, this, &QgsFilledMarkerSymbolLayerWidget::updateAssistantSymbol );
1159}
1160
1162
1164{
1165 if ( layer->layerType() != QLatin1String( "FilledMarker" ) )
1166 return;
1167
1168 // layer type is correct, we can do the cast
1169 mLayer = static_cast<QgsFilledMarkerSymbolLayer *>( layer );
1170
1171 // set values
1172 const Qgis::MarkerShape shape = mLayer->shape();
1173 for ( int i = 0; i < lstNames->count(); ++i )
1174 {
1175 if ( static_cast< Qgis::MarkerShape >( lstNames->item( i )->data( Qt::UserRole ).toInt() ) == shape )
1176 {
1177 lstNames->setCurrentRow( i );
1178 break;
1179 }
1180 }
1181 whileBlocking( spinSize )->setValue( mLayer->size() );
1182 whileBlocking( spinAngle )->setValue( mLayer->angle() );
1183 whileBlocking( spinOffsetX )->setValue( mLayer->offset().x() );
1184 whileBlocking( spinOffsetY )->setValue( mLayer->offset().y() );
1185
1186 mSizeUnitWidget->blockSignals( true );
1187 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
1188 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
1189 mSizeUnitWidget->blockSignals( false );
1190 mOffsetUnitWidget->blockSignals( true );
1191 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1192 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1193 mOffsetUnitWidget->blockSignals( false );
1194
1195 //anchor points
1196 whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mLayer->horizontalAnchorPoint() );
1197 whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mLayer->verticalAnchorPoint() );
1198
1205
1206 updateAssistantSymbol();
1207}
1208
1210{
1211 return mLayer;
1212}
1213
1214void QgsFilledMarkerSymbolLayerWidget::setShape()
1215{
1216 mLayer->setShape( static_cast< Qgis::MarkerShape >( lstNames->currentItem()->data( Qt::UserRole ).toInt() ) );
1217 emit changed();
1218}
1219
1220void QgsFilledMarkerSymbolLayerWidget::setSize()
1221{
1222 mLayer->setSize( spinSize->value() );
1223 emit changed();
1224}
1225
1226void QgsFilledMarkerSymbolLayerWidget::setAngle()
1227{
1228 mLayer->setAngle( spinAngle->value() );
1229 emit changed();
1230}
1231
1232void QgsFilledMarkerSymbolLayerWidget::setOffset()
1233{
1234 mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1235 emit changed();
1236}
1237
1238void QgsFilledMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
1239{
1240 if ( mLayer )
1241 {
1242 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
1243 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
1244 emit changed();
1245 }
1246}
1247
1248void QgsFilledMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
1249{
1250 if ( mLayer )
1251 {
1252 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1253 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1254 emit changed();
1255 }
1256}
1257
1258void QgsFilledMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
1259{
1260 if ( mLayer )
1261 {
1263 emit changed();
1264 }
1265}
1266
1267void QgsFilledMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
1268{
1269 if ( mLayer )
1270 {
1272 emit changed();
1273 }
1274}
1275
1276void QgsFilledMarkerSymbolLayerWidget::updateAssistantSymbol()
1277{
1278 for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
1279 {
1280 mAssistantPreviewSymbol->deleteSymbolLayer( i );
1281 }
1282 mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
1284 if ( ddSize )
1285 mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
1286}
1287
1288
1290
1292 : QgsSymbolLayerWidget( parent, vl )
1293{
1294 mLayer = nullptr;
1295
1296 setupUi( this );
1297 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsGradientFillSymbolLayerWidget::mOffsetUnitWidget_changed );
1298 connect( mSpinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::mSpinAngle_valueChanged );
1301
1302 btnColorRamp->setShowGradientOnly( true );
1303
1304 btnChangeColor->setAllowOpacity( true );
1305 btnChangeColor->setColorDialogTitle( tr( "Select Gradient Color" ) );
1306 btnChangeColor->setContext( QStringLiteral( "symbology" ) );
1307 btnChangeColor->setShowNoColor( true );
1308 btnChangeColor->setNoColorString( tr( "Transparent" ) );
1309 btnChangeColor2->setAllowOpacity( true );
1310 btnChangeColor2->setColorDialogTitle( tr( "Select Gradient Color" ) );
1311 btnChangeColor2->setContext( QStringLiteral( "symbology" ) );
1312 btnChangeColor2->setShowNoColor( true );
1313 btnChangeColor2->setNoColorString( tr( "Transparent" ) );
1314
1315 mStartColorDDBtn->registerLinkedWidget( btnChangeColor );
1316 mEndColorDDBtn->registerLinkedWidget( btnChangeColor2 );
1317
1318 spinOffsetX->setClearValue( 0.0 );
1319 spinOffsetY->setClearValue( 0.0 );
1320 mSpinAngle->setClearValue( 0.0 );
1321
1325 connect( cboGradientType, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGradientFillSymbolLayerWidget::setGradientType );
1326 connect( cboCoordinateMode, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGradientFillSymbolLayerWidget::setCoordinateMode );
1327 connect( cboGradientSpread, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGradientFillSymbolLayerWidget::setGradientSpread );
1328 connect( radioTwoColor, &QAbstractButton::toggled, this, &QgsGradientFillSymbolLayerWidget::colorModeChanged );
1329 connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::offsetChanged );
1330 connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::offsetChanged );
1331 connect( spinRefPoint1X, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1332 connect( spinRefPoint1Y, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1333 connect( checkRefPoint1Centroid, &QAbstractButton::toggled, this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1334 connect( spinRefPoint2X, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1335 connect( spinRefPoint2Y, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1336 connect( checkRefPoint2Centroid, &QAbstractButton::toggled, this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1337}
1338
1340{
1341 if ( layer->layerType() != QLatin1String( "GradientFill" ) )
1342 return;
1343
1344 // layer type is correct, we can do the cast
1345 mLayer = static_cast<QgsGradientFillSymbolLayer *>( layer );
1346
1347 // set values
1348 btnChangeColor->blockSignals( true );
1349 btnChangeColor->setColor( mLayer->color() );
1350 btnChangeColor->blockSignals( false );
1351 btnChangeColor2->blockSignals( true );
1352 btnChangeColor2->setColor( mLayer->color2() );
1353 btnChangeColor2->blockSignals( false );
1354
1356 {
1357 radioTwoColor->setChecked( true );
1358 btnColorRamp->setEnabled( false );
1359 }
1360 else
1361 {
1362 radioColorRamp->setChecked( true );
1363 btnChangeColor->setEnabled( false );
1364 btnChangeColor2->setEnabled( false );
1365 }
1366
1367 // set source color ramp
1368 if ( mLayer->colorRamp() )
1369 {
1370 btnColorRamp->blockSignals( true );
1371 btnColorRamp->setColorRamp( mLayer->colorRamp() );
1372 btnColorRamp->blockSignals( false );
1373 }
1374
1375 cboGradientType->blockSignals( true );
1376 switch ( mLayer->gradientType() )
1377 {
1379 cboGradientType->setCurrentIndex( 0 );
1380 break;
1382 cboGradientType->setCurrentIndex( 1 );
1383 break;
1385 cboGradientType->setCurrentIndex( 2 );
1386 break;
1387 }
1388 cboGradientType->blockSignals( false );
1389
1390 cboCoordinateMode->blockSignals( true );
1391 switch ( mLayer->coordinateMode() )
1392 {
1394 cboCoordinateMode->setCurrentIndex( 1 );
1395 checkRefPoint1Centroid->setEnabled( false );
1396 checkRefPoint2Centroid->setEnabled( false );
1397 break;
1399 default:
1400 cboCoordinateMode->setCurrentIndex( 0 );
1401 break;
1402 }
1403 cboCoordinateMode->blockSignals( false );
1404
1405 cboGradientSpread->blockSignals( true );
1406 switch ( mLayer->gradientSpread() )
1407 {
1409 cboGradientSpread->setCurrentIndex( 0 );
1410 break;
1412 cboGradientSpread->setCurrentIndex( 1 );
1413 break;
1415 cboGradientSpread->setCurrentIndex( 2 );
1416 break;
1417 }
1418 cboGradientSpread->blockSignals( false );
1419
1420 spinRefPoint1X->blockSignals( true );
1421 spinRefPoint1X->setValue( mLayer->referencePoint1().x() );
1422 spinRefPoint1X->blockSignals( false );
1423 spinRefPoint1Y->blockSignals( true );
1424 spinRefPoint1Y->setValue( mLayer->referencePoint1().y() );
1425 spinRefPoint1Y->blockSignals( false );
1426 checkRefPoint1Centroid->blockSignals( true );
1427 checkRefPoint1Centroid->setChecked( mLayer->referencePoint1IsCentroid() );
1429 {
1430 spinRefPoint1X->setEnabled( false );
1431 spinRefPoint1Y->setEnabled( false );
1432 }
1433 checkRefPoint1Centroid->blockSignals( false );
1434 spinRefPoint2X->blockSignals( true );
1435 spinRefPoint2X->setValue( mLayer->referencePoint2().x() );
1436 spinRefPoint2X->blockSignals( false );
1437 spinRefPoint2Y->blockSignals( true );
1438 spinRefPoint2Y->setValue( mLayer->referencePoint2().y() );
1439 spinRefPoint2Y->blockSignals( false );
1440 checkRefPoint2Centroid->blockSignals( true );
1441 checkRefPoint2Centroid->setChecked( mLayer->referencePoint2IsCentroid() );
1443 {
1444 spinRefPoint2X->setEnabled( false );
1445 spinRefPoint2Y->setEnabled( false );
1446 }
1447 checkRefPoint2Centroid->blockSignals( false );
1448
1449 spinOffsetX->blockSignals( true );
1450 spinOffsetX->setValue( mLayer->offset().x() );
1451 spinOffsetX->blockSignals( false );
1452 spinOffsetY->blockSignals( true );
1453 spinOffsetY->setValue( mLayer->offset().y() );
1454 spinOffsetY->blockSignals( false );
1455 mSpinAngle->blockSignals( true );
1456 mSpinAngle->setValue( mLayer->angle() );
1457 mSpinAngle->blockSignals( false );
1458
1459 mOffsetUnitWidget->blockSignals( true );
1460 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1461 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1462 mOffsetUnitWidget->blockSignals( false );
1463
1477}
1478
1480{
1481 return mLayer;
1482}
1483
1485{
1486 mLayer->setColor( color );
1487 emit changed();
1488}
1489
1491{
1492 mLayer->setColor2( color );
1493 emit changed();
1494}
1495
1496void QgsGradientFillSymbolLayerWidget::colorModeChanged()
1497{
1498 if ( radioTwoColor->isChecked() )
1499 {
1501 }
1502 else
1503 {
1505 }
1506 emit changed();
1507}
1508
1510{
1511 if ( btnColorRamp->isNull() )
1512 return;
1513
1514 mLayer->setColorRamp( btnColorRamp->colorRamp()->clone() );
1515 emit changed();
1516}
1517
1519{
1520 switch ( index )
1521 {
1522 case 0:
1524 //set sensible default reference points
1525 spinRefPoint1X->setValue( 0.5 );
1526 spinRefPoint1Y->setValue( 0 );
1527 spinRefPoint2X->setValue( 0.5 );
1528 spinRefPoint2Y->setValue( 1 );
1529 break;
1530 case 1:
1532 //set sensible default reference points
1533 spinRefPoint1X->setValue( 0 );
1534 spinRefPoint1Y->setValue( 0 );
1535 spinRefPoint2X->setValue( 1 );
1536 spinRefPoint2Y->setValue( 1 );
1537 break;
1538 case 2:
1540 spinRefPoint1X->setValue( 0.5 );
1541 spinRefPoint1Y->setValue( 0.5 );
1542 spinRefPoint2X->setValue( 1 );
1543 spinRefPoint2Y->setValue( 1 );
1544 break;
1545 }
1546 emit changed();
1547}
1548
1550{
1551
1552 switch ( index )
1553 {
1554 case 0:
1555 //feature coordinate mode
1557 //allow choice of centroid reference positions
1558 checkRefPoint1Centroid->setEnabled( true );
1559 checkRefPoint2Centroid->setEnabled( true );
1560 break;
1561 case 1:
1562 //viewport coordinate mode
1564 //disable choice of centroid reference positions
1565 checkRefPoint1Centroid->setChecked( Qt::Unchecked );
1566 checkRefPoint1Centroid->setEnabled( false );
1567 checkRefPoint2Centroid->setChecked( Qt::Unchecked );
1568 checkRefPoint2Centroid->setEnabled( false );
1569 break;
1570 }
1571
1572 emit changed();
1573}
1574
1576{
1577 switch ( index )
1578 {
1579 case 0:
1581 break;
1582 case 1:
1584 break;
1585 case 2:
1587 break;
1588 }
1589
1590 emit changed();
1591}
1592
1593void QgsGradientFillSymbolLayerWidget::offsetChanged()
1594{
1595 mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1596 emit changed();
1597}
1598
1599void QgsGradientFillSymbolLayerWidget::referencePointChanged()
1600{
1601 mLayer->setReferencePoint1( QPointF( spinRefPoint1X->value(), spinRefPoint1Y->value() ) );
1602 mLayer->setReferencePoint1IsCentroid( checkRefPoint1Centroid->isChecked() );
1603 mLayer->setReferencePoint2( QPointF( spinRefPoint2X->value(), spinRefPoint2Y->value() ) );
1604 mLayer->setReferencePoint2IsCentroid( checkRefPoint2Centroid->isChecked() );
1605 emit changed();
1606}
1607
1608void QgsGradientFillSymbolLayerWidget::mSpinAngle_valueChanged( double value )
1609{
1610 mLayer->setAngle( value );
1611 emit changed();
1612}
1613
1614void QgsGradientFillSymbolLayerWidget::mOffsetUnitWidget_changed()
1615{
1616 if ( mLayer )
1617 {
1618 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1619 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1620 emit changed();
1621 }
1622}
1623
1625
1627 : QgsSymbolLayerWidget( parent, vl )
1628{
1629 mLayer = nullptr;
1630
1631 setupUi( this );
1632 connect( mSpinBlurRadius, qOverload< int >( &QSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::mSpinBlurRadius_valueChanged );
1633 connect( mSpinMaxDistance, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::mSpinMaxDistance_valueChanged );
1634 connect( mDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsShapeburstFillSymbolLayerWidget::mDistanceUnitWidget_changed );
1635 connect( mRadioUseWholeShape, &QRadioButton::toggled, this, &QgsShapeburstFillSymbolLayerWidget::mRadioUseWholeShape_toggled );
1636 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsShapeburstFillSymbolLayerWidget::mOffsetUnitWidget_changed );
1637 connect( mIgnoreRingsCheckBox, &QCheckBox::stateChanged, this, &QgsShapeburstFillSymbolLayerWidget::mIgnoreRingsCheckBox_stateChanged );
1642
1643 QButtonGroup *group1 = new QButtonGroup( this );
1644 group1->addButton( radioColorRamp );
1645 group1->addButton( radioTwoColor );
1646 QButtonGroup *group2 = new QButtonGroup( this );
1647 group2->addButton( mRadioUseMaxDistance );
1648 group2->addButton( mRadioUseWholeShape );
1649 btnChangeColor->setAllowOpacity( true );
1650 btnChangeColor->setColorDialogTitle( tr( "Select Gradient Color" ) );
1651 btnChangeColor->setContext( QStringLiteral( "symbology" ) );
1652 btnChangeColor->setShowNoColor( true );
1653 btnChangeColor->setNoColorString( tr( "Transparent" ) );
1654 btnChangeColor2->setAllowOpacity( true );
1655 btnChangeColor2->setColorDialogTitle( tr( "Select Gradient Color" ) );
1656 btnChangeColor2->setContext( QStringLiteral( "symbology" ) );
1657 btnChangeColor2->setShowNoColor( true );
1658 btnChangeColor2->setNoColorString( tr( "Transparent" ) );
1659
1660 mStartColorDDBtn->registerLinkedWidget( btnChangeColor );
1661 mEndColorDDBtn->registerLinkedWidget( btnChangeColor2 );
1662
1663 spinOffsetX->setClearValue( 0.0 );
1664 spinOffsetY->setClearValue( 0.0 );
1665 mSpinMaxDistance->setClearValue( 5.0 );
1666
1667 btnColorRamp->setShowGradientOnly( true );
1668
1669 connect( btnColorRamp, &QgsColorRampButton::colorRampChanged, this, &QgsShapeburstFillSymbolLayerWidget::applyColorRamp );
1670
1673 connect( radioTwoColor, &QAbstractButton::toggled, this, &QgsShapeburstFillSymbolLayerWidget::colorModeChanged );
1674 connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::offsetChanged );
1675 connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::offsetChanged );
1676
1677 connect( mBlurSlider, &QAbstractSlider::valueChanged, mSpinBlurRadius, &QSpinBox::setValue );
1678 connect( mSpinBlurRadius, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), mBlurSlider, &QAbstractSlider::setValue );
1679}
1680
1682{
1683 if ( layer->layerType() != QLatin1String( "ShapeburstFill" ) )
1684 return;
1685
1686 // layer type is correct, we can do the cast
1687 mLayer = static_cast<QgsShapeburstFillSymbolLayer *>( layer );
1688
1689 // set values
1690 btnChangeColor->blockSignals( true );
1691 btnChangeColor->setColor( mLayer->color() );
1692 btnChangeColor->blockSignals( false );
1693 btnChangeColor2->blockSignals( true );
1694 btnChangeColor2->setColor( mLayer->color2() );
1695 btnChangeColor2->blockSignals( false );
1696
1698 {
1699 radioTwoColor->setChecked( true );
1700 btnColorRamp->setEnabled( false );
1701 }
1702 else
1703 {
1704 radioColorRamp->setChecked( true );
1705 btnChangeColor->setEnabled( false );
1706 btnChangeColor2->setEnabled( false );
1707 }
1708
1709 mSpinBlurRadius->blockSignals( true );
1710 mBlurSlider->blockSignals( true );
1711 mSpinBlurRadius->setValue( mLayer->blurRadius() );
1712 mBlurSlider->setValue( mLayer->blurRadius() );
1713 mSpinBlurRadius->blockSignals( false );
1714 mBlurSlider->blockSignals( false );
1715
1716 mSpinMaxDistance->blockSignals( true );
1717 mSpinMaxDistance->setValue( mLayer->maxDistance() );
1718 mSpinMaxDistance->blockSignals( false );
1719
1720 mRadioUseWholeShape->blockSignals( true );
1721 mRadioUseMaxDistance->blockSignals( true );
1722 if ( mLayer->useWholeShape() )
1723 {
1724 mRadioUseWholeShape->setChecked( true );
1725 mSpinMaxDistance->setEnabled( false );
1726 mDistanceUnitWidget->setEnabled( false );
1727 }
1728 else
1729 {
1730 mRadioUseMaxDistance->setChecked( true );
1731 mSpinMaxDistance->setEnabled( true );
1732 mDistanceUnitWidget->setEnabled( true );
1733 }
1734 mRadioUseWholeShape->blockSignals( false );
1735 mRadioUseMaxDistance->blockSignals( false );
1736
1737 mDistanceUnitWidget->blockSignals( true );
1738 mDistanceUnitWidget->setUnit( mLayer->distanceUnit() );
1739 mDistanceUnitWidget->setMapUnitScale( mLayer->distanceMapUnitScale() );
1740 mDistanceUnitWidget->blockSignals( false );
1741
1742 mIgnoreRingsCheckBox->blockSignals( true );
1743 mIgnoreRingsCheckBox->setCheckState( mLayer->ignoreRings() ? Qt::Checked : Qt::Unchecked );
1744 mIgnoreRingsCheckBox->blockSignals( false );
1745
1746 // set source color ramp
1747 if ( mLayer->colorRamp() )
1748 {
1749 btnColorRamp->blockSignals( true );
1750 btnColorRamp->setColorRamp( mLayer->colorRamp() );
1751 btnColorRamp->blockSignals( false );
1752 }
1753
1754 spinOffsetX->blockSignals( true );
1755 spinOffsetX->setValue( mLayer->offset().x() );
1756 spinOffsetX->blockSignals( false );
1757 spinOffsetY->blockSignals( true );
1758 spinOffsetY->setValue( mLayer->offset().y() );
1759 spinOffsetY->blockSignals( false );
1760 mOffsetUnitWidget->blockSignals( true );
1761 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1762 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1763 mOffsetUnitWidget->blockSignals( false );
1764
1772}
1773
1775{
1776 return mLayer;
1777}
1778
1780{
1781 if ( mLayer )
1782 {
1783 mLayer->setColor( color );
1784 emit changed();
1785 }
1786}
1787
1789{
1790 if ( mLayer )
1791 {
1792 mLayer->setColor2( color );
1793 emit changed();
1794 }
1795}
1796
1797void QgsShapeburstFillSymbolLayerWidget::colorModeChanged()
1798{
1799 if ( !mLayer )
1800 {
1801 return;
1802 }
1803
1804 if ( radioTwoColor->isChecked() )
1805 {
1807 }
1808 else
1809 {
1811 }
1812 emit changed();
1813}
1814
1815void QgsShapeburstFillSymbolLayerWidget::mSpinBlurRadius_valueChanged( int value )
1816{
1817 if ( mLayer )
1818 {
1819 mLayer->setBlurRadius( value );
1820 emit changed();
1821 }
1822}
1823
1824void QgsShapeburstFillSymbolLayerWidget::mSpinMaxDistance_valueChanged( double value )
1825{
1826 if ( mLayer )
1827 {
1828 mLayer->setMaxDistance( value );
1829 emit changed();
1830 }
1831}
1832
1833void QgsShapeburstFillSymbolLayerWidget::mDistanceUnitWidget_changed()
1834{
1835 if ( mLayer )
1836 {
1837 mLayer->setDistanceUnit( mDistanceUnitWidget->unit() );
1838 mLayer->setDistanceMapUnitScale( mDistanceUnitWidget->getMapUnitScale() );
1839 emit changed();
1840 }
1841}
1842
1843void QgsShapeburstFillSymbolLayerWidget::mRadioUseWholeShape_toggled( bool value )
1844{
1845 if ( mLayer )
1846 {
1847 mLayer->setUseWholeShape( value );
1848 mDistanceUnitWidget->setEnabled( !value );
1849 emit changed();
1850 }
1851}
1852
1853void QgsShapeburstFillSymbolLayerWidget::applyColorRamp()
1854{
1855 QgsColorRamp *ramp = btnColorRamp->colorRamp();
1856 if ( !ramp )
1857 return;
1858
1859 mLayer->setColorRamp( ramp );
1860 emit changed();
1861}
1862
1863void QgsShapeburstFillSymbolLayerWidget::offsetChanged()
1864{
1865 if ( mLayer )
1866 {
1867 mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1868 emit changed();
1869 }
1870}
1871
1872void QgsShapeburstFillSymbolLayerWidget::mOffsetUnitWidget_changed()
1873{
1874 if ( mLayer )
1875 {
1876 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1877 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1878 emit changed();
1879 }
1880}
1881
1882
1883void QgsShapeburstFillSymbolLayerWidget::mIgnoreRingsCheckBox_stateChanged( int state )
1884{
1885 const bool checked = ( state == Qt::Checked );
1886 mLayer->setIgnoreRings( checked );
1887 emit changed();
1888}
1889
1891
1893 : QgsSymbolLayerWidget( parent, vl )
1894{
1895 mLayer = nullptr;
1896
1897 setupUi( this );
1898 connect( mIntervalUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsMarkerLineSymbolLayerWidget::mIntervalUnitWidget_changed );
1899 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsMarkerLineSymbolLayerWidget::mOffsetUnitWidget_changed );
1900 connect( mOffsetAlongLineUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsMarkerLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed );
1901 connect( mAverageAngleUnit, &QgsUnitSelectionWidget::changed, this, &QgsMarkerLineSymbolLayerWidget::averageAngleUnitChanged );
1910
1911 mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconAllRings.svg" ) ), tr( "All Rings" ), QgsLineSymbolLayer::AllRings );
1912 mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconExteriorRing.svg" ) ), tr( "Exterior Ring Only" ), QgsLineSymbolLayer::ExteriorRingOnly );
1913 mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconInteriorRings.svg" ) ), tr( "Interior Rings Only" ), QgsLineSymbolLayer::InteriorRingsOnly );
1914 connect( mRingFilterComboBox, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]( int )
1915 {
1916 if ( mLayer )
1917 {
1918 mLayer->setRingFilter( static_cast< QgsLineSymbolLayer::RenderRingFilter >( mRingFilterComboBox->currentData().toInt() ) );
1919 emit changed();
1920 }
1921 } );
1922
1923 spinOffset->setClearValue( 0.0 );
1924 mSpinOffsetAlongLine->setClearValue( 0.0 );
1925 mSpinAverageAngleLength->setClearValue( 4.0 );
1926
1927 connect( spinInterval, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsMarkerLineSymbolLayerWidget::setInterval );
1928 connect( mSpinOffsetAlongLine, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsMarkerLineSymbolLayerWidget::setOffsetAlongLine );
1929 connect( chkRotateMarker, &QAbstractButton::clicked, this, &QgsMarkerLineSymbolLayerWidget::setRotate );
1930 connect( spinOffset, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsMarkerLineSymbolLayerWidget::setOffset );
1931 connect( mSpinAverageAngleLength, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsMarkerLineSymbolLayerWidget::setAverageAngle );
1932 connect( mCheckInterval, &QCheckBox::toggled, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1933 connect( mCheckVertex, &QCheckBox::toggled, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1934 connect( mCheckVertexLast, &QCheckBox::toggled, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1935 connect( mCheckVertexFirst, &QCheckBox::toggled, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1936 connect( mCheckCentralPoint, &QCheckBox::toggled, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1937 connect( mCheckCurvePoint, &QCheckBox::toggled, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1938 connect( mCheckSegmentCentralPoint, &QCheckBox::toggled, this, &QgsMarkerLineSymbolLayerWidget::setPlacement );
1939 connect( mCheckPlaceOnEveryPart, &QCheckBox::toggled, this, [ = ]
1940 {
1941 if ( mLayer )
1942 {
1943 mLayer->setPlaceOnEveryPart( mCheckPlaceOnEveryPart->isChecked() );
1944 emit changed();
1945 }
1946 } );
1947}
1948
1950{
1951 if ( layer->layerType() != QLatin1String( "MarkerLine" ) )
1952 return;
1953
1954 // layer type is correct, we can do the cast
1955 mLayer = static_cast<QgsMarkerLineSymbolLayer *>( layer );
1956
1957 // set values
1958 spinInterval->blockSignals( true );
1959 spinInterval->setValue( mLayer->interval() );
1960 spinInterval->blockSignals( false );
1961 mSpinOffsetAlongLine->blockSignals( true );
1962 mSpinOffsetAlongLine->setValue( mLayer->offsetAlongLine() );
1963 mSpinOffsetAlongLine->blockSignals( false );
1964 chkRotateMarker->blockSignals( true );
1965 chkRotateMarker->setChecked( mLayer->rotateSymbols() );
1966 chkRotateMarker->blockSignals( false );
1967 spinOffset->blockSignals( true );
1968 spinOffset->setValue( mLayer->offset() );
1969 spinOffset->blockSignals( false );
1970
1971 whileBlocking( mCheckInterval )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::Interval );
1974 whileBlocking( mCheckVertexFirst )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::FirstVertex
1976 whileBlocking( mCheckVertexLast )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::LastVertex
1978 whileBlocking( mCheckCentralPoint )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::CentralPoint );
1979 whileBlocking( mCheckCurvePoint )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::CurvePoint );
1980 whileBlocking( mCheckSegmentCentralPoint )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::SegmentCenter );
1981 whileBlocking( mCheckPlaceOnEveryPart )->setChecked( mLayer->placeOnEveryPart() );
1982
1983 // set units
1984 mIntervalUnitWidget->blockSignals( true );
1985 mIntervalUnitWidget->setUnit( mLayer->intervalUnit() );
1986 mIntervalUnitWidget->setMapUnitScale( mLayer->intervalMapUnitScale() );
1987 mIntervalUnitWidget->blockSignals( false );
1988 mOffsetUnitWidget->blockSignals( true );
1989 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1990 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1991 mOffsetUnitWidget->blockSignals( false );
1992 mOffsetAlongLineUnitWidget->blockSignals( true );
1993 mOffsetAlongLineUnitWidget->setUnit( mLayer->offsetAlongLineUnit() );
1994 mOffsetAlongLineUnitWidget->setMapUnitScale( mLayer->offsetAlongLineMapUnitScale() );
1995 mOffsetAlongLineUnitWidget->blockSignals( false );
1996
1997 whileBlocking( mAverageAngleUnit )->setUnit( mLayer->averageAngleUnit() );
1998 whileBlocking( mAverageAngleUnit )->setMapUnitScale( mLayer->averageAngleMapUnitScale() );
1999 whileBlocking( mSpinAverageAngleLength )->setValue( mLayer->averageAngleLength() );
2000
2001 whileBlocking( mRingFilterComboBox )->setCurrentIndex( mRingFilterComboBox->findData( mLayer->ringFilter() ) );
2002
2003 setPlacement(); // update gui
2004
2010}
2011
2013{
2014 return mLayer;
2015}
2016
2018{
2020
2021 switch ( context.symbolType() )
2022 {
2025 //these settings only have an effect when the symbol layers is part of a fill symbol
2026 mRingFilterComboBox->hide();
2027 mRingsLabel->hide();
2028 break;
2029
2032 break;
2033 }
2034}
2035
2037{
2038 mLayer->setInterval( val );
2039 emit changed();
2040}
2041
2043{
2044 mLayer->setOffsetAlongLine( val );
2045 emit changed();
2046}
2047
2048void QgsMarkerLineSymbolLayerWidget::setRotate()
2049{
2050 mSpinAverageAngleLength->setEnabled( chkRotateMarker->isChecked() && ( mCheckInterval->isChecked() || mCheckCentralPoint->isChecked() ) );
2051 mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
2052
2053 mLayer->setRotateSymbols( chkRotateMarker->isChecked() );
2054 emit changed();
2055}
2056
2057void QgsMarkerLineSymbolLayerWidget::setOffset()
2058{
2059 mLayer->setOffset( spinOffset->value() );
2060 emit changed();
2061}
2062
2063void QgsMarkerLineSymbolLayerWidget::setPlacement()
2064{
2065 const bool interval = mCheckInterval->isChecked();
2066 spinInterval->setEnabled( interval );
2067 mSpinOffsetAlongLine->setEnabled( mCheckInterval->isChecked() || mCheckVertexLast->isChecked() || mCheckVertexFirst->isChecked() );
2068 mOffsetAlongLineUnitWidget->setEnabled( mSpinOffsetAlongLine->isEnabled() );
2069 mSpinAverageAngleLength->setEnabled( chkRotateMarker->isChecked() && ( mCheckInterval->isChecked() || mCheckCentralPoint->isChecked() ) );
2070 mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
2071 mCheckPlaceOnEveryPart->setEnabled( mCheckVertexLast->isChecked() || mCheckVertexFirst->isChecked() );
2072
2073 Qgis::MarkerLinePlacements placements;
2074 if ( mCheckInterval->isChecked() )
2076 if ( mCheckVertex->isChecked() )
2078 if ( mCheckVertexLast->isChecked() )
2080 if ( mCheckVertexFirst->isChecked() )
2082 if ( mCheckCurvePoint->isChecked() )
2084 if ( mCheckSegmentCentralPoint->isChecked() )
2086 if ( mCheckCentralPoint->isChecked() )
2088 mLayer->setPlacements( placements );
2089
2090 emit changed();
2091}
2092
2093void QgsMarkerLineSymbolLayerWidget::mIntervalUnitWidget_changed()
2094{
2095 if ( mLayer )
2096 {
2097 mLayer->setIntervalUnit( mIntervalUnitWidget->unit() );
2098 mLayer->setIntervalMapUnitScale( mIntervalUnitWidget->getMapUnitScale() );
2099 emit changed();
2100 }
2101}
2102
2103void QgsMarkerLineSymbolLayerWidget::mOffsetUnitWidget_changed()
2104{
2105 if ( mLayer )
2106 {
2107 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
2108 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
2109 emit changed();
2110 }
2111}
2112
2113void QgsMarkerLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed()
2114{
2115 if ( mLayer )
2116 {
2117 mLayer->setOffsetAlongLineUnit( mOffsetAlongLineUnitWidget->unit() );
2118 mLayer->setOffsetAlongLineMapUnitScale( mOffsetAlongLineUnitWidget->getMapUnitScale() );
2119 }
2120 emit changed();
2121}
2122
2123void QgsMarkerLineSymbolLayerWidget::averageAngleUnitChanged()
2124{
2125 if ( mLayer )
2126 {
2127 mLayer->setAverageAngleUnit( mAverageAngleUnit->unit() );
2128 mLayer->setAverageAngleMapUnitScale( mAverageAngleUnit->getMapUnitScale() );
2129 }
2130 emit changed();
2131}
2132
2133void QgsMarkerLineSymbolLayerWidget::setAverageAngle( double val )
2134{
2135 if ( mLayer )
2136 {
2138 emit changed();
2139 }
2140}
2141
2142
2144
2146 : QgsSymbolLayerWidget( parent, vl )
2147{
2148 mLayer = nullptr;
2149
2150 setupUi( this );
2151 connect( mIntervalUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::mIntervalUnitWidget_changed );
2152 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::mOffsetUnitWidget_changed );
2153 connect( mOffsetAlongLineUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed );
2154 connect( mAverageAngleUnit, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::averageAngleUnitChanged );
2155 connect( mHashLengthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::hashLengthUnitWidgetChanged );
2166
2167 mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconAllRings.svg" ) ), tr( "All Rings" ), QgsLineSymbolLayer::AllRings );
2168 mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconExteriorRing.svg" ) ), tr( "Exterior Ring Only" ), QgsLineSymbolLayer::ExteriorRingOnly );
2169 mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconInteriorRings.svg" ) ), tr( "Interior Rings Only" ), QgsLineSymbolLayer::InteriorRingsOnly );
2170 connect( mRingFilterComboBox, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]( int )
2171 {
2172 if ( mLayer )
2173 {
2174 mLayer->setRingFilter( static_cast< QgsLineSymbolLayer::RenderRingFilter >( mRingFilterComboBox->currentData().toInt() ) );
2175 emit changed();
2176 }
2177 } );
2178
2179 spinOffset->setClearValue( 0.0 );
2180 mSpinOffsetAlongLine->setClearValue( 0.0 );
2181 mHashRotationSpinBox->setClearValue( 0 );
2182 mSpinAverageAngleLength->setClearValue( 4.0 );
2183
2184 connect( spinInterval, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setInterval );
2185 connect( mSpinOffsetAlongLine, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setOffsetAlongLine );
2186 connect( mSpinHashLength, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setHashLength );
2187 connect( mHashRotationSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setHashAngle );
2188 connect( chkRotateMarker, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setRotate );
2189 connect( spinOffset, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setOffset );
2190 connect( mSpinAverageAngleLength, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setAverageAngle );
2191
2192 connect( mCheckInterval, &QCheckBox::toggled, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2193 connect( mCheckVertex, &QCheckBox::toggled, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2194 connect( mCheckVertexLast, &QCheckBox::toggled, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2195 connect( mCheckVertexFirst, &QCheckBox::toggled, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2196 connect( mCheckCentralPoint, &QCheckBox::toggled, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2197 connect( mCheckCurvePoint, &QCheckBox::toggled, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2198 connect( mCheckSegmentCentralPoint, &QCheckBox::toggled, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
2199
2200 connect( mCheckPlaceOnEveryPart, &QCheckBox::toggled, this, [ = ]
2201 {
2202 if ( mLayer )
2203 {
2204 mLayer->setPlaceOnEveryPart( mCheckPlaceOnEveryPart->isChecked() );
2205 emit changed();
2206 }
2207 } );
2208}
2209
2211{
2212 if ( layer->layerType() != QLatin1String( "HashLine" ) )
2213 return;
2214
2215 // layer type is correct, we can do the cast
2216 mLayer = static_cast<QgsHashedLineSymbolLayer *>( layer );
2217
2218 // set values
2219 spinInterval->blockSignals( true );
2220 spinInterval->setValue( mLayer->interval() );
2221 spinInterval->blockSignals( false );
2222 mSpinOffsetAlongLine->blockSignals( true );
2223 mSpinOffsetAlongLine->setValue( mLayer->offsetAlongLine() );
2224 mSpinOffsetAlongLine->blockSignals( false );
2225 whileBlocking( mSpinHashLength )->setValue( mLayer->hashLength() );
2226 whileBlocking( mHashRotationSpinBox )->setValue( mLayer->hashAngle() );
2227 chkRotateMarker->blockSignals( true );
2228 chkRotateMarker->setChecked( mLayer->rotateSymbols() );
2229 chkRotateMarker->blockSignals( false );
2230 spinOffset->blockSignals( true );
2231 spinOffset->setValue( mLayer->offset() );
2232 spinOffset->blockSignals( false );
2233
2234 whileBlocking( mCheckInterval )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::Interval );
2235 whileBlocking( mCheckVertex )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::InnerVertices
2237 whileBlocking( mCheckVertexFirst )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::FirstVertex
2239 whileBlocking( mCheckVertexLast )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::LastVertex
2241 whileBlocking( mCheckCentralPoint )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::CentralPoint );
2242 whileBlocking( mCheckCurvePoint )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::CurvePoint );
2243 whileBlocking( mCheckSegmentCentralPoint )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::SegmentCenter );
2244 whileBlocking( mCheckPlaceOnEveryPart )->setChecked( mLayer->placeOnEveryPart() );
2245
2246 // set units
2247 mIntervalUnitWidget->blockSignals( true );
2248 mIntervalUnitWidget->setUnit( mLayer->intervalUnit() );
2249 mIntervalUnitWidget->setMapUnitScale( mLayer->intervalMapUnitScale() );
2250 mIntervalUnitWidget->blockSignals( false );
2251 mOffsetUnitWidget->blockSignals( true );
2252 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
2253 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
2254 mOffsetUnitWidget->blockSignals( false );
2255 mOffsetAlongLineUnitWidget->blockSignals( true );
2256 mOffsetAlongLineUnitWidget->setUnit( mLayer->offsetAlongLineUnit() );
2257 mOffsetAlongLineUnitWidget->setMapUnitScale( mLayer->offsetAlongLineMapUnitScale() );
2258 mOffsetAlongLineUnitWidget->blockSignals( false );
2259 whileBlocking( mAverageAngleUnit )->setUnit( mLayer->averageAngleUnit() );
2260 whileBlocking( mAverageAngleUnit )->setMapUnitScale( mLayer->averageAngleMapUnitScale() );
2261 whileBlocking( mSpinAverageAngleLength )->setValue( mLayer->averageAngleLength() );
2262 whileBlocking( mHashLengthUnitWidget )->setUnit( mLayer->hashLengthUnit() );
2263 whileBlocking( mHashLengthUnitWidget )->setMapUnitScale( mLayer->hashLengthMapUnitScale() );
2264
2265 whileBlocking( mRingFilterComboBox )->setCurrentIndex( mRingFilterComboBox->findData( mLayer->ringFilter() ) );
2266
2267 setPlacement(); // update gui
2268
2276}
2277
2279{
2280 return mLayer;
2281}
2282
2284{
2286
2287 switch ( context.symbolType() )
2288 {
2291 //these settings only have an effect when the symbol layers is part of a fill symbol
2292 mRingFilterComboBox->hide();
2293 mRingsLabel->hide();
2294 break;
2295
2298 break;
2299 }
2300}
2301
2302void QgsHashedLineSymbolLayerWidget::setInterval( double val )
2303{
2304 mLayer->setInterval( val );
2305 emit changed();
2306}
2307
2308void QgsHashedLineSymbolLayerWidget::setOffsetAlongLine( double val )
2309{
2310 mLayer->setOffsetAlongLine( val );
2311 emit changed();
2312}
2313
2314void QgsHashedLineSymbolLayerWidget::setHashLength( double val )
2315{
2316 mLayer->setHashLength( val );
2317 emit changed();
2318}
2319
2320void QgsHashedLineSymbolLayerWidget::setHashAngle( double val )
2321{
2322 mLayer->setHashAngle( val );
2323 emit changed();
2324}
2325
2326void QgsHashedLineSymbolLayerWidget::setRotate()
2327{
2328 mSpinAverageAngleLength->setEnabled( chkRotateMarker->isChecked() && ( mCheckInterval->isChecked() || mCheckCentralPoint->isChecked() ) );
2329 mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
2330
2331 mLayer->setRotateSymbols( chkRotateMarker->isChecked() );
2332 emit changed();
2333}
2334
2335void QgsHashedLineSymbolLayerWidget::setOffset()
2336{
2337 mLayer->setOffset( spinOffset->value() );
2338 emit changed();
2339}
2340
2341void QgsHashedLineSymbolLayerWidget::setPlacement()
2342{
2343 const bool interval = mCheckInterval->isChecked();
2344 spinInterval->setEnabled( interval );
2345 mSpinOffsetAlongLine->setEnabled( mCheckInterval->isChecked() || mCheckVertexLast->isChecked() || mCheckVertexFirst->isChecked() );
2346 mOffsetAlongLineUnitWidget->setEnabled( mSpinOffsetAlongLine->isEnabled() );
2347 mSpinAverageAngleLength->setEnabled( chkRotateMarker->isChecked() && ( mCheckInterval->isChecked() || mCheckCentralPoint->isChecked() ) );
2348 mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
2349 mCheckPlaceOnEveryPart->setEnabled( mCheckVertexLast->isChecked() || mCheckVertexFirst->isChecked() );
2350
2351 Qgis::MarkerLinePlacements placements;
2352 if ( mCheckInterval->isChecked() )
2354 if ( mCheckVertex->isChecked() )
2356 if ( mCheckVertexLast->isChecked() )
2358 if ( mCheckVertexFirst->isChecked() )
2360 if ( mCheckCurvePoint->isChecked() )
2362 if ( mCheckSegmentCentralPoint->isChecked() )
2364 if ( mCheckCentralPoint->isChecked() )
2366 mLayer->setPlacements( placements );
2367
2368 emit changed();
2369}
2370
2371void QgsHashedLineSymbolLayerWidget::mIntervalUnitWidget_changed()
2372{
2373 if ( mLayer )
2374 {
2375 mLayer->setIntervalUnit( mIntervalUnitWidget->unit() );
2376 mLayer->setIntervalMapUnitScale( mIntervalUnitWidget->getMapUnitScale() );
2377 emit changed();
2378 }
2379}
2380
2381void QgsHashedLineSymbolLayerWidget::mOffsetUnitWidget_changed()
2382{
2383 if ( mLayer )
2384 {
2385 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
2386 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
2387 emit changed();
2388 }
2389}
2390
2391void QgsHashedLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed()
2392{
2393 if ( mLayer )
2394 {
2395 mLayer->setOffsetAlongLineUnit( mOffsetAlongLineUnitWidget->unit() );
2396 mLayer->setOffsetAlongLineMapUnitScale( mOffsetAlongLineUnitWidget->getMapUnitScale() );
2397 }
2398 emit changed();
2399}
2400
2401void QgsHashedLineSymbolLayerWidget::hashLengthUnitWidgetChanged()
2402{
2403 if ( mLayer )
2404 {
2405 mLayer->setHashLengthUnit( mHashLengthUnitWidget->unit() );
2406 mLayer->setHashLengthMapUnitScale( mHashLengthUnitWidget->getMapUnitScale() );
2407 }
2408 emit changed();
2409}
2410
2411void QgsHashedLineSymbolLayerWidget::averageAngleUnitChanged()
2412{
2413 if ( mLayer )
2414 {
2415 mLayer->setAverageAngleUnit( mAverageAngleUnit->unit() );
2416 mLayer->setAverageAngleMapUnitScale( mAverageAngleUnit->getMapUnitScale() );
2417 }
2418 emit changed();
2419}
2420
2421void QgsHashedLineSymbolLayerWidget::setAverageAngle( double val )
2422{
2423 if ( mLayer )
2424 {
2425 mLayer->setAverageAngleLength( val );
2426 emit changed();
2427 }
2428}
2429
2431
2432
2434 : QgsSymbolLayerWidget( parent, vl )
2435{
2436 mLayer = nullptr;
2437
2438 setupUi( this );
2439
2440 mSvgSelectorWidget->setAllowParameters( true );
2441 mSvgSelectorWidget->sourceLineEdit()->setPropertyOverrideToolButtonVisible( true );
2442 mSvgSelectorWidget->sourceLineEdit()->setLastPathSettingsKey( QStringLiteral( "/UI/lastSVGMarkerDir" ) );
2443 mSvgSelectorWidget->initParametersModel( this, vl );
2444
2445 connect( mSvgSelectorWidget->sourceLineEdit(), &QgsSvgSourceLineEdit::sourceChanged, this, &QgsSvgMarkerSymbolLayerWidget::svgSourceChanged );
2446 connect( mChangeColorButton, &QgsColorButton::colorChanged, this, &QgsSvgMarkerSymbolLayerWidget::mChangeColorButton_colorChanged );
2447 connect( mChangeStrokeColorButton, &QgsColorButton::colorChanged, this, &QgsSvgMarkerSymbolLayerWidget::mChangeStrokeColorButton_colorChanged );
2448 connect( mStrokeWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
2449 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
2450 connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
2451 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
2452 connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSvgMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
2453 connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSvgMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
2460 mChangeColorButton->setAllowOpacity( true );
2461 mChangeColorButton->setColorDialogTitle( tr( "Select Fill color" ) );
2462 mChangeColorButton->setContext( QStringLiteral( "symbology" ) );
2463 mChangeStrokeColorButton->setAllowOpacity( true );
2464 mChangeStrokeColorButton->setColorDialogTitle( tr( "Select Stroke Color" ) );
2465 mChangeStrokeColorButton->setContext( QStringLiteral( "symbology" ) );
2466
2467 mFillColorDDBtn->registerLinkedWidget( mChangeColorButton );
2468 mStrokeColorDDBtn->registerLinkedWidget( mChangeStrokeColorButton );
2469
2470 spinOffsetX->setClearValue( 0.0 );
2471 spinOffsetY->setClearValue( 0.0 );
2472 spinAngle->setClearValue( 0.0 );
2473
2474 connect( spinWidth, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setWidth );
2475 connect( spinHeight, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setHeight );
2476 connect( mLockAspectRatio, static_cast < void ( QgsRatioLockButton::* )( bool ) > ( &QgsRatioLockButton::lockChanged ), this, &QgsSvgMarkerSymbolLayerWidget::lockAspectRatioChanged );
2477 connect( spinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setAngle );
2478 connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setOffset );
2479 connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setOffset );
2480 connect( this, &QgsSymbolLayerWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::updateAssistantSymbol );
2481
2484
2485 //make a temporary symbol for the size assistant preview
2486 mAssistantPreviewSymbol.reset( new QgsMarkerSymbol() );
2487
2488 if ( vectorLayer() )
2489 {
2490 mWidthDDBtn->setSymbol( mAssistantPreviewSymbol );
2491 mHeightDDBtn->setSymbol( mAssistantPreviewSymbol );
2492 }
2493}
2494
2496
2497#include <QTime>
2498#include <QAbstractListModel>
2499#include <QPixmapCache>
2500#include <QStyle>
2501
2502
2503
2504
2506{
2507 if ( !layer )
2508 {
2509 return;
2510 }
2511
2512 //activate gui for svg parameters only if supported by the svg file
2513 bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2514 QColor defaultFill, defaultStroke;
2515 double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2516 bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
2517 QgsApplication::svgCache()->containsParams( layer->path(), hasFillParam, hasDefaultFillColor, defaultFill,
2518 hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity,
2519 hasStrokeParam, hasDefaultStrokeColor, defaultStroke,
2520 hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth,
2521 hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
2522 mChangeColorButton->setEnabled( hasFillParam );
2523 mChangeColorButton->setAllowOpacity( hasFillOpacityParam );
2524 mChangeStrokeColorButton->setEnabled( hasStrokeParam );
2525 mChangeStrokeColorButton->setAllowOpacity( hasStrokeOpacityParam );
2526 mStrokeWidthSpinBox->setEnabled( hasStrokeWidthParam );
2527
2528 if ( hasFillParam )
2529 {
2530 QColor fill = layer->fillColor();
2531 const double existingOpacity = hasFillOpacityParam ? fill.alphaF() : 1.0;
2532 if ( hasDefaultFillColor && !skipDefaultColors )
2533 {
2534 fill = defaultFill;
2535 }
2536 fill.setAlphaF( hasDefaultFillOpacity ? defaultFillOpacity : existingOpacity );
2537 mChangeColorButton->setColor( fill );
2538 }
2539 if ( hasStrokeParam )
2540 {
2541 QColor stroke = layer->strokeColor();
2542 const double existingOpacity = hasStrokeOpacityParam ? stroke.alphaF() : 1.0;
2543 if ( hasDefaultStrokeColor && !skipDefaultColors )
2544 {
2545 stroke = defaultStroke;
2546 }
2547 stroke.setAlphaF( hasDefaultStrokeOpacity ? defaultStrokeOpacity : existingOpacity );
2548 mChangeStrokeColorButton->setColor( stroke );
2549 }
2550
2551 whileBlocking( mSvgSelectorWidget->sourceLineEdit() )->setSource( layer->path() );
2552
2553 mStrokeWidthSpinBox->blockSignals( true );
2554 mStrokeWidthSpinBox->setValue( hasDefaultStrokeWidth ? defaultStrokeWidth : layer->strokeWidth() );
2555 mStrokeWidthSpinBox->blockSignals( false );
2556
2557 const bool preservedAspectRatio = layer->preservedAspectRatio();
2558 spinHeight->blockSignals( true );
2559 if ( preservedAspectRatio )
2560 {
2561 spinHeight->setValue( layer->size() * layer->defaultAspectRatio() );
2562 }
2563 else
2564 {
2565 spinHeight->setValue( layer->size() * layer->fixedAspectRatio() );
2566 }
2567 spinHeight->setEnabled( layer->defaultAspectRatio() > 0.0 );
2568 spinHeight->blockSignals( false );
2569 whileBlocking( mLockAspectRatio )->setLocked( preservedAspectRatio );
2570}
2571
2572void QgsSvgMarkerSymbolLayerWidget::updateAssistantSymbol()
2573{
2574 for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
2575 {
2576 mAssistantPreviewSymbol->deleteSymbolLayer( i );
2577 }
2578 mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
2580 if ( ddSize )
2581 mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
2582}
2583
2584
2586{
2587 if ( !layer )
2588 {
2589 return;
2590 }
2591
2592 if ( layer->layerType() != QLatin1String( "SvgMarker" ) )
2593 return;
2594
2595 // layer type is correct, we can do the cast
2596 mLayer = static_cast<QgsSvgMarkerSymbolLayer *>( layer );
2597
2598 // set values
2599 mSvgSelectorWidget->setSvgPath( mLayer->path() );
2600 mSvgSelectorWidget->setSvgParameters( mLayer->parameters() );
2601
2602 spinWidth->blockSignals( true );
2603 spinWidth->setValue( mLayer->size() );
2604 spinWidth->blockSignals( false );
2605 spinAngle->blockSignals( true );
2606 spinAngle->setValue( mLayer->angle() );
2607 spinAngle->blockSignals( false );
2608
2609 // without blocking signals the value gets changed because of slot setOffset()
2610 spinOffsetX->blockSignals( true );
2611 spinOffsetX->setValue( mLayer->offset().x() );
2612 spinOffsetX->blockSignals( false );
2613 spinOffsetY->blockSignals( true );
2614 spinOffsetY->setValue( mLayer->offset().y() );
2615 spinOffsetY->blockSignals( false );
2616
2617 mSizeUnitWidget->blockSignals( true );
2618 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
2619 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
2620 mSizeUnitWidget->blockSignals( false );
2621 mStrokeWidthUnitWidget->blockSignals( true );
2622 mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
2623 mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
2624 mStrokeWidthUnitWidget->blockSignals( false );
2625 mOffsetUnitWidget->blockSignals( true );
2626 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
2627 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
2628 mOffsetUnitWidget->blockSignals( false );
2629
2630 //anchor points
2631 mHorizontalAnchorComboBox->blockSignals( true );
2632 mVerticalAnchorComboBox->blockSignals( true );
2633 mHorizontalAnchorComboBox->setCurrentIndex( mLayer->horizontalAnchorPoint() );
2634 mVerticalAnchorComboBox->setCurrentIndex( mLayer->verticalAnchorPoint() );
2635 mHorizontalAnchorComboBox->blockSignals( false );
2636 mVerticalAnchorComboBox->blockSignals( false );
2637
2638 setGuiForSvg( mLayer, true );
2639
2649
2650 registerDataDefinedButton( mSvgSelectorWidget->sourceLineEdit()->propertyOverrideToolButton(), QgsSymbolLayer::PropertyName );
2651
2652 updateAssistantSymbol();
2653}
2654
2656{
2657 return mLayer;
2658}
2659
2661{
2663 mSvgSelectorWidget->sourceLineEdit()->setMessageBar( context.messageBar() );
2664}
2665
2667{
2668 mLayer->setPath( name );
2669 whileBlocking( mSvgSelectorWidget->sourceLineEdit() )->setSource( name );
2670
2672 emit changed();
2673}
2674
2675void QgsSvgMarkerSymbolLayerWidget::setSvgParameters( const QMap<QString, QgsProperty> &parameters )
2676{
2677 mLayer->setParameters( parameters );
2678 whileBlocking( mSvgSelectorWidget )->setSvgParameters( parameters );
2679
2681 emit changed();
2682}
2683
2684void QgsSvgMarkerSymbolLayerWidget::setWidth()
2685{
2686 const double defaultAspectRatio = mLayer->defaultAspectRatio();
2687 double fixedAspectRatio = 0.0;
2688 spinHeight->blockSignals( true );
2689 if ( defaultAspectRatio <= 0.0 )
2690 {
2691 spinHeight->setValue( spinWidth->value() );
2692 }
2693 else if ( mLockAspectRatio->locked() )
2694 {
2695 spinHeight->setValue( spinWidth->value() * defaultAspectRatio );
2696 }
2697 else
2698 {
2699 fixedAspectRatio = spinHeight->value() / spinWidth->value();
2700 }
2701 spinHeight->blockSignals( false );
2702 mLayer->setSize( spinWidth->value() );
2703 mLayer->setFixedAspectRatio( fixedAspectRatio );
2704 emit changed();
2705}
2706
2707void QgsSvgMarkerSymbolLayerWidget::setHeight()
2708{
2709 const double defaultAspectRatio = mLayer->defaultAspectRatio();
2710 double fixedAspectRatio = 0.0;
2711 spinWidth->blockSignals( true );
2712 if ( defaultAspectRatio <= 0.0 )
2713 {
2714 spinWidth->setValue( spinHeight->value() );
2715 }
2716 else if ( mLockAspectRatio->locked() )
2717 {
2718 spinWidth->setValue( spinHeight->value() / defaultAspectRatio );
2719 }
2720 else
2721 {
2722 fixedAspectRatio = spinHeight->value() / spinWidth->value();
2723 }
2724 spinWidth->blockSignals( false );
2725 mLayer->setSize( spinWidth->value() );
2726 mLayer->setFixedAspectRatio( fixedAspectRatio );
2727 emit changed();
2728}
2729
2730void QgsSvgMarkerSymbolLayerWidget::lockAspectRatioChanged( const bool locked )
2731{
2732 //spinHeight->setEnabled( !locked );
2733 const double defaultAspectRatio = mLayer->defaultAspectRatio();
2734 if ( defaultAspectRatio <= 0.0 )
2735 {
2736 whileBlocking( mLockAspectRatio )->setLocked( true );
2737 }
2738 else if ( locked )
2739 {
2741 setWidth();
2742 }
2743 else
2744 {
2745 mLayer->setFixedAspectRatio( spinHeight->value() / spinWidth->value() );
2746 }
2747 //emit changed();
2748}
2749
2750void QgsSvgMarkerSymbolLayerWidget::setAngle()
2751{
2752 mLayer->setAngle( spinAngle->value() );
2753 emit changed();
2754}
2755
2756void QgsSvgMarkerSymbolLayerWidget::setOffset()
2757{
2758 mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
2759 emit changed();
2760}
2761
2762void QgsSvgMarkerSymbolLayerWidget::svgSourceChanged( const QString &text )
2763{
2764 mLayer->setPath( text );
2766 emit changed();
2767}
2768
2769void QgsSvgMarkerSymbolLayerWidget::mChangeColorButton_colorChanged( const QColor &color )
2770{
2771 if ( !mLayer )
2772 {
2773 return;
2774 }
2775
2776 mLayer->setFillColor( color );
2777 emit changed();
2778}
2779
2780void QgsSvgMarkerSymbolLayerWidget::mChangeStrokeColorButton_colorChanged( const QColor &color )
2781{
2782 if ( !mLayer )
2783 {
2784 return;
2785 }
2786
2787 mLayer->setStrokeColor( color );
2788 emit changed();
2789}
2790
2791void QgsSvgMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
2792{
2793 if ( mLayer )
2794 {
2795 mLayer->setStrokeWidth( d );
2796 emit changed();
2797 }
2798}
2799
2800void QgsSvgMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
2801{
2802 if ( mLayer )
2803 {
2804 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
2805 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
2806 emit changed();
2807 }
2808}
2809
2810void QgsSvgMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
2811{
2812 if ( mLayer )
2813 {
2814 mLayer->setStrokeWidthUnit( mStrokeWidthUnitWidget->unit() );
2815 mLayer->setStrokeWidthMapUnitScale( mStrokeWidthUnitWidget->getMapUnitScale() );
2816 emit changed();
2817 }
2818}
2819
2820void QgsSvgMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
2821{
2822 if ( mLayer )
2823 {
2824 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
2825 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
2826 emit changed();
2827 }
2828}
2829
2830void QgsSvgMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
2831{
2832 if ( mLayer )
2833 {
2835 emit changed();
2836 }
2837}
2838
2839void QgsSvgMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
2840{
2841 if ( mLayer )
2842 {
2844 emit changed();
2845 }
2846}
2847
2849
2851{
2852 mLayer = nullptr;
2853 setupUi( this );
2854
2855 mSvgSelectorWidget->setAllowParameters( true );
2856 mSvgSelectorWidget->sourceLineEdit()->setPropertyOverrideToolButtonVisible( true );
2857
2858 connect( mTextureWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mTextureWidthSpinBox_valueChanged );
2859 connect( mSvgSelectorWidget->sourceLineEdit(), &QgsSvgSourceLineEdit::sourceChanged, this, &QgsSVGFillSymbolLayerWidget::svgSourceChanged );
2860 connect( mRotationSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mRotationSpinBox_valueChanged );
2861 connect( mChangeColorButton, &QgsColorButton::colorChanged, this, &QgsSVGFillSymbolLayerWidget::mChangeColorButton_colorChanged );
2862 connect( mChangeStrokeColorButton, &QgsColorButton::colorChanged, this, &QgsSVGFillSymbolLayerWidget::mChangeStrokeColorButton_colorChanged );
2863 connect( mStrokeWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
2864 connect( mTextureWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSVGFillSymbolLayerWidget::mTextureWidthUnitWidget_changed );
2865 connect( mSvgStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSVGFillSymbolLayerWidget::mSvgStrokeWidthUnitWidget_changed );
2870
2871 mRotationSpinBox->setClearValue( 0.0 );
2872
2873 mChangeColorButton->setColorDialogTitle( tr( "Select Fill Color" ) );
2874 mChangeColorButton->setContext( QStringLiteral( "symbology" ) );
2875 mChangeStrokeColorButton->setColorDialogTitle( tr( "Select Stroke Color" ) );
2876 mChangeStrokeColorButton->setContext( QStringLiteral( "symbology" ) );
2877
2878 mFilColorDDBtn->registerLinkedWidget( mChangeColorButton );
2879 mStrokeColorDDBtn->registerLinkedWidget( mChangeStrokeColorButton );
2880
2881 connect( mSvgSelectorWidget, &QgsSvgSelectorWidget::svgSelected, this, &QgsSVGFillSymbolLayerWidget::setFile );
2882 connect( mSvgSelectorWidget, &QgsSvgSelectorWidget::svgParametersChanged, this, &QgsSVGFillSymbolLayerWidget::setSvgParameters );
2883}
2884
2886{
2887 if ( !layer )
2888 {
2889 return;
2890 }
2891
2892 if ( layer->layerType() != QLatin1String( "SVGFill" ) )
2893 {
2894 return;
2895 }
2896
2897 mLayer = dynamic_cast<QgsSVGFillSymbolLayer *>( layer );
2898 if ( mLayer )
2899 {
2900 const double width = mLayer->patternWidth();
2901 mTextureWidthSpinBox->blockSignals( true );
2902 mTextureWidthSpinBox->setValue( width );
2903 mTextureWidthSpinBox->blockSignals( false );
2904 whileBlocking( mSvgSelectorWidget->sourceLineEdit() )->setSource( mLayer->svgFilePath() );
2905 mRotationSpinBox->blockSignals( true );
2906 mRotationSpinBox->setValue( mLayer->angle() );
2907 mRotationSpinBox->blockSignals( false );
2908 mTextureWidthUnitWidget->blockSignals( true );
2909 mTextureWidthUnitWidget->setUnit( mLayer->patternWidthUnit() );
2910 mTextureWidthUnitWidget->setMapUnitScale( mLayer->patternWidthMapUnitScale() );
2911 mTextureWidthUnitWidget->blockSignals( false );
2912 mSvgStrokeWidthUnitWidget->blockSignals( true );
2913 mSvgStrokeWidthUnitWidget->setUnit( mLayer->svgStrokeWidthUnit() );
2914 mSvgStrokeWidthUnitWidget->setMapUnitScale( mLayer->svgStrokeWidthMapUnitScale() );
2915 mSvgStrokeWidthUnitWidget->blockSignals( false );
2916 mChangeColorButton->blockSignals( true );
2917 mChangeColorButton->setColor( mLayer->svgFillColor() );
2918 mChangeColorButton->blockSignals( false );
2919 mChangeStrokeColorButton->blockSignals( true );
2920 mChangeStrokeColorButton->setColor( mLayer->svgStrokeColor() );
2921 mChangeStrokeColorButton->blockSignals( false );
2922 mStrokeWidthSpinBox->blockSignals( true );
2923 mStrokeWidthSpinBox->setValue( mLayer->svgStrokeWidth() );
2924 mStrokeWidthSpinBox->blockSignals( false );
2925 }
2926 updateParamGui( false );
2927
2933
2934 registerDataDefinedButton( mSvgSelectorWidget->sourceLineEdit()->propertyOverrideToolButton(), QgsSymbolLayer::PropertyFile );
2935}
2936
2938{
2939 return mLayer;
2940}
2941
2943{
2945 mSvgSelectorWidget->sourceLineEdit()->setMessageBar( context.messageBar() );
2946}
2947
2948void QgsSVGFillSymbolLayerWidget::mTextureWidthSpinBox_valueChanged( double d )
2949{
2950 if ( mLayer )
2951 {
2952 mLayer->setPatternWidth( d );
2953 emit changed();
2954 }
2955}
2956
2957void QgsSVGFillSymbolLayerWidget::svgSourceChanged( const QString &text )
2958{
2959 if ( !mLayer )
2960 {
2961 return;
2962 }
2963
2964 mLayer->setSvgFilePath( text );
2966 emit changed();
2967}
2968
2969void QgsSVGFillSymbolLayerWidget::setFile( const QString &name )
2970{
2971 mLayer->setSvgFilePath( name );
2972 whileBlocking( mSvgSelectorWidget->sourceLineEdit() )->setSource( name );
2973
2975 emit changed();
2976}
2977
2978void QgsSVGFillSymbolLayerWidget::setSvgParameters( const QMap<QString, QgsProperty> &parameters )
2979{
2980 mLayer->setParameters( parameters );
2981 whileBlocking( mSvgSelectorWidget )->setSvgParameters( parameters );
2982
2984 emit changed();
2985}
2986
2987
2988void QgsSVGFillSymbolLayerWidget::mRotationSpinBox_valueChanged( double d )
2989{
2990 if ( mLayer )
2991 {
2992 mLayer->setAngle( d );
2993 emit changed();
2994 }
2995}
2996
2998{
2999 //activate gui for svg parameters only if supported by the svg file
3000 bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
3001 QColor defaultFill, defaultStroke;
3002 double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
3003 bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
3004 QgsApplication::svgCache()->containsParams( mSvgSelectorWidget->sourceLineEdit()->source(), hasFillParam, hasDefaultFillColor, defaultFill,
3005 hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity,
3006 hasStrokeParam, hasDefaultStrokeColor, defaultStroke,
3007 hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth,
3008 hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
3009 if ( resetValues )
3010 {
3011 QColor fill = mChangeColorButton->color();
3012 const double newOpacity = hasFillOpacityParam ? fill.alphaF() : 1.0;
3013 if ( hasDefaultFillColor )
3014 {
3015 fill = defaultFill;
3016 }
3017 fill.setAlphaF( hasDefaultFillOpacity ? defaultFillOpacity : newOpacity );
3018 mChangeColorButton->setColor( fill );
3019 }
3020 mChangeColorButton->setEnabled( hasFillParam );
3021 mChangeColorButton->setAllowOpacity( hasFillOpacityParam );
3022 if ( resetValues )
3023 {
3024 QColor stroke = mChangeStrokeColorButton->color();
3025 const double newOpacity = hasStrokeOpacityParam ? stroke.alphaF() : 1.0;
3026 if ( hasDefaultStrokeColor )
3027 {
3028 stroke = defaultStroke;
3029 }
3030 stroke.setAlphaF( hasDefaultStrokeOpacity ? defaultStrokeOpacity : newOpacity );
3031 mChangeStrokeColorButton->setColor( stroke );
3032 }
3033 mChangeStrokeColorButton->setEnabled( hasStrokeParam );
3034 mChangeStrokeColorButton->setAllowOpacity( hasStrokeOpacityParam );
3035 if ( hasDefaultStrokeWidth && resetValues )
3036 {
3037 mStrokeWidthSpinBox->setValue( defaultStrokeWidth );
3038 }
3039 mStrokeWidthSpinBox->setEnabled( hasStrokeWidthParam );
3040}
3041
3042void QgsSVGFillSymbolLayerWidget::mChangeColorButton_colorChanged( const QColor &color )
3043{
3044 if ( !mLayer )
3045 {
3046 return;
3047 }
3048
3049 mLayer->setSvgFillColor( color );
3050 emit changed();
3051}
3052
3053void QgsSVGFillSymbolLayerWidget::mChangeStrokeColorButton_colorChanged( const QColor &color )
3054{
3055 if ( !mLayer )
3056 {
3057 return;
3058 }
3059
3060 mLayer->setSvgStrokeColor( color );
3061 emit changed();
3062}
3063
3064void QgsSVGFillSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
3065{
3066 if ( mLayer )
3067 {
3069 emit changed();
3070 }
3071}
3072
3073void QgsSVGFillSymbolLayerWidget::mTextureWidthUnitWidget_changed()
3074{
3075 if ( mLayer )
3076 {
3077 mLayer->setPatternWidthUnit( mTextureWidthUnitWidget->unit() );
3078 mLayer->setPatternWidthMapUnitScale( mTextureWidthUnitWidget->getMapUnitScale() );
3079 emit changed();
3080 }
3081}
3082
3083void QgsSVGFillSymbolLayerWidget::mSvgStrokeWidthUnitWidget_changed()
3084{
3085 if ( mLayer )
3086 {
3087 mLayer->setSvgStrokeWidthUnit( mSvgStrokeWidthUnitWidget->unit() );
3088 mLayer->setSvgStrokeWidthMapUnitScale( mSvgStrokeWidthUnitWidget->getMapUnitScale() );
3089 emit changed();
3090 }
3091}
3092
3094
3096 QgsSymbolLayerWidget( parent, vl )
3097{
3098 setupUi( this );
3099 connect( mAngleSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLinePatternFillSymbolLayerWidget::mAngleSpinBox_valueChanged );
3100 connect( mDistanceSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLinePatternFillSymbolLayerWidget::mDistanceSpinBox_valueChanged );
3101 connect( mOffsetSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLinePatternFillSymbolLayerWidget::mOffsetSpinBox_valueChanged );
3102 connect( mDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsLinePatternFillSymbolLayerWidget::mDistanceUnitWidget_changed );
3103 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsLinePatternFillSymbolLayerWidget::mOffsetUnitWidget_changed );
3108 mOffsetSpinBox->setClearValue( 0 );
3109 mAngleSpinBox->setClearValue( 0 );
3110
3111 mCoordinateReferenceComboBox->addItem( tr( "Align Pattern to Feature" ), static_cast< int >( Qgis::SymbolCoordinateReference::Feature ) );
3112 mCoordinateReferenceComboBox->addItem( tr( "Align Pattern to Map Extent" ), static_cast< int >( Qgis::SymbolCoordinateReference::Viewport ) );
3113 connect( mCoordinateReferenceComboBox, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]
3114 {
3115 if ( mLayer )
3116 {
3117 mLayer->setCoordinateReference( static_cast< Qgis::SymbolCoordinateReference >( mCoordinateReferenceComboBox->currentData().toInt() ) );
3118 emit changed();
3119 }
3120 } );
3121
3122 mClipModeComboBox->addItem( tr( "Clip During Render Only" ), static_cast< int >( Qgis::LineClipMode::ClipPainterOnly ) );
3123 mClipModeComboBox->addItem( tr( "Clip Lines Before Render" ), static_cast< int >( Qgis::LineClipMode::ClipToIntersection ) );
3124 mClipModeComboBox->addItem( tr( "No Clipping" ), static_cast< int >( Qgis::LineClipMode::NoClipping ) );
3125 connect( mClipModeComboBox, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]
3126 {
3127 if ( mLayer )
3128 {
3129 mLayer->setClipMode( static_cast< Qgis::LineClipMode >( mClipModeComboBox->currentData().toInt() ) );
3130 emit changed();
3131 }
3132 } );
3133
3134}
3135
3137{
3138 if ( layer->layerType() != QLatin1String( "LinePatternFill" ) )
3139 {
3140 return;
3141 }
3142
3143 QgsLinePatternFillSymbolLayer *patternLayer = static_cast<QgsLinePatternFillSymbolLayer *>( layer );
3144 if ( patternLayer )
3145 {
3146 mLayer = patternLayer;
3147 whileBlocking( mAngleSpinBox )->setValue( mLayer->lineAngle() );
3148 whileBlocking( mDistanceSpinBox )->setValue( mLayer->distance() );
3149 whileBlocking( mOffsetSpinBox )->setValue( mLayer->offset() );
3150
3151 //units
3152 mDistanceUnitWidget->blockSignals( true );
3153 mDistanceUnitWidget->setUnit( mLayer->distanceUnit() );
3154 mDistanceUnitWidget->setMapUnitScale( mLayer->distanceMapUnitScale() );
3155 mDistanceUnitWidget->blockSignals( false );
3156 mOffsetUnitWidget->blockSignals( true );
3157 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
3158 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
3159 mOffsetUnitWidget->blockSignals( false );
3160
3161 whileBlocking( mCoordinateReferenceComboBox )->setCurrentIndex( mCoordinateReferenceComboBox->findData( static_cast< int >( mLayer->coordinateReference() ) ) );
3162
3163 whileBlocking( mClipModeComboBox )->setCurrentIndex( mClipModeComboBox->findData( static_cast< int >( mLayer->clipMode() ) ) );
3164 }
3165
3170}
3171
3173{
3174 return mLayer;
3175}
3176
3177void QgsLinePatternFillSymbolLayerWidget::mAngleSpinBox_valueChanged( double d )
3178{
3179 if ( mLayer )
3180 {
3181 mLayer->setLineAngle( d );
3182 emit changed();
3183 }
3184}
3185
3186void QgsLinePatternFillSymbolLayerWidget::mDistanceSpinBox_valueChanged( double d )
3187{
3188 if ( mLayer )
3189 {
3190 mLayer->setDistance( d );
3191 emit changed();
3192 }
3193}
3194
3195void QgsLinePatternFillSymbolLayerWidget::mOffsetSpinBox_valueChanged( double d )
3196{
3197 if ( mLayer )
3198 {
3199 mLayer->setOffset( d );
3200 emit changed();
3201 }
3202}
3203
3204void QgsLinePatternFillSymbolLayerWidget::mDistanceUnitWidget_changed()
3205{
3206 if ( mLayer )
3207 {
3208 mLayer->setDistanceUnit( mDistanceUnitWidget->unit() );
3209 mLayer->setDistanceMapUnitScale( mDistanceUnitWidget->getMapUnitScale() );
3210 emit changed();
3211 }
3212}
3213
3214void QgsLinePatternFillSymbolLayerWidget::mOffsetUnitWidget_changed()
3215{
3216 if ( mLayer )
3217 {
3218 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
3219 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
3220 emit changed();
3221 }
3222}
3223
3225
3227 QgsSymbolLayerWidget( parent, vl )
3228{
3229 setupUi( this );
3230 connect( mHorizontalDistanceSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceSpinBox_valueChanged );
3231 connect( mVerticalDistanceSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceSpinBox_valueChanged );
3232 connect( mHorizontalDisplacementSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementSpinBox_valueChanged );
3233 connect( mVerticalDisplacementSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementSpinBox_valueChanged );
3234 connect( mHorizontalOffsetSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetSpinBox_valueChanged );
3235 connect( mVerticalOffsetSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetSpinBox_valueChanged );
3236 connect( mHorizontalDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceUnitWidget_changed );
3237 connect( mVerticalDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceUnitWidget_changed );
3238 connect( mHorizontalDisplacementUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementUnitWidget_changed );
3239 connect( mVerticalDisplacementUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementUnitWidget_changed );
3240 connect( mHorizontalOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetUnitWidget_changed );
3241 connect( mVerticalOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetUnitWidget_changed );
3254
3255 mClipModeComboBox->addItem( tr( "Clip to Shape" ), static_cast< int >( Qgis::MarkerClipMode::Shape ) );
3256 mClipModeComboBox->addItem( tr( "Marker Centroid Within Shape" ), static_cast< int >( Qgis::MarkerClipMode::CentroidWithin ) );
3257 mClipModeComboBox->addItem( tr( "Marker Completely Within Shape" ), static_cast< int >( Qgis::MarkerClipMode::CompletelyWithin ) );
3258 mClipModeComboBox->addItem( tr( "No Clipping" ), static_cast< int >( Qgis::MarkerClipMode::NoClipping ) );
3259 connect( mClipModeComboBox, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]
3260 {
3261 if ( mLayer )
3262 {
3263 mLayer->setClipMode( static_cast< Qgis::MarkerClipMode >( mClipModeComboBox->currentData().toInt() ) );
3264 emit changed();
3265 }
3266 } );
3267
3268 mCoordinateReferenceComboBox->addItem( tr( "Align Pattern to Feature" ), static_cast< int >( Qgis::SymbolCoordinateReference::Feature ) );
3269 mCoordinateReferenceComboBox->addItem( tr( "Align Pattern to Map Extent" ), static_cast< int >( Qgis::SymbolCoordinateReference::Viewport ) );
3270 connect( mCoordinateReferenceComboBox, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]
3271 {
3272 if ( mLayer )
3273 {
3274 mLayer->setCoordinateReference( static_cast< Qgis::SymbolCoordinateReference >( mCoordinateReferenceComboBox->currentData().toInt() ) );
3275 emit changed();
3276 }
3277 } );
3278
3279 mSeedSpinBox->setShowClearButton( true );
3280 mSeedSpinBox->setClearValue( 0 );
3281 mRandomXSpinBox->setClearValue( 0 );
3282 mRandomYSpinBox->setClearValue( 0 );
3283
3288 connect( mRandomXSpinBox, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double d )
3289 {
3290 if ( mLayer )
3291 {
3293 emit changed();
3294 }
3295 } );
3296 connect( mRandomYSpinBox, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double d )
3297 {
3298 if ( mLayer )
3299 {
3301 emit changed();
3302 }
3303 } );
3304 connect( mRandomXOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, [ = ]
3305 {
3306 if ( mLayer )
3307 {
3308 mLayer->setRandomDeviationXUnit( mRandomXOffsetUnitWidget->unit() );
3309 mLayer->setRandomDeviationXMapUnitScale( mRandomXOffsetUnitWidget->getMapUnitScale() );
3310 emit changed();
3311 }
3312 } );
3313 connect( mRandomYOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, [ = ]
3314 {
3315 if ( mLayer )
3316 {
3317 mLayer->setRandomDeviationYUnit( mRandomYOffsetUnitWidget->unit() );
3318 mLayer->setRandomDeviationYMapUnitScale( mRandomYOffsetUnitWidget->getMapUnitScale() );
3319 emit changed();
3320 }
3321 } );
3322 connect( mSeedSpinBox, qOverload< int > ( &QSpinBox::valueChanged ), this, [ = ]( int v )
3323 {
3324 if ( mLayer )
3325 {
3326 mLayer->setSeed( v );
3327 emit changed();
3328 }
3329 } );
3330
3331 mAngleSpinBox->setShowClearButton( true );
3332 mAngleSpinBox->setClearValue( 0 );
3333 connect( mAngleSpinBox, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double d )
3334 {
3335 if ( mLayer )
3336 {
3337 mLayer->setAngle( d );
3338 emit changed();
3339 }
3340 } );
3341}
3342
3344{
3345 if ( !layer || layer->layerType() != QLatin1String( "PointPatternFill" ) )
3346 {
3347 return;
3348 }
3349
3350 mLayer = static_cast<QgsPointPatternFillSymbolLayer *>( layer );
3351 whileBlocking( mHorizontalDistanceSpinBox )->setValue( mLayer->distanceX() );
3352 whileBlocking( mVerticalDistanceSpinBox )->setValue( mLayer->distanceY() );
3353 whileBlocking( mHorizontalDisplacementSpinBox )->setValue( mLayer->displacementX() );
3354 whileBlocking( mVerticalDisplacementSpinBox )->setValue( mLayer->displacementY() );
3355 whileBlocking( mHorizontalOffsetSpinBox )->setValue( mLayer->offsetX() );
3356 whileBlocking( mVerticalOffsetSpinBox )->setValue( mLayer->offsetY() );
3357 whileBlocking( mAngleSpinBox )->setValue( mLayer->angle() );
3358
3359 mHorizontalDistanceUnitWidget->blockSignals( true );
3360 mHorizontalDistanceUnitWidget->setUnit( mLayer->distanceXUnit() );
3361 mHorizontalDistanceUnitWidget->setMapUnitScale( mLayer->distanceXMapUnitScale() );
3362 mHorizontalDistanceUnitWidget->blockSignals( false );
3363 mVerticalDistanceUnitWidget->blockSignals( true );
3364 mVerticalDistanceUnitWidget->setUnit( mLayer->distanceYUnit() );
3365 mVerticalDistanceUnitWidget->setMapUnitScale( mLayer->distanceYMapUnitScale() );
3366 mVerticalDistanceUnitWidget->blockSignals( false );
3367 mHorizontalDisplacementUnitWidget->blockSignals( true );
3368 mHorizontalDisplacementUnitWidget->setUnit( mLayer->displacementXUnit() );
3369 mHorizontalDisplacementUnitWidget->setMapUnitScale( mLayer->displacementXMapUnitScale() );
3370 mHorizontalDisplacementUnitWidget->blockSignals( false );
3371 mVerticalDisplacementUnitWidget->blockSignals( true );
3372 mVerticalDisplacementUnitWidget->setUnit( mLayer->displacementYUnit() );
3373 mVerticalDisplacementUnitWidget->setMapUnitScale( mLayer->displacementYMapUnitScale() );
3374 mVerticalDisplacementUnitWidget->blockSignals( false );
3375 mHorizontalOffsetUnitWidget->blockSignals( true );
3376 mHorizontalOffsetUnitWidget->setUnit( mLayer->offsetXUnit() );
3377 mHorizontalOffsetUnitWidget->setMapUnitScale( mLayer->offsetXMapUnitScale() );
3378 mHorizontalOffsetUnitWidget->blockSignals( false );
3379 mVerticalOffsetUnitWidget->blockSignals( true );
3380 mVerticalOffsetUnitWidget->setUnit( mLayer->offsetYUnit() );
3381 mVerticalOffsetUnitWidget->setMapUnitScale( mLayer->offsetYMapUnitScale() );
3382 mVerticalOffsetUnitWidget->blockSignals( false );
3383
3384 whileBlocking( mClipModeComboBox )->setCurrentIndex( mClipModeComboBox->findData( static_cast< int >( mLayer->clipMode() ) ) );
3385 whileBlocking( mCoordinateReferenceComboBox )->setCurrentIndex( mCoordinateReferenceComboBox->findData( static_cast< int >( mLayer->coordinateReference() ) ) );
3386
3387 whileBlocking( mRandomXSpinBox )->setValue( mLayer->maximumRandomDeviationX() );
3388 whileBlocking( mRandomYSpinBox )->setValue( mLayer->maximumRandomDeviationY() );
3389 whileBlocking( mRandomXOffsetUnitWidget )->setUnit( mLayer->randomDeviationXUnit() );
3390 whileBlocking( mRandomXOffsetUnitWidget )->setMapUnitScale( mLayer->randomDeviationXMapUnitScale() );
3391 whileBlocking( mRandomYOffsetUnitWidget )->setUnit( mLayer->randomDeviationYUnit() );
3392 whileBlocking( mRandomYOffsetUnitWidget )->setMapUnitScale( mLayer->randomDeviationYMapUnitScale() );
3393 whileBlocking( mSeedSpinBox )->setValue( mLayer->seed() );
3394
3407}
3408
3410{
3411 return mLayer;
3412}
3413
3414void QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceSpinBox_valueChanged( double d )
3415{
3416 if ( mLayer )
3417 {
3418 mLayer->setDistanceX( d );
3419 emit changed();
3420 }
3421}
3422
3423void QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceSpinBox_valueChanged( double d )
3424{
3425 if ( mLayer )
3426 {
3427 mLayer->setDistanceY( d );
3428 emit changed();
3429 }
3430}
3431
3432void QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementSpinBox_valueChanged( double d )
3433{
3434 if ( mLayer )
3435 {
3437 emit changed();
3438 }
3439}
3440
3441void QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementSpinBox_valueChanged( double d )
3442{
3443 if ( mLayer )
3444 {
3446 emit changed();
3447 }
3448}
3449
3450void QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetSpinBox_valueChanged( double d )
3451{
3452 if ( mLayer )
3453 {
3454 mLayer->setOffsetX( d );
3455 emit changed();
3456 }
3457}
3458
3459void QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetSpinBox_valueChanged( double d )
3460{
3461 if ( mLayer )
3462 {
3463 mLayer->setOffsetY( d );
3464 emit changed();
3465 }
3466}
3467
3468void QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceUnitWidget_changed()
3469{
3470 if ( mLayer )
3471 {
3472 mLayer->setDistanceXUnit( mHorizontalDistanceUnitWidget->unit() );
3473 mLayer->setDistanceXMapUnitScale( mHorizontalDistanceUnitWidget->getMapUnitScale() );
3474 emit changed();
3475 }
3476}
3477
3478void QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceUnitWidget_changed()
3479{
3480 if ( mLayer )
3481 {
3482 mLayer->setDistanceYUnit( mVerticalDistanceUnitWidget->unit() );
3483 mLayer->setDistanceYMapUnitScale( mVerticalDistanceUnitWidget->getMapUnitScale() );
3484 emit changed();
3485 }
3486}
3487
3488void QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementUnitWidget_changed()
3489{
3490 if ( mLayer )
3491 {
3492 mLayer->setDisplacementXUnit( mHorizontalDisplacementUnitWidget->unit() );
3493 mLayer->setDisplacementXMapUnitScale( mHorizontalDisplacementUnitWidget->getMapUnitScale() );
3494 emit changed();
3495 }
3496}
3497
3498void QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementUnitWidget_changed()
3499{
3500 if ( mLayer )
3501 {
3502 mLayer->setDisplacementYUnit( mVerticalDisplacementUnitWidget->unit() );
3503 mLayer->setDisplacementYMapUnitScale( mVerticalDisplacementUnitWidget->getMapUnitScale() );
3504 emit changed();
3505 }
3506}
3507
3508void QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetUnitWidget_changed()
3509{
3510 if ( mLayer )
3511 {
3512 mLayer->setOffsetXUnit( mHorizontalOffsetUnitWidget->unit() );
3513 mLayer->setOffsetXMapUnitScale( mHorizontalOffsetUnitWidget->getMapUnitScale() );
3514 emit changed();
3515 }
3516}
3517
3518void QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetUnitWidget_changed()
3519{
3520 if ( mLayer )
3521 {
3522 mLayer->setOffsetYUnit( mVerticalOffsetUnitWidget->unit() );
3523 mLayer->setOffsetYMapUnitScale( mVerticalOffsetUnitWidget->getMapUnitScale() );
3524 emit changed();
3525 }
3526}
3527
3529
3531 : QgsSymbolLayerWidget( parent, vl )
3532{
3533 mLayer = nullptr;
3534
3535 setupUi( this );
3536 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
3537 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
3538 connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
3539 connect( mStrokeWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
3540 connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
3541 connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
3548
3550 scrollArea->setWidget( widgetChar );
3551 scrollArea->setVerticalOnly( true );
3552
3553 btnColor->setAllowOpacity( true );
3554 btnColor->setColorDialogTitle( tr( "Select Symbol Fill Color" ) );
3555 btnColor->setContext( QStringLiteral( "symbology" ) );
3556 btnStrokeColor->setAllowOpacity( true );
3557 btnStrokeColor->setColorDialogTitle( tr( "Select Symbol Stroke Color" ) );
3558 btnStrokeColor->setContext( QStringLiteral( "symbology" ) );
3559
3560 mColorDDBtn->registerLinkedWidget( btnColor );
3561 mStrokeColorDDBtn->registerLinkedWidget( btnStrokeColor );
3562
3563 spinOffsetX->setClearValue( 0.0 );
3564 spinOffsetY->setClearValue( 0.0 );
3565 spinAngle->setClearValue( 0.0 );
3566
3567 //make a temporary symbol for the size assistant preview
3568 mAssistantPreviewSymbol.reset( new QgsMarkerSymbol() );
3569
3570 if ( vectorLayer() )
3571 mSizeDDBtn->setSymbol( mAssistantPreviewSymbol );
3572
3573 connect( cboFont, &QFontComboBox::currentFontChanged, this, &QgsFontMarkerSymbolLayerWidget::setFontFamily );
3574 connect( mFontStyleComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::mFontStyleComboBox_currentIndexChanged );
3575 connect( spinSize, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setSize );
3576 connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::penJoinStyleChanged );
3579 connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::penJoinStyleChanged );
3580 connect( spinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setAngle );
3581 connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setOffset );
3582 connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setOffset );
3584 connect( mCharLineEdit, &QLineEdit::textChanged, this, &QgsFontMarkerSymbolLayerWidget::setCharacterFromText );
3585
3586 connect( this, &QgsSymbolLayerWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::updateAssistantSymbol );
3587}
3588
3590
3592{
3593 if ( layer->layerType() != QLatin1String( "FontMarker" ) )
3594 return;
3595
3596 // layer type is correct, we can do the cast
3597 mLayer = static_cast<QgsFontMarkerSymbolLayer *>( layer );
3598
3599 mRefFont.setFamily( mLayer->fontFamily() );
3600 mRefFont.setStyleName( QgsFontUtils::translateNamedStyle( mLayer->fontStyle() ) );
3601
3602 mFontStyleComboBox->blockSignals( true );
3603 populateFontStyleComboBox();
3604 mFontStyleComboBox->blockSignals( false );
3605
3606 // set values
3607 whileBlocking( cboFont )->setCurrentFont( mRefFont );
3608 whileBlocking( spinSize )->setValue( mLayer->size() );
3609 whileBlocking( btnColor )->setColor( mLayer->color() );
3610 whileBlocking( btnStrokeColor )->setColor( mLayer->strokeColor() );
3611 whileBlocking( mStrokeWidthSpinBox )->setValue( mLayer->strokeWidth() );
3612 whileBlocking( spinAngle )->setValue( mLayer->angle() );
3613
3614 widgetChar->blockSignals( true );
3615 widgetChar->setFont( mRefFont );
3616 if ( mLayer->character().length() == 1 )
3617 {
3618 widgetChar->setCharacter( mLayer->character().at( 0 ) );
3619 }
3620 widgetChar->blockSignals( false );
3621 whileBlocking( mCharLineEdit )->setText( mLayer->character() );
3622 mCharPreview->setFont( mRefFont );
3623
3624 //block
3625 whileBlocking( spinOffsetX )->setValue( mLayer->offset().x() );
3626 whileBlocking( spinOffsetY )->setValue( mLayer->offset().y() );
3627
3628 mSizeUnitWidget->blockSignals( true );
3629 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
3630 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
3631 mSizeUnitWidget->blockSignals( false );
3632
3633 mStrokeWidthUnitWidget->blockSignals( true );
3634 mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
3635 mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
3636 mStrokeWidthUnitWidget->blockSignals( false );
3637
3638 mOffsetUnitWidget->blockSignals( true );
3639 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
3640 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
3641 mOffsetUnitWidget->blockSignals( false );
3642
3643 whileBlocking( cboJoinStyle )->setPenJoinStyle( mLayer->penJoinStyle() );
3644
3645 //anchor points
3646 whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mLayer->horizontalAnchorPoint() );
3647 whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mLayer->verticalAnchorPoint() );
3648
3661
3662 updateAssistantSymbol();
3663}
3664
3666{
3667 return mLayer;
3668}
3669
3671{
3672 if ( mLayer )
3673 {
3674 mLayer->setFontFamily( font.family() );
3675 mRefFont.setFamily( font.family() );
3676 widgetChar->setFont( mRefFont );
3677 mCharPreview->setFont( mRefFont );
3678 populateFontStyleComboBox();
3679 emit changed();
3680 }
3681}
3682
3683void QgsFontMarkerSymbolLayerWidget::setFontStyle( const QString &style )
3684{
3685 if ( mLayer )
3686 {
3687 QgsFontUtils::updateFontViaStyle( mRefFont, style );
3689 widgetChar->setFont( mRefFont );
3690 mCharPreview->setFont( mRefFont );
3691 emit changed();
3692 }
3693}
3694
3696{
3697 mLayer->setColor( color );
3698 emit changed();
3699}
3700
3702{
3703 mLayer->setStrokeColor( color );
3704 emit changed();
3705}
3706
3708{
3709 mLayer->setSize( size );
3710 //widgetChar->updateSize(size);
3711 emit changed();
3712}
3713
3715{
3716 mLayer->setAngle( angle );
3717 emit changed();
3718}
3719
3721{
3722 mCharPreview->setText( text );
3723
3724 if ( text.isEmpty() )
3725 return;
3726
3727 // take the last character of a string for a better experience when users cycle through several characters on their keyboard
3728 QString character = text;
3729 if ( text.contains( QRegularExpression( QStringLiteral( "^0x[0-9a-fA-F]{1,4}$" ) ) ) )
3730 {
3731 bool ok = false;
3732 const unsigned int value = text.toUInt( &ok, 0 );
3733 if ( ok )
3734 {
3735 character = QChar( value );
3736 mCharPreview->setText( character );
3737 }
3738 }
3739
3740 if ( character != mLayer->character() )
3741 {
3742 mLayer->setCharacter( character );
3743 if ( mLayer->character().length() == 1 )
3744 {
3745 whileBlocking( widgetChar )->setCharacter( mLayer->character().at( 0 ) );
3746 }
3747 else
3748 {
3750 }
3751 emit changed();
3752 }
3753}
3754
3756{
3757 if ( mLayer->character().length() > 1 || QGuiApplication::keyboardModifiers() & Qt::ControlModifier )
3758 {
3759 mCharLineEdit->insert( chr );
3760 return;
3761 }
3762
3763 mLayer->setCharacter( chr );
3764 whileBlocking( mCharLineEdit )->setText( chr );
3765 mCharPreview->setText( chr );
3766 emit changed();
3767}
3768
3769void QgsFontMarkerSymbolLayerWidget::setOffset()
3770{
3771 mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
3772 emit changed();
3773}
3774
3775void QgsFontMarkerSymbolLayerWidget::penJoinStyleChanged()
3776{
3777 mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
3778 emit changed();
3779}
3780
3781void QgsFontMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
3782{
3783 if ( mLayer )
3784 {
3785 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
3786 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
3787 emit changed();
3788 }
3789}
3790
3791void QgsFontMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
3792{
3793 if ( mLayer )
3794 {
3795 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
3796 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
3797 emit changed();
3798 }
3799}
3800
3801void QgsFontMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
3802{
3803 if ( mLayer )
3804 {
3805 mLayer->setStrokeWidthUnit( mSizeUnitWidget->unit() );
3806 mLayer->setStrokeWidthMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
3807 emit changed();
3808 }
3809}
3810
3811void QgsFontMarkerSymbolLayerWidget::populateFontStyleComboBox()
3812{
3813 mFontStyleComboBox->clear();
3814 const QStringList styles = mFontDB.styles( mRefFont.family() );
3815 const auto constStyles = styles;
3816 for ( const QString &style : constStyles )
3817 {
3818 mFontStyleComboBox->addItem( style );
3819 }
3820
3821 QString targetStyle = mFontDB.styleString( mRefFont );
3822 if ( !styles.contains( targetStyle ) )
3823 {
3824 const QFont f = QFont( mRefFont.family() );
3825 targetStyle = QFontInfo( f ).styleName();
3826 mRefFont.setStyleName( targetStyle );
3827 }
3828 int curIndx = 0;
3829 const int stylIndx = mFontStyleComboBox->findText( targetStyle );
3830 if ( stylIndx > -1 )
3831 {
3832 curIndx = stylIndx;
3833 }
3834
3835 mFontStyleComboBox->setCurrentIndex( curIndx );
3836}
3837
3838void QgsFontMarkerSymbolLayerWidget::mFontStyleComboBox_currentIndexChanged( int index )
3839{
3840 Q_UNUSED( index );
3841 setFontStyle( mFontStyleComboBox->currentText() );
3842}
3843
3844void QgsFontMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
3845{
3846 if ( mLayer )
3847 {
3849 emit changed();
3850 }
3851}
3852
3853void QgsFontMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
3854{
3855 if ( mLayer )
3856 {
3858 emit changed();
3859 }
3860}
3861
3862void QgsFontMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
3863{
3864 if ( mLayer )
3865 {
3866 mLayer->setStrokeWidth( d );
3867 emit changed();
3868 }
3869}
3870
3871void QgsFontMarkerSymbolLayerWidget::updateAssistantSymbol()
3872{
3873 for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
3874 {
3875 mAssistantPreviewSymbol->deleteSymbolLayer( i );
3876 }
3877 mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
3879 if ( ddSize )
3880 mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
3881}
3882
3884
3885
3887 : QgsSymbolLayerWidget( parent, vl )
3888{
3889 mLayer = nullptr;
3890
3891 setupUi( this );
3892 connect( mDrawInsideCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mDrawInsideCheckBox_stateChanged );
3893 connect( mDrawAllPartsCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mDrawAllPartsCheckBox_stateChanged );
3894 connect( mClipPointsCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mClipPointsCheckBox_stateChanged );
3895 connect( mClipOnCurrentPartOnlyCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mClipOnCurrentPartOnlyCheckBox_stateChanged );
3896}
3897
3899{
3900 if ( layer->layerType() != QLatin1String( "CentroidFill" ) )
3901 return;
3902
3903 // layer type is correct, we can do the cast
3904 mLayer = static_cast<QgsCentroidFillSymbolLayer *>( layer );
3905
3906 // set values
3907 whileBlocking( mDrawInsideCheckBox )->setChecked( mLayer->pointOnSurface() );
3908 whileBlocking( mDrawAllPartsCheckBox )->setChecked( mLayer->pointOnAllParts() );
3909 whileBlocking( mClipPointsCheckBox )->setChecked( mLayer->clipPoints() );
3910 whileBlocking( mClipOnCurrentPartOnlyCheckBox )->setChecked( mLayer->clipOnCurrentPartOnly() );
3911}
3912
3914{
3915 return mLayer;
3916}
3917
3918void QgsCentroidFillSymbolLayerWidget::mDrawInsideCheckBox_stateChanged( int state )
3919{
3920 mLayer->setPointOnSurface( state == Qt::Checked );
3921 emit changed();
3922}
3923
3924void QgsCentroidFillSymbolLayerWidget::mDrawAllPartsCheckBox_stateChanged( int state )
3925{
3926 mLayer->setPointOnAllParts( state == Qt::Checked );
3927 emit changed();
3928}
3929
3930void QgsCentroidFillSymbolLayerWidget::mClipPointsCheckBox_stateChanged( int state )
3931{
3932 mLayer->setClipPoints( state == Qt::Checked );
3933 emit changed();
3934}
3935
3936void QgsCentroidFillSymbolLayerWidget::mClipOnCurrentPartOnlyCheckBox_stateChanged( int state )
3937{
3938 mLayer->setClipOnCurrentPartOnly( state == Qt::Checked );
3939 emit changed();
3940}
3941
3943
3945 : QgsSymbolLayerWidget( parent, vl )
3946{
3947 mLayer = nullptr;
3948
3949 setupUi( this );
3950
3951 mImageSourceLineEdit->setLastPathSettingsKey( QStringLiteral( "/UI/lastRasterMarkerImageDir" ) );
3952
3953 connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsRasterMarkerSymbolLayerWidget::imageSourceChanged );
3954 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
3955 connect( mRotationSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setAngle );
3956 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
3957 connect( mWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setWidth );
3958 connect( mHeightSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setHeight );
3959 connect( mLockAspectRatio, static_cast < void ( QgsRatioLockButton::* )( bool ) > ( &QgsRatioLockButton::lockChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setLockAspectRatio );
3960
3965
3966 mSpinOffsetX->setClearValue( 0.0 );
3967 mSpinOffsetY->setClearValue( 0.0 );
3968 mRotationSpinBox->setClearValue( 0.0 );
3969
3970 connect( mSpinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setOffset );
3971 connect( mSpinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setOffset );
3972 connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsRasterMarkerSymbolLayerWidget::setOpacity );
3973
3974 connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
3975 connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
3976}
3977
3979{
3980 if ( !layer )
3981 {
3982 return;
3983 }
3984
3985 if ( layer->layerType() != QLatin1String( "RasterMarker" ) )
3986 return;
3987
3988 // layer type is correct, we can do the cast
3989 mLayer = static_cast<QgsRasterMarkerSymbolLayer *>( layer );
3990
3991 // set values
3992 whileBlocking( mImageSourceLineEdit )->setSource( mLayer->path() );
3993
3994 whileBlocking( mWidthSpinBox )->setValue( mLayer->size() );
3995 const bool preservedAspectRatio = mLayer->preservedAspectRatio();
3996 mHeightSpinBox->blockSignals( true );
3997 if ( preservedAspectRatio )
3998 {
3999 mHeightSpinBox->setValue( mLayer->size() );
4000 }
4001 else
4002 {
4003 mHeightSpinBox->setValue( mLayer->size() * mLayer->fixedAspectRatio() );
4004 }
4005 mHeightSpinBox->setEnabled( mLayer->defaultAspectRatio() > 0.0 );
4006 mHeightSpinBox->blockSignals( false );
4007 whileBlocking( mLockAspectRatio )->setLocked( preservedAspectRatio );
4008
4009 whileBlocking( mRotationSpinBox )->setValue( mLayer->angle() );
4010 whileBlocking( mOpacityWidget )->setOpacity( mLayer->opacity() );
4011
4012 whileBlocking( mSpinOffsetX )->setValue( mLayer->offset().x() );
4013 whileBlocking( mSpinOffsetY )->setValue( mLayer->offset().y() );
4014
4015 mSizeUnitWidget->blockSignals( true );
4016 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
4017 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
4018 mSizeUnitWidget->blockSignals( false );
4019 mOffsetUnitWidget->blockSignals( true );
4020 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
4021 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
4022 mOffsetUnitWidget->blockSignals( false );
4023
4024 //anchor points
4025 whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mLayer->horizontalAnchorPoint() );
4026 whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mLayer->verticalAnchorPoint() );
4027
4036
4037 updatePreviewImage();
4038}
4039
4041{
4042 return mLayer;
4043}
4044
4046{
4048 mImageSourceLineEdit->setMessageBar( context.messageBar() );
4049}
4050
4051void QgsRasterMarkerSymbolLayerWidget::imageSourceChanged( const QString &text )
4052{
4053 mLayer->setPath( text );
4054 updatePreviewImage();
4055 emit changed();
4056}
4057
4058void QgsRasterMarkerSymbolLayerWidget::updatePreviewImage()
4059{
4060 bool fitsInCache = false;
4061 const QImage image = QgsApplication::imageCache()->pathAsImage( mLayer->path(), QSize( 150, 150 ), true, 1.0, fitsInCache );
4062 if ( image.isNull() )
4063 {
4064 mLabelImagePreview->setPixmap( QPixmap() );
4065 return;
4066 }
4067
4068 QImage previewImage( 150, 150, QImage::Format_ARGB32 );
4069 previewImage.fill( Qt::transparent );
4070 const QRect imageRect( ( 150 - image.width() ) / 2.0, ( 150 - image.height() ) / 2.0, image.width(), image.height() );
4071 QPainter p;
4072 p.begin( &previewImage );
4073 //draw a checkerboard background
4074 uchar pixDataRGB[] = { 150, 150, 150, 150,
4075 100, 100, 100, 150,
4076 100, 100, 100, 150,
4077 150, 150, 150, 150
4078 };
4079 const QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
4080 const QPixmap pix = QPixmap::fromImage( img.scaled( 8, 8 ) );
4081 QBrush checkerBrush;
4082 checkerBrush.setTexture( pix );
4083 p.fillRect( imageRect, checkerBrush );
4084
4085 if ( mLayer->opacity() < 1.0 )
4086 {
4087 p.setOpacity( mLayer->opacity() );
4088 }
4089
4090 p.drawImage( imageRect.left(), imageRect.top(), image );
4091 p.end();
4092 mLabelImagePreview->setPixmap( QPixmap::fromImage( previewImage ) );
4093}
4094
4095void QgsRasterMarkerSymbolLayerWidget::setWidth()
4096{
4097 const double defaultAspectRatio = mLayer->defaultAspectRatio();
4098 double fixedAspectRatio = 0.0;
4099 mHeightSpinBox->blockSignals( true );
4100 if ( defaultAspectRatio <= 0.0 )
4101 {
4102 mHeightSpinBox->setValue( mWidthSpinBox->value() );
4103 }
4104 else if ( mLockAspectRatio->locked() )
4105 {
4106 mHeightSpinBox->setValue( mWidthSpinBox->value() * defaultAspectRatio );
4107 }
4108 else
4109 {
4110 fixedAspectRatio = mHeightSpinBox->value() / mWidthSpinBox->value();
4111 }
4112 mHeightSpinBox->blockSignals( false );
4113 mLayer->setSize( mWidthSpinBox->value() );
4114 mLayer->setFixedAspectRatio( fixedAspectRatio );
4115 emit changed();
4116}
4117
4118void QgsRasterMarkerSymbolLayerWidget::setHeight()
4119{
4120 const double defaultAspectRatio = mLayer->defaultAspectRatio();
4121 double fixedAspectRatio = 0.0;
4122 mWidthSpinBox->blockSignals( true );
4123 if ( defaultAspectRatio <= 0.0 )
4124 {
4125 mWidthSpinBox->setValue( mHeightSpinBox->value() );
4126 }
4127 else if ( mLockAspectRatio->locked() )
4128 {
4129 mWidthSpinBox->setValue( mHeightSpinBox->value() / defaultAspectRatio );
4130 }
4131 else
4132 {
4133 fixedAspectRatio = mHeightSpinBox->value() / mWidthSpinBox->value();
4134 }
4135 mWidthSpinBox->blockSignals( false );
4136 mLayer->setSize( mWidthSpinBox->value() );
4137 mLayer->setFixedAspectRatio( fixedAspectRatio );
4138 emit changed();
4139}
4140
4141void QgsRasterMarkerSymbolLayerWidget::setLockAspectRatio( const bool locked )
4142{
4143 const double defaultAspectRatio = mLayer->defaultAspectRatio();
4144 if ( defaultAspectRatio <= 0.0 )
4145 {
4146 whileBlocking( mLockAspectRatio )->setLocked( true );
4147 }
4148 else if ( locked )
4149 {
4151 setWidth();
4152 }
4153 else
4154 {
4155 mLayer->setFixedAspectRatio( mHeightSpinBox->value() / mWidthSpinBox->value() );
4156 }
4157}
4158
4159void QgsRasterMarkerSymbolLayerWidget::setAngle()
4160{
4161 mLayer->setAngle( mRotationSpinBox->value() );
4162 emit changed();
4163}
4164
4165void QgsRasterMarkerSymbolLayerWidget::setOpacity( double value )
4166{
4167 mLayer->setOpacity( value );
4168 emit changed();
4169 updatePreviewImage();
4170}
4171
4172void QgsRasterMarkerSymbolLayerWidget::setOffset()
4173{
4174 mLayer->setOffset( QPointF( mSpinOffsetX->value(), mSpinOffsetY->value() ) );
4175 emit changed();
4176}
4177
4178void QgsRasterMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
4179{
4180 if ( mLayer )
4181 {
4182 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
4183 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
4184 emit changed();
4185 }
4186}
4187
4188void QgsRasterMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
4189{
4190 if ( mLayer )
4191 {
4192 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
4193 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
4194 emit changed();
4195 }
4196}
4197
4198void QgsRasterMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
4199{
4200 if ( mLayer )
4201 {
4203 emit changed();
4204 }
4205}
4206
4207void QgsRasterMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
4208{
4209 if ( mLayer )
4210 {
4212 emit changed();
4213 }
4214}
4215
4216
4218
4220 : QgsSymbolLayerWidget( parent, vl )
4221{
4222 mLayer = nullptr;
4223
4224 setupUi( this );
4225
4226 mImageSourceLineEdit->setLastPathSettingsKey( QStringLiteral( "/UI/lastAnimatedMarkerImageDir" ) );
4227
4228 connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsAnimatedMarkerSymbolLayerWidget::imageSourceChanged );
4229 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsAnimatedMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
4230 connect( mRotationSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::setAngle );
4231 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsAnimatedMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
4232 connect( mWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::setWidth );
4233 connect( mHeightSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::setHeight );
4234 connect( mLockAspectRatio, static_cast < void ( QgsRatioLockButton::* )( bool ) > ( &QgsRatioLockButton::lockChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::setLockAspectRatio );
4235
4236 mFrameRateSpin->setClearValue( 10 );
4237 mFrameRateSpin->setShowClearButton( true );
4238 connect( mFrameRateSpin, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value )
4239 {
4240 mLayer->setFrameRate( value );
4241 emit changed();
4242 } );
4243
4248
4249 mSpinOffsetX->setClearValue( 0.0 );
4250 mSpinOffsetY->setClearValue( 0.0 );
4251 mRotationSpinBox->setClearValue( 0.0 );
4252
4253 connect( mSpinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::setOffset );
4254 connect( mSpinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::setOffset );
4255 connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsAnimatedMarkerSymbolLayerWidget::setOpacity );
4256
4257 connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
4258 connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
4259}
4260
4262{
4263 if ( !layer )
4264 {
4265 return;
4266 }
4267
4268 if ( layer->layerType() != QLatin1String( "AnimatedMarker" ) )
4269 return;
4270
4271 // layer type is correct, we can do the cast
4272 mLayer = static_cast<QgsAnimatedMarkerSymbolLayer *>( layer );
4273
4274 // set values
4275 whileBlocking( mImageSourceLineEdit )->setSource( mLayer->path() );
4276
4277 const double firstFrameTime = QgsApplication::imageCache()->nextFrameDelay( mLayer->path() );
4278 if ( firstFrameTime > 0 )
4279 {
4280 mFrameRateSpin->setClearValue( 1000 / firstFrameTime );
4281 }
4282 else
4283 {
4284 mFrameRateSpin->setClearValue( 10 );
4285 }
4286
4287 whileBlocking( mWidthSpinBox )->setValue( mLayer->size() );
4288 const bool preservedAspectRatio = mLayer->preservedAspectRatio();
4289 mHeightSpinBox->blockSignals( true );
4290 if ( preservedAspectRatio )
4291 {
4292 mHeightSpinBox->setValue( mLayer->size() );
4293 }
4294 else
4295 {
4296 mHeightSpinBox->setValue( mLayer->size() * mLayer->fixedAspectRatio() );
4297 }
4298 mHeightSpinBox->setEnabled( mLayer->defaultAspectRatio() > 0.0 );
4299 mHeightSpinBox->blockSignals( false );
4300 whileBlocking( mLockAspectRatio )->setLocked( preservedAspectRatio );
4301
4302 whileBlocking( mRotationSpinBox )->setValue( mLayer->angle() );
4303 whileBlocking( mOpacityWidget )->setOpacity( mLayer->opacity() );
4304
4305 whileBlocking( mSpinOffsetX )->setValue( mLayer->offset().x() );
4306 whileBlocking( mSpinOffsetY )->setValue( mLayer->offset().y() );
4307
4308 whileBlocking( mFrameRateSpin )->setValue( mLayer->frameRate() );
4309
4310 mSizeUnitWidget->blockSignals( true );
4311 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
4312 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
4313 mSizeUnitWidget->blockSignals( false );
4314 mOffsetUnitWidget->blockSignals( true );
4315 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
4316 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
4317 mOffsetUnitWidget->blockSignals( false );
4318
4319 //anchor points
4320 whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mLayer->horizontalAnchorPoint() );
4321 whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mLayer->verticalAnchorPoint() );
4322
4331
4332 updatePreviewImage();
4333}
4334
4336{
4337 return mLayer;
4338}
4339
4341{
4343 mImageSourceLineEdit->setMessageBar( context.messageBar() );
4344}
4345
4346void QgsAnimatedMarkerSymbolLayerWidget::imageSourceChanged( const QString &text )
4347{
4348 mLayer->setPath( text );
4349
4350 const double firstFrameTime = QgsApplication::imageCache()->nextFrameDelay( text );
4351 if ( firstFrameTime > 0 )
4352 {
4353 mFrameRateSpin->setClearValue( 1000 / firstFrameTime );
4354 }
4355 else
4356 {
4357 mFrameRateSpin->setClearValue( 10 );
4358 }
4359 updatePreviewImage();
4360 emit changed();
4361}
4362
4363void QgsAnimatedMarkerSymbolLayerWidget::updatePreviewImage()
4364{
4365 if ( mPreviewMovie )
4366 {
4367 mLabelImagePreview->setMovie( nullptr );
4368 mPreviewMovie->deleteLater();
4369 mPreviewMovie = nullptr;
4370 }
4371
4372 mPreviewMovie = new QMovie( mLayer->path(), QByteArray(), this );
4373 mPreviewMovie->setScaledSize( QSize( 150, 150 ) );
4374 mLabelImagePreview->setMovie( mPreviewMovie );
4375 mPreviewMovie->start();
4376}
4377
4378void QgsAnimatedMarkerSymbolLayerWidget::setWidth()
4379{
4380 const double defaultAspectRatio = mLayer->defaultAspectRatio();
4381 double fixedAspectRatio = 0.0;
4382 mHeightSpinBox->blockSignals( true );
4383 if ( defaultAspectRatio <= 0.0 )
4384 {
4385 mHeightSpinBox->setValue( mWidthSpinBox->value() );
4386 }
4387 else if ( mLockAspectRatio->locked() )
4388 {
4389 mHeightSpinBox->setValue( mWidthSpinBox->value() * defaultAspectRatio );
4390 }
4391 else
4392 {
4393 fixedAspectRatio = mHeightSpinBox->value() / mWidthSpinBox->value();
4394 }
4395 mHeightSpinBox->blockSignals( false );
4396 mLayer->setSize( mWidthSpinBox->value() );
4397 mLayer->setFixedAspectRatio( fixedAspectRatio );
4398 emit changed();
4399}
4400
4401void QgsAnimatedMarkerSymbolLayerWidget::setHeight()
4402{
4403 const double defaultAspectRatio = mLayer->defaultAspectRatio();
4404 double fixedAspectRatio = 0.0;
4405 mWidthSpinBox->blockSignals( true );
4406 if ( defaultAspectRatio <= 0.0 )
4407 {
4408 mWidthSpinBox->setValue( mHeightSpinBox->value() );
4409 }
4410 else if ( mLockAspectRatio->locked() )
4411 {
4412 mWidthSpinBox->setValue( mHeightSpinBox->value() / defaultAspectRatio );
4413 }
4414 else
4415 {
4416 fixedAspectRatio = mHeightSpinBox->value() / mWidthSpinBox->value();
4417 }
4418 mWidthSpinBox->blockSignals( false );
4419 mLayer->setSize( mWidthSpinBox->value() );
4420 mLayer->setFixedAspectRatio( fixedAspectRatio );
4421 emit changed();
4422}
4423
4424void QgsAnimatedMarkerSymbolLayerWidget::setLockAspectRatio( const bool locked )
4425{
4426 const double defaultAspectRatio = mLayer->defaultAspectRatio();
4427 if ( defaultAspectRatio <= 0.0 )
4428 {
4429 whileBlocking( mLockAspectRatio )->setLocked( true );
4430 }
4431 else if ( locked )
4432 {
4434 setWidth();
4435 }
4436 else
4437 {
4438 mLayer->setFixedAspectRatio( mHeightSpinBox->value() / mWidthSpinBox->value() );
4439 }
4440}
4441
4442void QgsAnimatedMarkerSymbolLayerWidget::setAngle()
4443{
4444 mLayer->setAngle( mRotationSpinBox->value() );
4445 emit changed();
4446}
4447
4448void QgsAnimatedMarkerSymbolLayerWidget::setOpacity( double value )
4449{
4450 mLayer->setOpacity( value );
4451 emit changed();
4452 updatePreviewImage();
4453}
4454
4455void QgsAnimatedMarkerSymbolLayerWidget::setOffset()
4456{
4457 mLayer->setOffset( QPointF( mSpinOffsetX->value(), mSpinOffsetY->value() ) );
4458 emit changed();
4459}
4460
4461void QgsAnimatedMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
4462{
4463 if ( mLayer )
4464 {
4465 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
4466 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
4467 emit changed();
4468 }
4469}
4470
4471void QgsAnimatedMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
4472{
4473 if ( mLayer )
4474 {
4475 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
4476 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
4477 emit changed();
4478 }
4479}
4480
4481void QgsAnimatedMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index )
4482{
4483 if ( mLayer )
4484 {
4486 emit changed();
4487 }
4488}
4489
4490void QgsAnimatedMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int index )
4491{
4492 if ( mLayer )
4493 {
4495 emit changed();
4496 }
4497}
4498
4500
4502 : QgsSymbolLayerWidget( parent, vl )
4503{
4504 mLayer = nullptr;
4505 setupUi( this );
4506
4507 mImageSourceLineEdit->setLastPathSettingsKey( QStringLiteral( "/UI/lastRasterMarkerImageDir" ) );
4508 connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsRasterFillSymbolLayerWidget::imageSourceChanged );
4509
4510 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterFillSymbolLayerWidget::mOffsetUnitWidget_changed );
4511 connect( mRotationSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::mRotationSpinBox_valueChanged );
4512 connect( mWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterFillSymbolLayerWidget::mWidthUnitWidget_changed );
4513 connect( mWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::mWidthSpinBox_valueChanged );
4514
4519
4520 mSpinOffsetX->setClearValue( 0.0 );
4521 mSpinOffsetY->setClearValue( 0.0 );
4522 mRotationSpinBox->setClearValue( 0.0 );
4523
4524 connect( cboCoordinateMode, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterFillSymbolLayerWidget::setCoordinateMode );
4525 connect( mSpinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::offsetChanged );
4526 connect( mSpinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::offsetChanged );
4527 connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsRasterFillSymbolLayerWidget::opacityChanged );
4528}
4529
4530
4532{
4533 if ( !layer )
4534 {
4535 return;
4536 }
4537
4538 if ( layer->layerType() != QLatin1String( "RasterFill" ) )
4539 {
4540 return;
4541 }
4542
4543 mLayer = dynamic_cast<QgsRasterFillSymbolLayer *>( layer );
4544 if ( !mLayer )
4545 {
4546 return;
4547 }
4548
4549 whileBlocking( mImageSourceLineEdit )->setSource( mLayer->imageFilePath() );
4550
4551 cboCoordinateMode->blockSignals( true );
4552 switch ( mLayer->coordinateMode() )
4553 {
4555 cboCoordinateMode->setCurrentIndex( 1 );
4556 break;
4558 default:
4559 cboCoordinateMode->setCurrentIndex( 0 );
4560 break;
4561 }
4562 cboCoordinateMode->blockSignals( false );
4563 whileBlocking( mOpacityWidget )->setOpacity( mLayer->opacity() );
4564 whileBlocking( mRotationSpinBox )->setValue( mLayer->angle() );
4565
4566 whileBlocking( mSpinOffsetX )->setValue( mLayer->offset().x() );
4567 whileBlocking( mSpinOffsetY )->setValue( mLayer->offset().y() );
4568 mOffsetUnitWidget->blockSignals( true );
4569 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
4570 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
4571 mOffsetUnitWidget->blockSignals( false );
4572
4573 whileBlocking( mWidthSpinBox )->setValue( mLayer->width() );
4574 mWidthUnitWidget->blockSignals( true );
4575 mWidthUnitWidget->setUnit( mLayer->widthUnit() );
4576 mWidthUnitWidget->setMapUnitScale( mLayer->widthMapUnitScale() );
4577 mWidthUnitWidget->blockSignals( false );
4578
4579 updatePreviewImage();
4580
4586}
4587
4589{
4590 return mLayer;
4591}
4592
4593void QgsRasterFillSymbolLayerWidget::imageSourceChanged( const QString &text )
4594{
4595 mLayer->setImageFilePath( text );
4596 updatePreviewImage();
4597 emit changed();
4598}
4599
4600void QgsRasterFillSymbolLayerWidget::setCoordinateMode( int index )
4601{
4602 switch ( index )
4603 {
4604 case 0:
4605 //feature coordinate mode
4607 break;
4608 case 1:
4609 //viewport coordinate mode
4611 break;
4612 }
4613
4614 emit changed();
4615}
4616
4617void QgsRasterFillSymbolLayerWidget::opacityChanged( double value )
4618{
4619 if ( !mLayer )
4620 {
4621 return;
4622 }
4623
4624 mLayer->setOpacity( value );
4625 emit changed();
4626 updatePreviewImage();
4627}
4628
4629void QgsRasterFillSymbolLayerWidget::offsetChanged()
4630{
4631 mLayer->setOffset( QPointF( mSpinOffsetX->value(), mSpinOffsetY->value() ) );
4632 emit changed();
4633}
4634
4635void QgsRasterFillSymbolLayerWidget::mOffsetUnitWidget_changed()
4636{
4637 if ( !mLayer )
4638 {
4639 return;
4640 }
4641 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
4642 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
4643 emit changed();
4644}
4645
4646void QgsRasterFillSymbolLayerWidget::mRotationSpinBox_valueChanged( double d )
4647{
4648 if ( mLayer )
4649 {
4650 mLayer->setAngle( d );
4651 emit changed();
4652 }
4653}
4654
4655void QgsRasterFillSymbolLayerWidget::mWidthUnitWidget_changed()
4656{
4657 if ( !mLayer )
4658 {
4659 return;
4660 }
4661 mLayer->setWidthUnit( mWidthUnitWidget->unit() );
4662 mLayer->setWidthMapUnitScale( mWidthUnitWidget->getMapUnitScale() );
4663 emit changed();
4664}
4665
4666void QgsRasterFillSymbolLayerWidget::mWidthSpinBox_valueChanged( double d )
4667{
4668 if ( !mLayer )
4669 {
4670 return;
4671 }
4672 mLayer->setWidth( d );
4673 emit changed();
4674}
4675
4676void QgsRasterFillSymbolLayerWidget::updatePreviewImage()
4677{
4678 bool fitsInCache = false;
4679 const QImage image = QgsApplication::imageCache()->pathAsImage( mLayer->imageFilePath(), QSize( 150, 150 ), true, 1.0, fitsInCache );
4680 if ( image.isNull() )
4681 {
4682 mLabelImagePreview->setPixmap( QPixmap() );
4683 return;
4684 }
4685
4686 QImage previewImage( 150, 150, QImage::Format_ARGB32 );
4687 previewImage.fill( Qt::transparent );
4688 const QRect imageRect( ( 150 - image.width() ) / 2.0, ( 150 - image.height() ) / 2.0, image.width(), image.height() );
4689 QPainter p;
4690 p.begin( &previewImage );
4691 //draw a checkerboard background
4692 uchar pixDataRGB[] = { 150, 150, 150, 150,
4693 100, 100, 100, 150,
4694 100, 100, 100, 150,
4695 150, 150, 150, 150
4696 };
4697 const QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
4698 const QPixmap pix = QPixmap::fromImage( img.scaled( 8, 8 ) );
4699 QBrush checkerBrush;
4700 checkerBrush.setTexture( pix );
4701 p.fillRect( imageRect, checkerBrush );
4702
4703 if ( mLayer->opacity() < 1.0 )
4704 {
4705 p.setOpacity( mLayer->opacity() );
4706 }
4707
4708 p.drawImage( imageRect.left(), imageRect.top(), image );
4709 p.end();
4710 mLabelImagePreview->setPixmap( QPixmap::fromImage( previewImage ) );
4711}
4712
4713//
4714// QgsRasterLineSymbolLayerWidget
4715//
4716
4717
4719 : QgsSymbolLayerWidget( parent, vl )
4720{
4721 mLayer = nullptr;
4722 setupUi( this );
4723
4724 mImageSourceLineEdit->setLastPathSettingsKey( Q