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