QGIS API Documentation 3.99.0-Master (2fe06baccd8)
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
19#include "characterwidget.h"
20#include "qgsapplication.h"
21#include "qgsauxiliarystorage.h"
22#include "qgscolorramp.h"
23#include "qgscolorrampbutton.h"
24#include "qgsdashspacedialog.h"
26#include "qgsfillsymbol.h"
27#include "qgsfillsymbollayer.h"
28#include "qgsfontutils.h"
30#include "qgsiconutils.h"
31#include "qgsimagecache.h"
33#include "qgslinesymbol.h"
34#include "qgslinesymbollayer.h"
35#include "qgsmapcanvas.h"
36#include "qgsmarkersymbol.h"
41#include "qgsproperty.h"
42#include "qgssvgcache.h"
44#include "qgssymbollayerutils.h"
45#include "qgsvectorlayer.h"
46
47#include <QAbstractButton>
48#include <QAction>
49#include <QBuffer>
50#include <QButtonGroup>
51#include <QColorDialog>
52#include <QCursor>
53#include <QDir>
54#include <QFileDialog>
55#include <QInputDialog>
56#include <QMenu>
57#include <QMessageBox>
58#include <QMovie>
59#include <QPainter>
60#include <QRegularExpression>
61#include <QStandardItemModel>
62#include <QSvgRenderer>
63
64#include "moc_qgssymbollayerwidget.cpp"
65
67{
68 if ( auto *lExpressionContext = mContext.expressionContext() )
69 return *lExpressionContext;
70
71 QgsExpressionContext expContext( mContext.globalProjectAtlasMapLayerScopes( vectorLayer() ) );
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, [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, [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, [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 = std::make_shared<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, [this]( double value ) {
274 if ( !mLayer )
275 return;
276
277 mLayer->setTrimDistanceStart( value );
278 emit changed();
279 } );
280 connect( mTrimDistanceStartUnitWidget, &QgsUnitSelectionWidget::changed, this, [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, [this]( double value ) {
289 if ( !mLayer )
290 return;
291
292 mLayer->setTrimDistanceEnd( value );
293 emit changed();
294 } );
295 connect( mTrimDistanceEndUnitWidget, &QgsUnitSelectionWidget::changed, this, [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() );
319 const QgsProperty ddWidth = mLayer->dataDefinedProperties().property( QgsSymbolLayer::Property::StrokeWidth );
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
485 mLayer->setUseCustomDashPattern( checked );
486 emit changed();
487}
488
489void QgsSimpleLineSymbolLayerWidget::mChangePatternButton_clicked()
490{
491 QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( this );
492 if ( panel && panel->dockMode() )
493 {
494 QgsDashSpaceWidget *widget = new QgsDashSpaceWidget( mLayer->customDashVector(), panel );
495 widget->setPanelTitle( tr( "Custom Dash Pattern" ) );
496 widget->setUnit( mDashPatternUnitWidget->unit() );
497 connect( widget, &QgsPanelWidget::widgetChanged, this, [this, widget]() {
498 mLayer->setCustomDashVector( widget->dashDotVector() );
500 } );
502 panel->openPanel( widget );
503 return;
504 }
505
506 QgsDashSpaceDialog d( mLayer->customDashVector() );
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
632 mHorizontalAnchorComboBox->addItem( tr( "Left" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Left ) );
633 mHorizontalAnchorComboBox->addItem( tr( "Horizontal Center" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Center ) );
634 mHorizontalAnchorComboBox->addItem( tr( "Right" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Right ) );
635
636 mVerticalAnchorComboBox->addItem( tr( "Top" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Top ) );
637 mVerticalAnchorComboBox->addItem( tr( "Vertical Center" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Center ) );
638 mVerticalAnchorComboBox->addItem( tr( "Bottom" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Bottom ) );
639
640 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
641 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
642 connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
643 connect( mStrokeStyleComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mStrokeStyleComboBox_currentIndexChanged );
644 connect( mStrokeWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
645 connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
646 connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
650
651 btnChangeColorFill->setAllowOpacity( true );
652 btnChangeColorFill->setColorDialogTitle( tr( "Select Fill Color" ) );
653 btnChangeColorFill->setContext( QStringLiteral( "symbology" ) );
654 btnChangeColorFill->setShowNoColor( true );
655 btnChangeColorFill->setNoColorString( tr( "Transparent Fill" ) );
656 btnChangeColorStroke->setAllowOpacity( true );
657 btnChangeColorStroke->setColorDialogTitle( tr( "Select Stroke Color" ) );
658 btnChangeColorStroke->setContext( QStringLiteral( "symbology" ) );
659 btnChangeColorStroke->setShowNoColor( true );
660 btnChangeColorStroke->setNoColorString( tr( "Transparent Stroke" ) );
661
662 mFillColorDDBtn->registerLinkedWidget( btnChangeColorFill );
663 mStrokeColorDDBtn->registerLinkedWidget( btnChangeColorStroke );
664
665 spinOffsetX->setClearValue( 0.0 );
666 spinOffsetY->setClearValue( 0.0 );
667 spinAngle->setClearValue( 0.0 );
668
669 //make a temporary symbol for the size assistant preview
670 mAssistantPreviewSymbol = std::make_shared<QgsMarkerSymbol>();
671
672 if ( vectorLayer() )
673 mSizeDDBtn->setSymbol( mAssistantPreviewSymbol );
674
675 int size = lstNames->iconSize().width();
676
677 size = std::max( 30, static_cast<int>( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 3 ) ) );
678
679 lstNames->setGridSize( QSize( size * 1.2, size * 1.2 ) );
680 lstNames->setIconSize( QSize( size, size ) );
681
682 const double markerSize = size * 0.8;
684 for ( const Qgis::MarkerShape shape : shapes )
685 {
686 QgsSimpleMarkerSymbolLayer *lyr = new QgsSimpleMarkerSymbolLayer( shape, markerSize );
688 lyr->setColor( QColor( 200, 200, 200 ) );
689 lyr->setStrokeColor( QColor( 0, 0, 0 ) );
690 const QIcon icon = QgsSymbolLayerUtils::symbolLayerPreviewIcon( lyr, Qgis::RenderUnit::Pixels, QSize( size, size ), QgsMapUnitScale(), Qgis::SymbolType::Hybrid, nullptr, QgsScreenProperties( screen() ) );
691 QListWidgetItem *item = new QListWidgetItem( icon, QString(), lstNames );
692 item->setData( Qt::UserRole, static_cast<int>( shape ) );
693 item->setToolTip( QgsSimpleMarkerSymbolLayerBase::encodeShape( shape ) );
694 delete lyr;
695 }
696 // show at least 3 rows
697 lstNames->setMinimumHeight( lstNames->gridSize().height() * 3.1 );
698
699 connect( lstNames, &QListWidget::currentRowChanged, this, &QgsSimpleMarkerSymbolLayerWidget::setShape );
702 connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::penJoinStyleChanged );
703 connect( cboCapStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::penCapStyleChanged );
704 connect( spinSize, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setSize );
705 connect( spinAngle, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setAngle );
706 connect( spinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setOffset );
707 connect( spinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setOffset );
708 connect( this, &QgsSymbolLayerWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::updateAssistantSymbol );
709}
710
712
714{
715 if ( layer->layerType() != QLatin1String( "SimpleMarker" ) )
716 return;
717
718 // layer type is correct, we can do the cast
719 mLayer = static_cast<QgsSimpleMarkerSymbolLayer *>( layer );
720
721 // set values
722 const Qgis::MarkerShape shape = mLayer->shape();
723 for ( int i = 0; i < lstNames->count(); ++i )
724 {
725 if ( static_cast<Qgis::MarkerShape>( lstNames->item( i )->data( Qt::UserRole ).toInt() ) == shape )
726 {
727 lstNames->setCurrentRow( i );
728 break;
729 }
730 }
731 btnChangeColorStroke->blockSignals( true );
732 btnChangeColorStroke->setColor( mLayer->strokeColor() );
733 btnChangeColorStroke->blockSignals( false );
734 btnChangeColorFill->blockSignals( true );
735 btnChangeColorFill->setColor( mLayer->fillColor() );
736 btnChangeColorFill->setEnabled( QgsSimpleMarkerSymbolLayerBase::shapeIsFilled( mLayer->shape() ) );
737 btnChangeColorFill->blockSignals( false );
738 spinSize->blockSignals( true );
739 spinSize->setValue( mLayer->size() );
740 spinSize->blockSignals( false );
741 spinAngle->blockSignals( true );
742 spinAngle->setValue( mLayer->angle() );
743 spinAngle->blockSignals( false );
744 mStrokeStyleComboBox->blockSignals( true );
745 mStrokeStyleComboBox->setPenStyle( mLayer->strokeStyle() );
746 mStrokeStyleComboBox->blockSignals( false );
747 mStrokeWidthSpinBox->blockSignals( true );
748 mStrokeWidthSpinBox->setValue( mLayer->strokeWidth() );
749 mStrokeWidthSpinBox->blockSignals( false );
750 cboJoinStyle->blockSignals( true );
751 cboJoinStyle->setPenJoinStyle( mLayer->penJoinStyle() );
752 cboJoinStyle->blockSignals( false );
753 cboCapStyle->blockSignals( true );
754 cboCapStyle->setPenCapStyle( mLayer->penCapStyle() );
755 cboCapStyle->blockSignals( false );
756
757 // without blocking signals the value gets changed because of slot setOffset()
758 spinOffsetX->blockSignals( true );
759 spinOffsetX->setValue( mLayer->offset().x() );
760 spinOffsetX->blockSignals( false );
761 spinOffsetY->blockSignals( true );
762 spinOffsetY->setValue( mLayer->offset().y() );
763 spinOffsetY->blockSignals( false );
764
765 mSizeUnitWidget->blockSignals( true );
766 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
767 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
768 mSizeUnitWidget->blockSignals( false );
769 mOffsetUnitWidget->blockSignals( true );
770 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
771 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
772 mOffsetUnitWidget->blockSignals( false );
773 mStrokeWidthUnitWidget->blockSignals( true );
774 mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
775 mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
776 mStrokeWidthUnitWidget->blockSignals( false );
777
778 //anchor points
779 mHorizontalAnchorComboBox->blockSignals( true );
780 mVerticalAnchorComboBox->blockSignals( true );
781 mHorizontalAnchorComboBox->setCurrentIndex( mHorizontalAnchorComboBox->findData( QVariant::fromValue( mLayer->horizontalAnchorPoint() ) ) );
782 mVerticalAnchorComboBox->setCurrentIndex( mVerticalAnchorComboBox->findData( QVariant::fromValue( mLayer->verticalAnchorPoint() ) ) );
783 mHorizontalAnchorComboBox->blockSignals( false );
784 mVerticalAnchorComboBox->blockSignals( false );
785
798
799 updateAssistantSymbol();
800}
801
806
807void QgsSimpleMarkerSymbolLayerWidget::setShape()
808{
809 mLayer->setShape( static_cast<Qgis::MarkerShape>( lstNames->currentItem()->data( Qt::UserRole ).toInt() ) );
810 btnChangeColorFill->setEnabled( QgsSimpleMarkerSymbolLayerBase::shapeIsFilled( mLayer->shape() ) );
811 emit changed();
812}
813
815{
816 mLayer->setStrokeColor( color );
817 emit changed();
818}
819
821{
822 mLayer->setColor( color );
823 emit changed();
824}
825
826void QgsSimpleMarkerSymbolLayerWidget::penJoinStyleChanged()
827{
828 mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
829 emit changed();
830}
831
832void QgsSimpleMarkerSymbolLayerWidget::penCapStyleChanged()
833{
834 mLayer->setPenCapStyle( cboCapStyle->penCapStyle() );
835 emit changed();
836}
837
838void QgsSimpleMarkerSymbolLayerWidget::setSize()
839{
840 mLayer->setSize( spinSize->value() );
841 emit changed();
842}
843
844void QgsSimpleMarkerSymbolLayerWidget::setAngle()
845{
846 mLayer->setAngle( spinAngle->value() );
847 emit changed();
848}
849
850void QgsSimpleMarkerSymbolLayerWidget::setOffset()
851{
852 mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
853 emit changed();
854}
855
856void QgsSimpleMarkerSymbolLayerWidget::mStrokeStyleComboBox_currentIndexChanged( int index )
857{
858 Q_UNUSED( index )
859
860 if ( mLayer )
861 {
862 mLayer->setStrokeStyle( mStrokeStyleComboBox->penStyle() );
863 emit changed();
864 }
865}
866
867void QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
868{
869 if ( mLayer )
870 {
871 mLayer->setStrokeWidth( d );
872 emit changed();
873 }
874}
875
876void QgsSimpleMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
877{
878 if ( mLayer )
879 {
880 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
881 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
882 emit changed();
883 }
884}
885
886void QgsSimpleMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
887{
888 if ( mLayer )
889 {
890 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
891 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
892 emit changed();
893 }
894}
895
896void QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
897{
898 if ( mLayer )
899 {
900 mLayer->setStrokeWidthUnit( mStrokeWidthUnitWidget->unit() );
901 mLayer->setStrokeWidthMapUnitScale( mStrokeWidthUnitWidget->getMapUnitScale() );
902 emit changed();
903 }
904}
905
906void QgsSimpleMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int )
907{
908 if ( mLayer )
909 {
910 mLayer->setHorizontalAnchorPoint( mHorizontalAnchorComboBox->currentData().value< Qgis::HorizontalAnchorPoint >() );
911 emit changed();
912 }
913}
914
915void QgsSimpleMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int )
916{
917 if ( mLayer )
918 {
919 mLayer->setVerticalAnchorPoint( mVerticalAnchorComboBox->currentData().value< Qgis::VerticalAnchorPoint >() );
920 emit changed();
921 }
922}
923
924void QgsSimpleMarkerSymbolLayerWidget::updateAssistantSymbol()
925{
926 for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1; i >= 0; --i )
927 {
928 mAssistantPreviewSymbol->deleteSymbolLayer( i );
929 }
930 mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
931 const QgsProperty ddSize = mLayer->dataDefinedProperties().property( QgsSymbolLayer::Property::Size );
932 if ( ddSize )
933 mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
934}
935
936
938
940 : QgsSymbolLayerWidget( parent, vl )
941{
942 mLayer = nullptr;
943
944 setupUi( this );
945 connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleFillSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
946 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleFillSymbolLayerWidget::mOffsetUnitWidget_changed );
949
950 btnChangeColor->setAllowOpacity( true );
951 btnChangeColor->setColorDialogTitle( tr( "Select Fill Color" ) );
952 btnChangeColor->setContext( QStringLiteral( "symbology" ) );
953 btnChangeColor->setShowNoColor( true );
954 btnChangeColor->setNoColorString( tr( "Transparent Fill" ) );
955 btnChangeStrokeColor->setAllowOpacity( true );
956 btnChangeStrokeColor->setColorDialogTitle( tr( "Select Stroke Color" ) );
957 btnChangeStrokeColor->setContext( QStringLiteral( "symbology" ) );
958 btnChangeStrokeColor->setShowNoColor( true );
959 btnChangeStrokeColor->setNoColorString( tr( "Transparent Stroke" ) );
960
961 spinOffsetX->setClearValue( 0.0 );
962 spinOffsetY->setClearValue( 0.0 );
963
965 connect( cboFillStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleFillSymbolLayerWidget::setBrushStyle );
967 connect( spinStrokeWidth, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleFillSymbolLayerWidget::strokeWidthChanged );
968 connect( cboStrokeStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleFillSymbolLayerWidget::strokeStyleChanged );
969 connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleFillSymbolLayerWidget::strokeStyleChanged );
970 connect( spinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleFillSymbolLayerWidget::offsetChanged );
971 connect( spinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleFillSymbolLayerWidget::offsetChanged );
972
973 mFillColorDDBtn->registerLinkedWidget( btnChangeColor );
974 mStrokeColorDDBtn->registerLinkedWidget( btnChangeStrokeColor );
975}
976
978{
979 if ( layer->layerType() != QLatin1String( "SimpleFill" ) )
980 return;
981
982 // layer type is correct, we can do the cast
983 mLayer = static_cast<QgsSimpleFillSymbolLayer *>( layer );
984
985 // set values
986 btnChangeColor->blockSignals( true );
987 btnChangeColor->setColor( mLayer->color() );
988 btnChangeColor->blockSignals( false );
989 cboFillStyle->blockSignals( true );
990 cboFillStyle->setBrushStyle( mLayer->brushStyle() );
991 cboFillStyle->blockSignals( false );
992 btnChangeStrokeColor->blockSignals( true );
993 btnChangeStrokeColor->setColor( mLayer->strokeColor() );
994 btnChangeStrokeColor->blockSignals( false );
995 cboStrokeStyle->blockSignals( true );
996 cboStrokeStyle->setPenStyle( mLayer->strokeStyle() );
997 cboStrokeStyle->blockSignals( false );
998 spinStrokeWidth->blockSignals( true );
999 spinStrokeWidth->setValue( mLayer->strokeWidth() );
1000 spinStrokeWidth->blockSignals( false );
1001 cboJoinStyle->blockSignals( true );
1002 cboJoinStyle->setPenJoinStyle( mLayer->penJoinStyle() );
1003 cboJoinStyle->blockSignals( false );
1004 spinOffsetX->blockSignals( true );
1005 spinOffsetX->setValue( mLayer->offset().x() );
1006 spinOffsetX->blockSignals( false );
1007 spinOffsetY->blockSignals( true );
1008 spinOffsetY->setValue( mLayer->offset().y() );
1009 spinOffsetY->blockSignals( false );
1010
1011 mStrokeWidthUnitWidget->blockSignals( true );
1012 mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
1013 mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
1014 mStrokeWidthUnitWidget->blockSignals( false );
1015 mOffsetUnitWidget->blockSignals( true );
1016 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1017 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1018 mOffsetUnitWidget->blockSignals( false );
1019
1027}
1028
1033
1035{
1036 mLayer->setColor( color );
1037 emit changed();
1038}
1039
1041{
1042 mLayer->setStrokeColor( color );
1043 emit changed();
1044}
1045
1046void QgsSimpleFillSymbolLayerWidget::setBrushStyle()
1047{
1048 mLayer->setBrushStyle( cboFillStyle->brushStyle() );
1049 emit changed();
1050}
1051
1052void QgsSimpleFillSymbolLayerWidget::strokeWidthChanged()
1053{
1054 mLayer->setStrokeWidth( spinStrokeWidth->value() );
1055 emit changed();
1056}
1057
1058void QgsSimpleFillSymbolLayerWidget::strokeStyleChanged()
1059{
1060 mLayer->setStrokeStyle( cboStrokeStyle->penStyle() );
1061 mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
1062 emit changed();
1063}
1064
1065void QgsSimpleFillSymbolLayerWidget::offsetChanged()
1066{
1067 mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1068 emit changed();
1069}
1070
1071void QgsSimpleFillSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
1072{
1073 if ( mLayer )
1074 {
1075 mLayer->setStrokeWidthUnit( mStrokeWidthUnitWidget->unit() );
1076 mLayer->setStrokeWidthMapUnitScale( mStrokeWidthUnitWidget->getMapUnitScale() );
1077 emit changed();
1078 }
1079}
1080
1081void QgsSimpleFillSymbolLayerWidget::mOffsetUnitWidget_changed()
1082{
1083 if ( mLayer )
1084 {
1085 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1086 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1087 emit changed();
1088 }
1089}
1090
1092
1094 : QgsSymbolLayerWidget( parent, vl )
1095{
1096 mLayer = nullptr;
1097
1098 setupUi( this );
1099
1100 mHorizontalAnchorComboBox->addItem( tr( "Left" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Left ) );
1101 mHorizontalAnchorComboBox->addItem( tr( "Horizontal Center" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Center ) );
1102 mHorizontalAnchorComboBox->addItem( tr( "Right" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Right ) );
1103
1104 mVerticalAnchorComboBox->addItem( tr( "Top" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Top ) );
1105 mVerticalAnchorComboBox->addItem( tr( "Vertical Center" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Center ) );
1106 mVerticalAnchorComboBox->addItem( tr( "Bottom" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Bottom ) );
1107
1108 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFilledMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
1109 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFilledMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
1110 connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFilledMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
1111 connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFilledMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
1114
1115 spinOffsetX->setClearValue( 0.0 );
1116 spinOffsetY->setClearValue( 0.0 );
1117 spinAngle->setClearValue( 0.0 );
1118
1119 //make a temporary symbol for the size assistant preview
1120 mAssistantPreviewSymbol = std::make_shared<QgsMarkerSymbol>();
1121
1122 if ( vectorLayer() )
1123 mSizeDDBtn->setSymbol( mAssistantPreviewSymbol );
1124
1125 int size = lstNames->iconSize().width();
1126 size = std::max( 30, static_cast<int>( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 3 ) ) );
1127 lstNames->setGridSize( QSize( size * 1.2, size * 1.2 ) );
1128 lstNames->setIconSize( QSize( size, size ) );
1129
1130 const double markerSize = size * 0.8;
1132 for ( const Qgis::MarkerShape shape : shapes )
1133 {
1134 QgsSimpleMarkerSymbolLayer *lyr = new QgsSimpleMarkerSymbolLayer( shape, markerSize );
1136 lyr->setColor( QColor( 200, 200, 200 ) );
1137 lyr->setStrokeColor( QColor( 0, 0, 0 ) );
1138 const QIcon icon = QgsSymbolLayerUtils::symbolLayerPreviewIcon( lyr, Qgis::RenderUnit::Pixels, QSize( size, size ), QgsMapUnitScale(), Qgis::SymbolType::Hybrid, nullptr, QgsScreenProperties( screen() ) );
1139 QListWidgetItem *item = new QListWidgetItem( icon, QString(), lstNames );
1140 item->setData( Qt::UserRole, static_cast<int>( shape ) );
1141 item->setToolTip( QgsSimpleMarkerSymbolLayerBase::encodeShape( shape ) );
1142 delete lyr;
1143 }
1144 // show at least 3 rows
1145 lstNames->setMinimumHeight( lstNames->gridSize().height() * 3.1 );
1146
1147 connect( lstNames, &QListWidget::currentRowChanged, this, &QgsFilledMarkerSymbolLayerWidget::setShape );
1148 connect( spinSize, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setSize );
1149 connect( spinAngle, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setAngle );
1150 connect( spinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setOffset );
1151 connect( spinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setOffset );
1152 connect( this, &QgsSymbolLayerWidget::changed, this, &QgsFilledMarkerSymbolLayerWidget::updateAssistantSymbol );
1153}
1154
1156
1158{
1159 if ( layer->layerType() != QLatin1String( "FilledMarker" ) )
1160 return;
1161
1162 // layer type is correct, we can do the cast
1163 mLayer = static_cast<QgsFilledMarkerSymbolLayer *>( layer );
1164
1165 // set values
1166 const Qgis::MarkerShape shape = mLayer->shape();
1167 for ( int i = 0; i < lstNames->count(); ++i )
1168 {
1169 if ( static_cast<Qgis::MarkerShape>( lstNames->item( i )->data( Qt::UserRole ).toInt() ) == shape )
1170 {
1171 lstNames->setCurrentRow( i );
1172 break;
1173 }
1174 }
1175 whileBlocking( spinSize )->setValue( mLayer->size() );
1176 whileBlocking( spinAngle )->setValue( mLayer->angle() );
1177 whileBlocking( spinOffsetX )->setValue( mLayer->offset().x() );
1178 whileBlocking( spinOffsetY )->setValue( mLayer->offset().y() );
1179
1180 mSizeUnitWidget->blockSignals( true );
1181 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
1182 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
1183 mSizeUnitWidget->blockSignals( false );
1184 mOffsetUnitWidget->blockSignals( true );
1185 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1186 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1187 mOffsetUnitWidget->blockSignals( false );
1188
1189 //anchor points
1190 whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mHorizontalAnchorComboBox->findData( QVariant::fromValue( mLayer->horizontalAnchorPoint() ) ) );
1191 whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mVerticalAnchorComboBox->findData( QVariant::fromValue( mLayer->verticalAnchorPoint() ) ) );
1192
1199
1200 updateAssistantSymbol();
1201}
1202
1207
1208void QgsFilledMarkerSymbolLayerWidget::setShape()
1209{
1210 mLayer->setShape( static_cast<Qgis::MarkerShape>( lstNames->currentItem()->data( Qt::UserRole ).toInt() ) );
1211 emit changed();
1212}
1213
1214void QgsFilledMarkerSymbolLayerWidget::setSize()
1215{
1216 mLayer->setSize( spinSize->value() );
1217 emit changed();
1218}
1219
1220void QgsFilledMarkerSymbolLayerWidget::setAngle()
1221{
1222 mLayer->setAngle( spinAngle->value() );
1223 emit changed();
1224}
1225
1226void QgsFilledMarkerSymbolLayerWidget::setOffset()
1227{
1228 mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1229 emit changed();
1230}
1231
1232void QgsFilledMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
1233{
1234 if ( mLayer )
1235 {
1236 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
1237 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
1238 emit changed();
1239 }
1240}
1241
1242void QgsFilledMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
1243{
1244 if ( mLayer )
1245 {
1246 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1247 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1248 emit changed();
1249 }
1250}
1251
1252void QgsFilledMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int )
1253{
1254 if ( mLayer )
1255 {
1256 mLayer->setHorizontalAnchorPoint( mHorizontalAnchorComboBox->currentData().value<Qgis::HorizontalAnchorPoint>() );
1257 emit changed();
1258 }
1259}
1260
1261void QgsFilledMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int )
1262{
1263 if ( mLayer )
1264 {
1265 mLayer->setVerticalAnchorPoint( mVerticalAnchorComboBox->currentData().value< Qgis::VerticalAnchorPoint >() );
1266 emit changed();
1267 }
1268}
1269
1270void QgsFilledMarkerSymbolLayerWidget::updateAssistantSymbol()
1271{
1272 for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1; i >= 0; --i )
1273 {
1274 mAssistantPreviewSymbol->deleteSymbolLayer( i );
1275 }
1276 mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
1277 const QgsProperty ddSize = mLayer->dataDefinedProperties().property( QgsSymbolLayer::Property::Size );
1278 if ( ddSize )
1279 mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
1280}
1281
1282
1284
1286 : QgsSymbolLayerWidget( parent, vl )
1287{
1288 mLayer = nullptr;
1289
1290 setupUi( this );
1291 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsGradientFillSymbolLayerWidget::mOffsetUnitWidget_changed );
1292 connect( mSpinAngle, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::mSpinAngle_valueChanged );
1294
1295 btnColorRamp->setShowGradientOnly( true );
1296
1297 btnChangeColor->setAllowOpacity( true );
1298 btnChangeColor->setColorDialogTitle( tr( "Select Gradient Color" ) );
1299 btnChangeColor->setContext( QStringLiteral( "symbology" ) );
1300 btnChangeColor->setShowNoColor( true );
1301 btnChangeColor->setNoColorString( tr( "Transparent" ) );
1302 btnChangeColor2->setAllowOpacity( true );
1303 btnChangeColor2->setColorDialogTitle( tr( "Select Gradient Color" ) );
1304 btnChangeColor2->setContext( QStringLiteral( "symbology" ) );
1305 btnChangeColor2->setShowNoColor( true );
1306 btnChangeColor2->setNoColorString( tr( "Transparent" ) );
1307
1308 mStartColorDDBtn->registerLinkedWidget( btnChangeColor );
1309 mEndColorDDBtn->registerLinkedWidget( btnChangeColor2 );
1310
1311 spinOffsetX->setClearValue( 0.0 );
1312 spinOffsetY->setClearValue( 0.0 );
1313 mSpinAngle->setClearValue( 0.0 );
1314
1318 connect( cboGradientType, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGradientFillSymbolLayerWidget::setGradientType );
1319 connect( cboCoordinateMode, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGradientFillSymbolLayerWidget::setCoordinateMode );
1320 connect( cboGradientSpread, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGradientFillSymbolLayerWidget::setGradientSpread );
1321 connect( radioTwoColor, &QAbstractButton::toggled, this, &QgsGradientFillSymbolLayerWidget::colorModeChanged );
1322 connect( spinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::offsetChanged );
1323 connect( spinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::offsetChanged );
1324 connect( spinRefPoint1X, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1325 connect( spinRefPoint1Y, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1326 connect( checkRefPoint1Centroid, &QAbstractButton::toggled, this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1327 connect( spinRefPoint2X, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1328 connect( spinRefPoint2Y, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1329 connect( checkRefPoint2Centroid, &QAbstractButton::toggled, this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1330}
1331
1333{
1334 if ( layer->layerType() != QLatin1String( "GradientFill" ) )
1335 return;
1336
1337 // layer type is correct, we can do the cast
1338 mLayer = static_cast<QgsGradientFillSymbolLayer *>( layer );
1339
1340 // set values
1341 btnChangeColor->blockSignals( true );
1342 btnChangeColor->setColor( mLayer->color() );
1343 btnChangeColor->blockSignals( false );
1344 btnChangeColor2->blockSignals( true );
1345 btnChangeColor2->setColor( mLayer->color2() );
1346 btnChangeColor2->blockSignals( false );
1347
1348 if ( mLayer->gradientColorType() == Qgis::GradientColorSource::SimpleTwoColor )
1349 {
1350 radioTwoColor->setChecked( true );
1351 btnColorRamp->setEnabled( false );
1352 }
1353 else
1354 {
1355 radioColorRamp->setChecked( true );
1356 btnChangeColor->setEnabled( false );
1357 btnChangeColor2->setEnabled( false );
1358 }
1359
1360 // set source color ramp
1361 if ( mLayer->colorRamp() )
1362 {
1363 btnColorRamp->blockSignals( true );
1364 btnColorRamp->setColorRamp( mLayer->colorRamp() );
1365 btnColorRamp->blockSignals( false );
1366 }
1367
1368 cboGradientType->blockSignals( true );
1369 switch ( mLayer->gradientType() )
1370 {
1372 cboGradientType->setCurrentIndex( 0 );
1373 break;
1375 cboGradientType->setCurrentIndex( 1 );
1376 break;
1378 cboGradientType->setCurrentIndex( 2 );
1379 break;
1380 }
1381 cboGradientType->blockSignals( false );
1382
1383 cboCoordinateMode->blockSignals( true );
1384 switch ( mLayer->coordinateMode() )
1385 {
1387 cboCoordinateMode->setCurrentIndex( 1 );
1388 checkRefPoint1Centroid->setEnabled( false );
1389 checkRefPoint2Centroid->setEnabled( false );
1390 break;
1392 default:
1393 cboCoordinateMode->setCurrentIndex( 0 );
1394 break;
1395 }
1396 cboCoordinateMode->blockSignals( false );
1397
1398 cboGradientSpread->blockSignals( true );
1399 switch ( mLayer->gradientSpread() )
1400 {
1402 cboGradientSpread->setCurrentIndex( 0 );
1403 break;
1405 cboGradientSpread->setCurrentIndex( 1 );
1406 break;
1408 cboGradientSpread->setCurrentIndex( 2 );
1409 break;
1410 }
1411 cboGradientSpread->blockSignals( false );
1412
1413 spinRefPoint1X->blockSignals( true );
1414 spinRefPoint1X->setValue( mLayer->referencePoint1().x() );
1415 spinRefPoint1X->blockSignals( false );
1416 spinRefPoint1Y->blockSignals( true );
1417 spinRefPoint1Y->setValue( mLayer->referencePoint1().y() );
1418 spinRefPoint1Y->blockSignals( false );
1419 checkRefPoint1Centroid->blockSignals( true );
1420 checkRefPoint1Centroid->setChecked( mLayer->referencePoint1IsCentroid() );
1421 if ( mLayer->referencePoint1IsCentroid() )
1422 {
1423 spinRefPoint1X->setEnabled( false );
1424 spinRefPoint1Y->setEnabled( false );
1425 }
1426 checkRefPoint1Centroid->blockSignals( false );
1427 spinRefPoint2X->blockSignals( true );
1428 spinRefPoint2X->setValue( mLayer->referencePoint2().x() );
1429 spinRefPoint2X->blockSignals( false );
1430 spinRefPoint2Y->blockSignals( true );
1431 spinRefPoint2Y->setValue( mLayer->referencePoint2().y() );
1432 spinRefPoint2Y->blockSignals( false );
1433 checkRefPoint2Centroid->blockSignals( true );
1434 checkRefPoint2Centroid->setChecked( mLayer->referencePoint2IsCentroid() );
1435 if ( mLayer->referencePoint2IsCentroid() )
1436 {
1437 spinRefPoint2X->setEnabled( false );
1438 spinRefPoint2Y->setEnabled( false );
1439 }
1440 checkRefPoint2Centroid->blockSignals( false );
1441
1442 spinOffsetX->blockSignals( true );
1443 spinOffsetX->setValue( mLayer->offset().x() );
1444 spinOffsetX->blockSignals( false );
1445 spinOffsetY->blockSignals( true );
1446 spinOffsetY->setValue( mLayer->offset().y() );
1447 spinOffsetY->blockSignals( false );
1448 mSpinAngle->blockSignals( true );
1449 mSpinAngle->setValue( mLayer->angle() );
1450 mSpinAngle->blockSignals( false );
1451
1452 mOffsetUnitWidget->blockSignals( true );
1453 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1454 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1455 mOffsetUnitWidget->blockSignals( false );
1456
1470}
1471
1476
1478{
1479 mLayer->setColor( color );
1480 emit changed();
1481}
1482
1484{
1485 mLayer->setColor2( color );
1486 emit changed();
1487}
1488
1489void QgsGradientFillSymbolLayerWidget::colorModeChanged()
1490{
1491 if ( radioTwoColor->isChecked() )
1492 {
1494 }
1495 else
1496 {
1497 mLayer->setGradientColorType( Qgis::GradientColorSource::ColorRamp );
1498 }
1499 emit changed();
1500}
1501
1503{
1504 if ( btnColorRamp->isNull() )
1505 return;
1506
1507 mLayer->setColorRamp( btnColorRamp->colorRamp()->clone() );
1508 emit changed();
1509}
1510
1512{
1513 switch ( index )
1514 {
1515 case 0:
1516 mLayer->setGradientType( Qgis::GradientType::Linear );
1517 //set sensible default reference points
1518 spinRefPoint1X->setValue( 0.5 );
1519 spinRefPoint1Y->setValue( 0 );
1520 spinRefPoint2X->setValue( 0.5 );
1521 spinRefPoint2Y->setValue( 1 );
1522 break;
1523 case 1:
1524 mLayer->setGradientType( Qgis::GradientType::Radial );
1525 //set sensible default reference points
1526 spinRefPoint1X->setValue( 0 );
1527 spinRefPoint1Y->setValue( 0 );
1528 spinRefPoint2X->setValue( 1 );
1529 spinRefPoint2Y->setValue( 1 );
1530 break;
1531 case 2:
1532 mLayer->setGradientType( Qgis::GradientType::Conical );
1533 spinRefPoint1X->setValue( 0.5 );
1534 spinRefPoint1Y->setValue( 0.5 );
1535 spinRefPoint2X->setValue( 1 );
1536 spinRefPoint2Y->setValue( 1 );
1537 break;
1538 }
1539 emit changed();
1540}
1541
1543{
1544 switch ( index )
1545 {
1546 case 0:
1547 //feature coordinate mode
1549 //allow choice of centroid reference positions
1550 checkRefPoint1Centroid->setEnabled( true );
1551 checkRefPoint2Centroid->setEnabled( true );
1552 break;
1553 case 1:
1554 //viewport coordinate mode
1556 //disable choice of centroid reference positions
1557 checkRefPoint1Centroid->setChecked( Qt::Unchecked );
1558 checkRefPoint1Centroid->setEnabled( false );
1559 checkRefPoint2Centroid->setChecked( Qt::Unchecked );
1560 checkRefPoint2Centroid->setEnabled( false );
1561 break;
1562 }
1563
1564 emit changed();
1565}
1566
1568{
1569 switch ( index )
1570 {
1571 case 0:
1572 mLayer->setGradientSpread( Qgis::GradientSpread::Pad );
1573 break;
1574 case 1:
1575 mLayer->setGradientSpread( Qgis::GradientSpread::Repeat );
1576 break;
1577 case 2:
1578 mLayer->setGradientSpread( Qgis::GradientSpread::Reflect );
1579 break;
1580 }
1581
1582 emit changed();
1583}
1584
1585void QgsGradientFillSymbolLayerWidget::offsetChanged()
1586{
1587 mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1588 emit changed();
1589}
1590
1591void QgsGradientFillSymbolLayerWidget::referencePointChanged()
1592{
1593 mLayer->setReferencePoint1( QPointF( spinRefPoint1X->value(), spinRefPoint1Y->value() ) );
1594 mLayer->setReferencePoint1IsCentroid( checkRefPoint1Centroid->isChecked() );
1595 mLayer->setReferencePoint2( QPointF( spinRefPoint2X->value(), spinRefPoint2Y->value() ) );
1596 mLayer->setReferencePoint2IsCentroid( checkRefPoint2Centroid->isChecked() );
1597 emit changed();
1598}
1599
1600void QgsGradientFillSymbolLayerWidget::mSpinAngle_valueChanged( double value )
1601{
1602 mLayer->setAngle( value );
1603 emit changed();
1604}
1605
1606void QgsGradientFillSymbolLayerWidget::mOffsetUnitWidget_changed()
1607{
1608 if ( mLayer )
1609 {
1610 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1611 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1612 emit changed();
1613 }
1614}
1615
1617
1619 : QgsSymbolLayerWidget( parent, vl )
1620{
1621 mLayer = nullptr;
1622
1623 setupUi( this );
1624 connect( mSpinBlurRadius, qOverload<int>( &QSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::mSpinBlurRadius_valueChanged );
1625 connect( mSpinMaxDistance, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::mSpinMaxDistance_valueChanged );
1626 connect( mDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsShapeburstFillSymbolLayerWidget::mDistanceUnitWidget_changed );
1627 connect( mRadioUseWholeShape, &QRadioButton::toggled, this, &QgsShapeburstFillSymbolLayerWidget::mRadioUseWholeShape_toggled );
1628 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsShapeburstFillSymbolLayerWidget::mOffsetUnitWidget_changed );
1629 connect( mIgnoreRingsCheckBox, &QCheckBox::stateChanged, this, &QgsShapeburstFillSymbolLayerWidget::mIgnoreRingsCheckBox_stateChanged );
1632
1633 QButtonGroup *group1 = new QButtonGroup( this );
1634 group1->addButton( radioColorRamp );
1635 group1->addButton( radioTwoColor );
1636 QButtonGroup *group2 = new QButtonGroup( this );
1637 group2->addButton( mRadioUseMaxDistance );
1638 group2->addButton( mRadioUseWholeShape );
1639 btnChangeColor->setAllowOpacity( true );
1640 btnChangeColor->setColorDialogTitle( tr( "Select Gradient Color" ) );
1641 btnChangeColor->setContext( QStringLiteral( "symbology" ) );
1642 btnChangeColor->setShowNoColor( true );
1643 btnChangeColor->setNoColorString( tr( "Transparent" ) );
1644 btnChangeColor2->setAllowOpacity( true );
1645 btnChangeColor2->setColorDialogTitle( tr( "Select Gradient Color" ) );
1646 btnChangeColor2->setContext( QStringLiteral( "symbology" ) );
1647 btnChangeColor2->setShowNoColor( true );
1648 btnChangeColor2->setNoColorString( tr( "Transparent" ) );
1649
1650 mStartColorDDBtn->registerLinkedWidget( btnChangeColor );
1651 mEndColorDDBtn->registerLinkedWidget( btnChangeColor2 );
1652
1653 spinOffsetX->setClearValue( 0.0 );
1654 spinOffsetY->setClearValue( 0.0 );
1655 mSpinMaxDistance->setClearValue( 5.0 );
1656
1657 btnColorRamp->setShowGradientOnly( true );
1658
1659 connect( btnColorRamp, &QgsColorRampButton::colorRampChanged, this, &QgsShapeburstFillSymbolLayerWidget::applyColorRamp );
1660
1663 connect( radioTwoColor, &QAbstractButton::toggled, this, &QgsShapeburstFillSymbolLayerWidget::colorModeChanged );
1664 connect( spinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::offsetChanged );
1665 connect( spinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::offsetChanged );
1666
1667 connect( mBlurSlider, &QAbstractSlider::valueChanged, mSpinBlurRadius, &QSpinBox::setValue );
1668 connect( mSpinBlurRadius, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ), mBlurSlider, &QAbstractSlider::setValue );
1669}
1670
1672{
1673 if ( layer->layerType() != QLatin1String( "ShapeburstFill" ) )
1674 return;
1675
1676 // layer type is correct, we can do the cast
1677 mLayer = static_cast<QgsShapeburstFillSymbolLayer *>( layer );
1678
1679 // set values
1680 btnChangeColor->blockSignals( true );
1681 btnChangeColor->setColor( mLayer->color() );
1682 btnChangeColor->blockSignals( false );
1683 btnChangeColor2->blockSignals( true );
1684 btnChangeColor2->setColor( mLayer->color2() );
1685 btnChangeColor2->blockSignals( false );
1686
1688 {
1689 radioTwoColor->setChecked( true );
1690 btnColorRamp->setEnabled( false );
1691 }
1692 else
1693 {
1694 radioColorRamp->setChecked( true );
1695 btnChangeColor->setEnabled( false );
1696 btnChangeColor2->setEnabled( false );
1697 }
1698
1699 mSpinBlurRadius->blockSignals( true );
1700 mBlurSlider->blockSignals( true );
1701 mSpinBlurRadius->setValue( mLayer->blurRadius() );
1702 mBlurSlider->setValue( mLayer->blurRadius() );
1703 mSpinBlurRadius->blockSignals( false );
1704 mBlurSlider->blockSignals( false );
1705
1706 mSpinMaxDistance->blockSignals( true );
1707 mSpinMaxDistance->setValue( mLayer->maxDistance() );
1708 mSpinMaxDistance->blockSignals( false );
1709
1710 mRadioUseWholeShape->blockSignals( true );
1711 mRadioUseMaxDistance->blockSignals( true );
1712 if ( mLayer->useWholeShape() )
1713 {
1714 mRadioUseWholeShape->setChecked( true );
1715 mSpinMaxDistance->setEnabled( false );
1716 mDistanceUnitWidget->setEnabled( false );
1717 }
1718 else
1719 {
1720 mRadioUseMaxDistance->setChecked( true );
1721 mSpinMaxDistance->setEnabled( true );
1722 mDistanceUnitWidget->setEnabled( true );
1723 }
1724 mRadioUseWholeShape->blockSignals( false );
1725 mRadioUseMaxDistance->blockSignals( false );
1726
1727 mDistanceUnitWidget->blockSignals( true );
1728 mDistanceUnitWidget->setUnit( mLayer->distanceUnit() );
1729 mDistanceUnitWidget->setMapUnitScale( mLayer->distanceMapUnitScale() );
1730 mDistanceUnitWidget->blockSignals( false );
1731
1732 mIgnoreRingsCheckBox->blockSignals( true );
1733 mIgnoreRingsCheckBox->setCheckState( mLayer->ignoreRings() ? Qt::Checked : Qt::Unchecked );
1734 mIgnoreRingsCheckBox->blockSignals( false );
1735
1736 // set source color ramp
1737 if ( mLayer->colorRamp() )
1738 {
1739 btnColorRamp->blockSignals( true );
1740 btnColorRamp->setColorRamp( mLayer->colorRamp() );
1741 btnColorRamp->blockSignals( false );
1742 }
1743
1744 spinOffsetX->blockSignals( true );
1745 spinOffsetX->setValue( mLayer->offset().x() );
1746 spinOffsetX->blockSignals( false );
1747 spinOffsetY->blockSignals( true );
1748 spinOffsetY->setValue( mLayer->offset().y() );
1749 spinOffsetY->blockSignals( false );
1750 mOffsetUnitWidget->blockSignals( true );
1751 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1752 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1753 mOffsetUnitWidget->blockSignals( false );
1754
1762}
1763
1768
1770{
1771 if ( mLayer )
1772 {
1773 mLayer->setColor( color );
1774 emit changed();
1775 }
1776}
1777
1779{
1780 if ( mLayer )
1781 {
1782 mLayer->setColor2( color );
1783 emit changed();
1784 }
1785}
1786
1787void QgsShapeburstFillSymbolLayerWidget::colorModeChanged()
1788{
1789 if ( !mLayer )
1790 {
1791 return;
1792 }
1793
1794 if ( radioTwoColor->isChecked() )
1795 {
1797 }
1798 else
1799 {
1801 }
1802 emit changed();
1803}
1804
1805void QgsShapeburstFillSymbolLayerWidget::mSpinBlurRadius_valueChanged( int value )
1806{
1807 if ( mLayer )
1808 {
1809 mLayer->setBlurRadius( value );
1810 emit changed();
1811 }
1812}
1813
1814void QgsShapeburstFillSymbolLayerWidget::mSpinMaxDistance_valueChanged( double value )
1815{
1816 if ( mLayer )
1817 {
1818 mLayer->setMaxDistance( value );
1819 emit changed();
1820 }
1821}
1822
1823void QgsShapeburstFillSymbolLayerWidget::mDistanceUnitWidget_changed()
1824{
1825 if ( mLayer )
1826 {
1827 mLayer->setDistanceUnit( mDistanceUnitWidget->unit() );
1828 mLayer->setDistanceMapUnitScale( mDistanceUnitWidget->getMapUnitScale() );
1829 emit changed();
1830 }
1831}
1832
1833void QgsShapeburstFillSymbolLayerWidget::mRadioUseWholeShape_toggled( bool value )
1834{
1835 if ( mLayer )
1836 {
1837 mLayer->setUseWholeShape( value );
1838 mDistanceUnitWidget->setEnabled( !value );
1839 emit changed();
1840 }
1841}
1842
1843void QgsShapeburstFillSymbolLayerWidget::applyColorRamp()
1844{
1845 QgsColorRamp *ramp = btnColorRamp->colorRamp();
1846 if ( !ramp )
1847 return;
1848
1849 mLayer->setColorRamp( ramp );
1850 emit changed();
1851}
1852
1853void QgsShapeburstFillSymbolLayerWidget::offsetChanged()
1854{
1855 if ( mLayer )
1856 {
1857 mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1858 emit changed();
1859 }
1860}
1861
1862void QgsShapeburstFillSymbolLayerWidget::mOffsetUnitWidget_changed()
1863{
1864 if ( mLayer )
1865 {
1866 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1867 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1868 emit changed();
1869 }
1870}
1871
1872
1873void QgsShapeburstFillSymbolLayerWidget::mIgnoreRingsCheckBox_stateChanged( int state )
1874{
1875 const bool checked = ( state == Qt::Checked );
1876 mLayer->setIgnoreRings( checked );
1877 emit changed();
1878}
1879
1881
1883 : QgsSymbolLayerWidget( parent, vl )
1884 , mSymbolType( symbolType )
1885{
1886 mLayer = nullptr;
1887
1888 setupUi( this );
1889 connect( mIntervalUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsTemplatedLineSymbolLayerWidget::mIntervalUnitWidget_changed );
1890 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsTemplatedLineSymbolLayerWidget::mOffsetUnitWidget_changed );
1891 connect( mOffsetAlongLineUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsTemplatedLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed );
1892 connect( mAverageAngleUnit, &QgsUnitSelectionWidget::changed, this, &QgsTemplatedLineSymbolLayerWidget::averageAngleUnitChanged );
1897
1898 mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconAllRings.svg" ) ), tr( "All Rings" ), QgsLineSymbolLayer::AllRings );
1899 mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconExteriorRing.svg" ) ), tr( "Exterior Ring Only" ), QgsLineSymbolLayer::ExteriorRingOnly );
1900 mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconInteriorRings.svg" ) ), tr( "Interior Rings Only" ), QgsLineSymbolLayer::InteriorRingsOnly );
1901 connect( mRingFilterComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
1902 if ( mLayer )
1903 {
1904 mLayer->setRingFilter( static_cast<QgsLineSymbolLayer::RenderRingFilter>( mRingFilterComboBox->currentData().toInt() ) );
1905 emit changed();
1906 }
1907 } );
1908
1909 spinOffset->setClearValue( 0.0 );
1910 mSpinOffsetAlongLine->setClearValue( 0.0 );
1911 mHashRotationSpinBox->setClearValue( 0 );
1912 mSpinAverageAngleLength->setClearValue( 4.0 );
1913
1914 connect( spinInterval, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsTemplatedLineSymbolLayerWidget::setInterval );
1915 connect( mSpinOffsetAlongLine, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsTemplatedLineSymbolLayerWidget::setOffsetAlongLine );
1916 connect( mSpinHashLength, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsTemplatedLineSymbolLayerWidget::setHashLength );
1917 connect( mHashRotationSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsTemplatedLineSymbolLayerWidget::setHashAngle );
1918 connect( chkRotateMarker, &QAbstractButton::clicked, this, &QgsTemplatedLineSymbolLayerWidget::setRotate );
1919 connect( spinOffset, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsTemplatedLineSymbolLayerWidget::setOffset );
1920 connect( mSpinAverageAngleLength, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsTemplatedLineSymbolLayerWidget::setAverageAngle );
1921
1922 connect( mCheckInterval, &QCheckBox::toggled, this, &QgsTemplatedLineSymbolLayerWidget::setPlacement );
1923 connect( mCheckVertex, &QCheckBox::toggled, this, &QgsTemplatedLineSymbolLayerWidget::setPlacement );
1924 connect( mCheckVertexLast, &QCheckBox::toggled, this, &QgsTemplatedLineSymbolLayerWidget::setPlacement );
1925 connect( mCheckVertexFirst, &QCheckBox::toggled, this, &QgsTemplatedLineSymbolLayerWidget::setPlacement );
1926 connect( mCheckCentralPoint, &QCheckBox::toggled, this, &QgsTemplatedLineSymbolLayerWidget::setPlacement );
1927 connect( mCheckCurvePoint, &QCheckBox::toggled, this, &QgsTemplatedLineSymbolLayerWidget::setPlacement );
1928 connect( mCheckSegmentCentralPoint, &QCheckBox::toggled, this, &QgsTemplatedLineSymbolLayerWidget::setPlacement );
1929
1930 connect( mCheckPlaceOnEveryPart, &QCheckBox::toggled, this, [this] {
1931 if ( mLayer )
1932 {
1933 mLayer->setPlaceOnEveryPart( mCheckPlaceOnEveryPart->isChecked() );
1934 emit changed();
1935 }
1936 } );
1937
1938
1939 switch ( mSymbolType )
1940 {
1942 {
1943 connect( mHashLengthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsTemplatedLineSymbolLayerWidget::hashLengthUnitWidgetChanged );
1945 mPlacementLabel->setText( tr( "Hash placement" ) );
1946 chkRotateMarker->setText( tr( "Rotate hash to follow line direction" ) );
1947 mHashLengthLabel->setVisible( true );
1948 mSpinHashLength->setVisible( true );
1949 mHashLengthUnitWidget->setVisible( true );
1950 mHashLengthDDBtn->setVisible( true );
1951 mHashRotationLabel->setVisible( true );
1952 mHashRotationSpinBox->setVisible( true );
1953 mHashRotationDDBtn->setVisible( true );
1954 break;
1955 }
1956
1958 mPlacementLabel->setText( tr( "Marker placement" ) );
1959 chkRotateMarker->setText( tr( "Rotate marker to follow line direction" ) );
1960 mHashLengthLabel->setVisible( false );
1961 mSpinHashLength->setVisible( false );
1962 mHashLengthUnitWidget->setVisible( false );
1963 mHashLengthDDBtn->setVisible( false );
1964 mHashRotationLabel->setVisible( false );
1965 mHashRotationSpinBox->setVisible( false );
1966 mHashRotationDDBtn->setVisible( false );
1967 }
1968}
1969
1971{
1972 switch ( mSymbolType )
1973 {
1975 if ( layer->layerType() != QLatin1String( "HashLine" ) )
1976 return;
1977 break;
1978
1980 if ( layer->layerType() != QLatin1String( "MarkerLine" ) )
1981 return;
1982 }
1983
1984 // layer type is correct, we can do the cast
1985 mLayer = static_cast<QgsTemplatedLineSymbolLayerBase *>( layer );
1986
1987 // set values
1988 spinInterval->blockSignals( true );
1989 spinInterval->setValue( mLayer->interval() );
1990 spinInterval->blockSignals( false );
1991 mSpinOffsetAlongLine->blockSignals( true );
1992 mSpinOffsetAlongLine->setValue( mLayer->offsetAlongLine() );
1993 mSpinOffsetAlongLine->blockSignals( false );
1994
1995 chkRotateMarker->blockSignals( true );
1996 chkRotateMarker->setChecked( mLayer->rotateSymbols() );
1997 chkRotateMarker->blockSignals( false );
1998 spinOffset->blockSignals( true );
1999 spinOffset->setValue( mLayer->offset() );
2000 spinOffset->blockSignals( false );
2001
2002 whileBlocking( mCheckInterval )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::Interval );
2003 whileBlocking( mCheckVertex )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::InnerVertices || mLayer->placements() & Qgis::MarkerLinePlacement::Vertex );
2004 whileBlocking( mCheckVertexFirst )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::FirstVertex || mLayer->placements() & Qgis::MarkerLinePlacement::Vertex );
2005 whileBlocking( mCheckVertexLast )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::LastVertex || mLayer->placements() & Qgis::MarkerLinePlacement::Vertex );
2006 whileBlocking( mCheckCentralPoint )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::CentralPoint );
2007 whileBlocking( mCheckCurvePoint )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::CurvePoint );
2008 whileBlocking( mCheckSegmentCentralPoint )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::SegmentCenter );
2009 whileBlocking( mCheckPlaceOnEveryPart )->setChecked( mLayer->placeOnEveryPart() );
2010
2011 // set units
2012 mIntervalUnitWidget->blockSignals( true );
2013 mIntervalUnitWidget->setUnit( mLayer->intervalUnit() );
2014 mIntervalUnitWidget->setMapUnitScale( mLayer->intervalMapUnitScale() );
2015 mIntervalUnitWidget->blockSignals( false );
2016 mOffsetUnitWidget->blockSignals( true );
2017 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
2018 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
2019 mOffsetUnitWidget->blockSignals( false );
2020 mOffsetAlongLineUnitWidget->blockSignals( true );
2021 mOffsetAlongLineUnitWidget->setUnit( mLayer->offsetAlongLineUnit() );
2022 mOffsetAlongLineUnitWidget->setMapUnitScale( mLayer->offsetAlongLineMapUnitScale() );
2023 mOffsetAlongLineUnitWidget->blockSignals( false );
2024 whileBlocking( mAverageAngleUnit )->setUnit( mLayer->averageAngleUnit() );
2025 whileBlocking( mAverageAngleUnit )->setMapUnitScale( mLayer->averageAngleMapUnitScale() );
2026 whileBlocking( mSpinAverageAngleLength )->setValue( mLayer->averageAngleLength() );
2027
2028 switch ( mSymbolType )
2029 {
2031 {
2032 QgsHashedLineSymbolLayer *hashLayer = static_cast<QgsHashedLineSymbolLayer *>( mLayer );
2033 whileBlocking( mSpinHashLength )->setValue( hashLayer->hashLength() );
2034 whileBlocking( mHashRotationSpinBox )->setValue( hashLayer->hashAngle() );
2035 whileBlocking( mHashLengthUnitWidget )->setUnit( hashLayer->hashLengthUnit() );
2036 whileBlocking( mHashLengthUnitWidget )->setMapUnitScale( hashLayer->hashLengthMapUnitScale() );
2039 break;
2040 }
2041
2043 break;
2044 }
2045
2046 whileBlocking( mRingFilterComboBox )->setCurrentIndex( mRingFilterComboBox->findData( mLayer->ringFilter() ) );
2047
2048 setPlacement(); // update gui
2049
2055}
2056
2061
2063{
2065
2066 switch ( context.symbolType() )
2067 {
2070 //these settings only have an effect when the symbol layers is part of a fill symbol
2071 mRingFilterComboBox->hide();
2072 mRingsLabel->hide();
2073 break;
2074
2077 break;
2078 }
2079}
2080
2082{
2083 mLayer->setInterval( val );
2084 emit changed();
2085}
2086
2088{
2089 mLayer->setOffsetAlongLine( val );
2090 emit changed();
2091}
2092
2093void QgsTemplatedLineSymbolLayerWidget::setHashLength( double val )
2094{
2095 switch ( mSymbolType )
2096 {
2098 {
2099 QgsHashedLineSymbolLayer *hashLayer = static_cast<QgsHashedLineSymbolLayer *>( mLayer );
2100 hashLayer->setHashLength( val );
2101 emit changed();
2102 break;
2103 }
2104
2106 Q_ASSERT( false );
2107 }
2108}
2109
2110void QgsTemplatedLineSymbolLayerWidget::setHashAngle( double val )
2111{
2112 if ( !mLayer )
2113 return;
2114
2115 switch ( mSymbolType )
2116 {
2118 {
2119 QgsHashedLineSymbolLayer *hashLayer = static_cast<QgsHashedLineSymbolLayer *>( mLayer );
2120 hashLayer->setHashAngle( val );
2121 emit changed();
2122 break;
2123 }
2124
2126 Q_ASSERT( false );
2127 }
2128}
2129
2130void QgsTemplatedLineSymbolLayerWidget::setRotate()
2131{
2132 mSpinAverageAngleLength->setEnabled( chkRotateMarker->isChecked() && ( mCheckInterval->isChecked() || mCheckCentralPoint->isChecked() ) );
2133 mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
2134
2135 mLayer->setRotateSymbols( chkRotateMarker->isChecked() );
2136 emit changed();
2137}
2138
2139void QgsTemplatedLineSymbolLayerWidget::setOffset()
2140{
2141 mLayer->setOffset( spinOffset->value() );
2142 emit changed();
2143}
2144
2145void QgsTemplatedLineSymbolLayerWidget::setPlacement()
2146{
2147 const bool interval = mCheckInterval->isChecked();
2148 spinInterval->setEnabled( interval );
2149 mSpinOffsetAlongLine->setEnabled( mCheckInterval->isChecked() || mCheckVertexLast->isChecked() || mCheckVertexFirst->isChecked() );
2150 mOffsetAlongLineUnitWidget->setEnabled( mSpinOffsetAlongLine->isEnabled() );
2151 mSpinAverageAngleLength->setEnabled( chkRotateMarker->isChecked() && ( mCheckInterval->isChecked() || mCheckCentralPoint->isChecked() ) );
2152 mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
2153 mCheckPlaceOnEveryPart->setEnabled( mCheckVertexLast->isChecked() || mCheckVertexFirst->isChecked() );
2154
2155 Qgis::MarkerLinePlacements placements;
2156 if ( mCheckInterval->isChecked() )
2158 if ( mCheckVertex->isChecked() )
2160 if ( mCheckVertexLast->isChecked() )
2162 if ( mCheckVertexFirst->isChecked() )
2164 if ( mCheckCurvePoint->isChecked() )
2166 if ( mCheckSegmentCentralPoint->isChecked() )
2168 if ( mCheckCentralPoint->isChecked() )
2170 mLayer->setPlacements( placements );
2171
2172 emit changed();
2173}
2174
2175void QgsTemplatedLineSymbolLayerWidget::mIntervalUnitWidget_changed()
2176{
2177 if ( mLayer )
2178 {
2179 mLayer->setIntervalUnit( mIntervalUnitWidget->unit() );
2180 mLayer->setIntervalMapUnitScale( mIntervalUnitWidget->getMapUnitScale() );
2181 emit changed();
2182 }
2183}
2184
2185void QgsTemplatedLineSymbolLayerWidget::mOffsetUnitWidget_changed()
2186{
2187 if ( mLayer )
2188 {
2189 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
2190 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
2191 emit changed();
2192 }
2193}
2194
2195void QgsTemplatedLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed()
2196{
2197 if ( mLayer )
2198 {
2199 mLayer->setOffsetAlongLineUnit( mOffsetAlongLineUnitWidget->unit() );
2200 mLayer->setOffsetAlongLineMapUnitScale( mOffsetAlongLineUnitWidget->getMapUnitScale() );
2201 }
2202 emit changed();
2203}
2204
2205void QgsTemplatedLineSymbolLayerWidget::hashLengthUnitWidgetChanged()
2206{
2207 if ( !mLayer )
2208 return;
2209
2210 switch ( mSymbolType )
2211 {
2213 {
2214 QgsHashedLineSymbolLayer *hashLayer = static_cast<QgsHashedLineSymbolLayer *>( mLayer );
2215 hashLayer->setHashLengthUnit( mHashLengthUnitWidget->unit() );
2216 hashLayer->setHashLengthMapUnitScale( mHashLengthUnitWidget->getMapUnitScale() );
2217 emit changed();
2218 break;
2219 }
2220
2222 Q_ASSERT( false );
2223 }
2224}
2225
2226void QgsTemplatedLineSymbolLayerWidget::averageAngleUnitChanged()
2227{
2228 if ( mLayer )
2229 {
2230 mLayer->setAverageAngleUnit( mAverageAngleUnit->unit() );
2231 mLayer->setAverageAngleMapUnitScale( mAverageAngleUnit->getMapUnitScale() );
2232 }
2233 emit changed();
2234}
2235
2236void QgsTemplatedLineSymbolLayerWidget::setAverageAngle( double val )
2237{
2238 if ( mLayer )
2239 {
2240 mLayer->setAverageAngleLength( val );
2241 emit changed();
2242 }
2243}
2244
2246
2251
2253
2258
2260
2261
2263 : QgsSymbolLayerWidget( parent, vl )
2264{
2265 mLayer = nullptr;
2266
2267 setupUi( this );
2268
2269 mHorizontalAnchorComboBox->addItem( tr( "Left" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Left ) );
2270 mHorizontalAnchorComboBox->addItem( tr( "Horizontal Center" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Center ) );
2271 mHorizontalAnchorComboBox->addItem( tr( "Right" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Right ) );
2272
2273 mVerticalAnchorComboBox->addItem( tr( "Top" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Top ) );
2274 mVerticalAnchorComboBox->addItem( tr( "Vertical Center" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Center ) );
2275 mVerticalAnchorComboBox->addItem( tr( "Bottom" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Bottom ) );
2276
2277 mSvgSelectorWidget->setAllowParameters( true );
2278 mSvgSelectorWidget->sourceLineEdit()->setPropertyOverrideToolButtonVisible( true );
2279 mSvgSelectorWidget->sourceLineEdit()->setLastPathSettingsKey( QStringLiteral( "/UI/lastSVGMarkerDir" ) );
2280 mSvgSelectorWidget->initParametersModel( this, vl );
2281
2282 connect( mSvgSelectorWidget->sourceLineEdit(), &QgsSvgSourceLineEdit::sourceChanged, this, &QgsSvgMarkerSymbolLayerWidget::svgSourceChanged );
2283 connect( mChangeColorButton, &QgsColorButton::colorChanged, this, &QgsSvgMarkerSymbolLayerWidget::mChangeColorButton_colorChanged );
2284 connect( mChangeStrokeColorButton, &QgsColorButton::colorChanged, this, &QgsSvgMarkerSymbolLayerWidget::mChangeStrokeColorButton_colorChanged );
2285 connect( mStrokeWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
2286 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
2287 connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
2288 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
2289 connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSvgMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
2290 connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSvgMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
2294 mChangeColorButton->setAllowOpacity( true );
2295 mChangeColorButton->setColorDialogTitle( tr( "Select Fill color" ) );
2296 mChangeColorButton->setContext( QStringLiteral( "symbology" ) );
2297 mChangeStrokeColorButton->setAllowOpacity( true );
2298 mChangeStrokeColorButton->setColorDialogTitle( tr( "Select Stroke Color" ) );
2299 mChangeStrokeColorButton->setContext( QStringLiteral( "symbology" ) );
2300
2301 mFillColorDDBtn->registerLinkedWidget( mChangeColorButton );
2302 mStrokeColorDDBtn->registerLinkedWidget( mChangeStrokeColorButton );
2303
2304 spinOffsetX->setClearValue( 0.0 );
2305 spinOffsetY->setClearValue( 0.0 );
2306 spinAngle->setClearValue( 0.0 );
2307
2308 connect( spinWidth, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setWidth );
2309 connect( spinHeight, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setHeight );
2310 connect( mLockAspectRatio, static_cast<void ( QgsRatioLockButton::* )( bool )>( &QgsRatioLockButton::lockChanged ), this, &QgsSvgMarkerSymbolLayerWidget::lockAspectRatioChanged );
2311 connect( spinAngle, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setAngle );
2312 connect( spinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setOffset );
2313 connect( spinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setOffset );
2314 connect( this, &QgsSymbolLayerWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::updateAssistantSymbol );
2315
2318
2319 //make a temporary symbol for the size assistant preview
2320 mAssistantPreviewSymbol = std::make_shared<QgsMarkerSymbol>();
2321
2322 if ( vectorLayer() )
2323 {
2324 mWidthDDBtn->setSymbol( mAssistantPreviewSymbol );
2325 mHeightDDBtn->setSymbol( mAssistantPreviewSymbol );
2326 }
2327}
2328
2330
2331#include <QTime>
2332#include <QAbstractListModel>
2333#include <QPixmapCache>
2334#include <QStyle>
2335#include <memory>
2336
2337
2339{
2340 if ( !layer )
2341 {
2342 return;
2343 }
2344
2345 //activate gui for svg parameters only if supported by the svg file
2346 bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2347 QColor defaultFill, defaultStroke;
2348 double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2349 bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
2350 QgsApplication::svgCache()->containsParams( layer->path(), hasFillParam, hasDefaultFillColor, defaultFill, hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity, hasStrokeParam, hasDefaultStrokeColor, defaultStroke, hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth, hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
2351 mChangeColorButton->setEnabled( hasFillParam );
2352 mChangeColorButton->setAllowOpacity( hasFillOpacityParam );
2353 mChangeStrokeColorButton->setEnabled( hasStrokeParam );
2354 mChangeStrokeColorButton->setAllowOpacity( hasStrokeOpacityParam );
2355 mStrokeWidthSpinBox->setEnabled( hasStrokeWidthParam );
2356
2357 if ( hasFillParam )
2358 {
2359 QColor fill = layer->fillColor();
2360 const double existingOpacity = hasFillOpacityParam ? fill.alphaF() : 1.0;
2361 if ( hasDefaultFillColor && !skipDefaultColors )
2362 {
2363 fill = defaultFill;
2364 }
2365 fill.setAlphaF( hasDefaultFillOpacity ? defaultFillOpacity : existingOpacity );
2366 mChangeColorButton->setColor( fill );
2367 }
2368 if ( hasStrokeParam )
2369 {
2370 QColor stroke = layer->strokeColor();
2371 const double existingOpacity = hasStrokeOpacityParam ? stroke.alphaF() : 1.0;
2372 if ( hasDefaultStrokeColor && !skipDefaultColors )
2373 {
2374 stroke = defaultStroke;
2375 }
2376 stroke.setAlphaF( hasDefaultStrokeOpacity ? defaultStrokeOpacity : existingOpacity );
2377 mChangeStrokeColorButton->setColor( stroke );
2378 }
2379
2380 whileBlocking( mSvgSelectorWidget->sourceLineEdit() )->setSource( layer->path() );
2381
2382 mStrokeWidthSpinBox->blockSignals( true );
2383 mStrokeWidthSpinBox->setValue( hasDefaultStrokeWidth ? defaultStrokeWidth : layer->strokeWidth() );
2384 mStrokeWidthSpinBox->blockSignals( false );
2385
2386 const bool preservedAspectRatio = layer->preservedAspectRatio();
2387 spinHeight->blockSignals( true );
2388 if ( preservedAspectRatio )
2389 {
2390 spinHeight->setValue( layer->size() * layer->defaultAspectRatio() );
2391 }
2392 else
2393 {
2394 spinHeight->setValue( layer->size() * layer->fixedAspectRatio() );
2395 }
2396 spinHeight->setEnabled( layer->defaultAspectRatio() > 0.0 );
2397 spinHeight->blockSignals( false );
2398 whileBlocking( mLockAspectRatio )->setLocked( preservedAspectRatio );
2399}
2400
2401void QgsSvgMarkerSymbolLayerWidget::updateAssistantSymbol()
2402{
2403 for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1; i >= 0; --i )
2404 {
2405 mAssistantPreviewSymbol->deleteSymbolLayer( i );
2406 }
2407 mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
2408 const QgsProperty ddSize = mLayer->dataDefinedProperties().property( QgsSymbolLayer::Property::Size );
2409 if ( ddSize )
2410 mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
2411}
2412
2413
2415{
2416 if ( !layer )
2417 {
2418 return;
2419 }
2420
2421 if ( layer->layerType() != QLatin1String( "SvgMarker" ) )
2422 return;
2423
2424 // layer type is correct, we can do the cast
2425 mLayer = static_cast<QgsSvgMarkerSymbolLayer *>( layer );
2426
2427 // set values
2428 mSvgSelectorWidget->setSvgPath( mLayer->path() );
2429 mSvgSelectorWidget->setSvgParameters( mLayer->parameters() );
2430
2431 spinWidth->blockSignals( true );
2432 spinWidth->setValue( mLayer->size() );
2433 spinWidth->blockSignals( false );
2434 spinAngle->blockSignals( true );
2435 spinAngle->setValue( mLayer->angle() );
2436 spinAngle->blockSignals( false );
2437
2438 // without blocking signals the value gets changed because of slot setOffset()
2439 spinOffsetX->blockSignals( true );
2440 spinOffsetX->setValue( mLayer->offset().x() );
2441 spinOffsetX->blockSignals( false );
2442 spinOffsetY->blockSignals( true );
2443 spinOffsetY->setValue( mLayer->offset().y() );
2444 spinOffsetY->blockSignals( false );
2445
2446 mSizeUnitWidget->blockSignals( true );
2447 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
2448 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
2449 mSizeUnitWidget->blockSignals( false );
2450 mStrokeWidthUnitWidget->blockSignals( true );
2451 mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
2452 mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
2453 mStrokeWidthUnitWidget->blockSignals( false );
2454 mOffsetUnitWidget->blockSignals( true );
2455 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
2456 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
2457 mOffsetUnitWidget->blockSignals( false );
2458
2459 //anchor points
2460 mHorizontalAnchorComboBox->blockSignals( true );
2461 mVerticalAnchorComboBox->blockSignals( true );
2462 mHorizontalAnchorComboBox->setCurrentIndex( mHorizontalAnchorComboBox->findData( QVariant::fromValue( mLayer->horizontalAnchorPoint() ) ) );
2463 mVerticalAnchorComboBox->setCurrentIndex( mVerticalAnchorComboBox->findData( QVariant::fromValue( mLayer->verticalAnchorPoint() ) ) );
2464 mHorizontalAnchorComboBox->blockSignals( false );
2465 mVerticalAnchorComboBox->blockSignals( false );
2466
2467 setGuiForSvg( mLayer, true );
2468
2478
2479 registerDataDefinedButton( mSvgSelectorWidget->sourceLineEdit()->propertyOverrideToolButton(), QgsSymbolLayer::Property::Name );
2480
2481 updateAssistantSymbol();
2482}
2483
2488
2490{
2492 mSvgSelectorWidget->sourceLineEdit()->setMessageBar( context.messageBar() );
2493}
2494
2496{
2497 mLayer->setPath( name );
2498 whileBlocking( mSvgSelectorWidget->sourceLineEdit() )->setSource( name );
2499
2501 emit changed();
2502}
2503
2504void QgsSvgMarkerSymbolLayerWidget::setSvgParameters( const QMap<QString, QgsProperty> &parameters )
2505{
2506 mLayer->setParameters( parameters );
2507 whileBlocking( mSvgSelectorWidget )->setSvgParameters( parameters );
2508
2510 emit changed();
2511}
2512
2513void QgsSvgMarkerSymbolLayerWidget::setWidth()
2514{
2515 const double defaultAspectRatio = mLayer->defaultAspectRatio();
2516 double fixedAspectRatio = 0.0;
2517 spinHeight->blockSignals( true );
2518 if ( defaultAspectRatio <= 0.0 )
2519 {
2520 spinHeight->setValue( spinWidth->value() );
2521 }
2522 else if ( mLockAspectRatio->locked() )
2523 {
2524 spinHeight->setValue( spinWidth->value() * defaultAspectRatio );
2525 }
2526 else
2527 {
2528 fixedAspectRatio = spinHeight->value() / spinWidth->value();
2529 }
2530 spinHeight->blockSignals( false );
2531 mLayer->setSize( spinWidth->value() );
2532 mLayer->setFixedAspectRatio( fixedAspectRatio );
2533 emit changed();
2534}
2535
2536void QgsSvgMarkerSymbolLayerWidget::setHeight()
2537{
2538 const double defaultAspectRatio = mLayer->defaultAspectRatio();
2539 double fixedAspectRatio = 0.0;
2540 spinWidth->blockSignals( true );
2541 if ( defaultAspectRatio <= 0.0 )
2542 {
2543 spinWidth->setValue( spinHeight->value() );
2544 }
2545 else if ( mLockAspectRatio->locked() )
2546 {
2547 spinWidth->setValue( spinHeight->value() / defaultAspectRatio );
2548 }
2549 else
2550 {
2551 fixedAspectRatio = spinHeight->value() / spinWidth->value();
2552 }
2553 spinWidth->blockSignals( false );
2554 mLayer->setSize( spinWidth->value() );
2555 mLayer->setFixedAspectRatio( fixedAspectRatio );
2556 emit changed();
2557}
2558
2559void QgsSvgMarkerSymbolLayerWidget::lockAspectRatioChanged( const bool locked )
2560{
2561 //spinHeight->setEnabled( !locked );
2562 const double defaultAspectRatio = mLayer->defaultAspectRatio();
2563 if ( defaultAspectRatio <= 0.0 )
2564 {
2565 whileBlocking( mLockAspectRatio )->setLocked( true );
2566 }
2567 else if ( locked )
2568 {
2569 mLayer->setFixedAspectRatio( 0.0 );
2570 setWidth();
2571 }
2572 else
2573 {
2574 mLayer->setFixedAspectRatio( spinHeight->value() / spinWidth->value() );
2575 }
2576 //emit changed();
2577}
2578
2579void QgsSvgMarkerSymbolLayerWidget::setAngle()
2580{
2581 mLayer->setAngle( spinAngle->value() );
2582 emit changed();
2583}
2584
2585void QgsSvgMarkerSymbolLayerWidget::setOffset()
2586{
2587 mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
2588 emit changed();
2589}
2590
2591void QgsSvgMarkerSymbolLayerWidget::svgSourceChanged( const QString &text )
2592{
2593 mLayer->setPath( text );
2595 emit changed();
2596}
2597
2598void QgsSvgMarkerSymbolLayerWidget::mChangeColorButton_colorChanged( const QColor &color )
2599{
2600 if ( !mLayer )
2601 {
2602 return;
2603 }
2604
2605 mLayer->setFillColor( color );
2606 emit changed();
2607}
2608
2609void QgsSvgMarkerSymbolLayerWidget::mChangeStrokeColorButton_colorChanged( const QColor &color )
2610{
2611 if ( !mLayer )
2612 {
2613 return;
2614 }
2615
2616 mLayer->setStrokeColor( color );
2617 emit changed();
2618}
2619
2620void QgsSvgMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
2621{
2622 if ( mLayer )
2623 {
2624 mLayer->setStrokeWidth( d );
2625 emit changed();
2626 }
2627}
2628
2629void QgsSvgMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
2630{
2631 if ( mLayer )
2632 {
2633 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
2634 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
2635 emit changed();
2636 }
2637}
2638
2639void QgsSvgMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
2640{
2641 if ( mLayer )
2642 {
2643 mLayer->setStrokeWidthUnit( mStrokeWidthUnitWidget->unit() );
2644 mLayer->setStrokeWidthMapUnitScale( mStrokeWidthUnitWidget->getMapUnitScale() );
2645 emit changed();
2646 }
2647}
2648
2649void QgsSvgMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
2650{
2651 if ( mLayer )
2652 {
2653 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
2654 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
2655 emit changed();
2656 }
2657}
2658
2659void QgsSvgMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int )
2660{
2661 if ( mLayer )
2662 {
2663 mLayer->setHorizontalAnchorPoint( mHorizontalAnchorComboBox->currentData().value< Qgis::HorizontalAnchorPoint >() );
2664 emit changed();
2665 }
2666}
2667
2668void QgsSvgMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int )
2669{
2670 if ( mLayer )
2671 {
2672 mLayer->setVerticalAnchorPoint( mVerticalAnchorComboBox->currentData().value< Qgis::VerticalAnchorPoint >() );
2673 emit changed();
2674 }
2675}
2676
2678
2680 : QgsSymbolLayerWidget( parent, vl )
2681{
2682 mLayer = nullptr;
2683 setupUi( this );
2684
2685 mSvgSelectorWidget->setAllowParameters( true );
2686 mSvgSelectorWidget->sourceLineEdit()->setPropertyOverrideToolButtonVisible( true );
2687
2688 connect( mTextureWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mTextureWidthSpinBox_valueChanged );
2689 connect( mSvgSelectorWidget->sourceLineEdit(), &QgsSvgSourceLineEdit::sourceChanged, this, &QgsSVGFillSymbolLayerWidget::svgSourceChanged );
2690 connect( mRotationSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mRotationSpinBox_valueChanged );
2691 connect( mChangeColorButton, &QgsColorButton::colorChanged, this, &QgsSVGFillSymbolLayerWidget::mChangeColorButton_colorChanged );
2692 connect( mChangeStrokeColorButton, &QgsColorButton::colorChanged, this, &QgsSVGFillSymbolLayerWidget::mChangeStrokeColorButton_colorChanged );
2693 connect( mStrokeWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
2694 connect( mTextureWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSVGFillSymbolLayerWidget::mTextureWidthUnitWidget_changed );
2695 connect( mSvgStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSVGFillSymbolLayerWidget::mSvgStrokeWidthUnitWidget_changed );
2698
2699 mRotationSpinBox->setClearValue( 0.0 );
2700
2701 mChangeColorButton->setColorDialogTitle( tr( "Select Fill Color" ) );
2702 mChangeColorButton->setContext( QStringLiteral( "symbology" ) );
2703 mChangeStrokeColorButton->setColorDialogTitle( tr( "Select Stroke Color" ) );
2704 mChangeStrokeColorButton->setContext( QStringLiteral( "symbology" ) );
2705
2706 mFilColorDDBtn->registerLinkedWidget( mChangeColorButton );
2707 mStrokeColorDDBtn->registerLinkedWidget( mChangeStrokeColorButton );
2708
2709 connect( mSvgSelectorWidget, &QgsSvgSelectorWidget::svgSelected, this, &QgsSVGFillSymbolLayerWidget::setFile );
2710 connect( mSvgSelectorWidget, &QgsSvgSelectorWidget::svgParametersChanged, this, &QgsSVGFillSymbolLayerWidget::setSvgParameters );
2711}
2712
2714{
2715 if ( !layer )
2716 {
2717 return;
2718 }
2719
2720 if ( layer->layerType() != QLatin1String( "SVGFill" ) )
2721 {
2722 return;
2723 }
2724
2725 mLayer = dynamic_cast<QgsSVGFillSymbolLayer *>( layer );
2726 if ( mLayer )
2727 {
2728 const double width = mLayer->patternWidth();
2729 mTextureWidthSpinBox->blockSignals( true );
2730 mTextureWidthSpinBox->setValue( width );
2731 mTextureWidthSpinBox->blockSignals( false );
2732 whileBlocking( mSvgSelectorWidget->sourceLineEdit() )->setSource( mLayer->svgFilePath() );
2733 mRotationSpinBox->blockSignals( true );
2734 mRotationSpinBox->setValue( mLayer->angle() );
2735 mRotationSpinBox->blockSignals( false );
2736 mTextureWidthUnitWidget->blockSignals( true );
2737 mTextureWidthUnitWidget->setUnit( mLayer->patternWidthUnit() );
2738 mTextureWidthUnitWidget->setMapUnitScale( mLayer->patternWidthMapUnitScale() );
2739 mTextureWidthUnitWidget->blockSignals( false );
2740 mSvgStrokeWidthUnitWidget->blockSignals( true );
2741 mSvgStrokeWidthUnitWidget->setUnit( mLayer->svgStrokeWidthUnit() );
2742 mSvgStrokeWidthUnitWidget->setMapUnitScale( mLayer->svgStrokeWidthMapUnitScale() );
2743 mSvgStrokeWidthUnitWidget->blockSignals( false );
2744 mChangeColorButton->blockSignals( true );
2745 mChangeColorButton->setColor( mLayer->svgFillColor() );
2746 mChangeColorButton->blockSignals( false );
2747 mChangeStrokeColorButton->blockSignals( true );
2748 mChangeStrokeColorButton->setColor( mLayer->svgStrokeColor() );
2749 mChangeStrokeColorButton->blockSignals( false );
2750 mStrokeWidthSpinBox->blockSignals( true );
2751 mStrokeWidthSpinBox->setValue( mLayer->svgStrokeWidth() );
2752 mStrokeWidthSpinBox->blockSignals( false );
2753 }
2754 updateParamGui( false );
2755
2761
2762 registerDataDefinedButton( mSvgSelectorWidget->sourceLineEdit()->propertyOverrideToolButton(), QgsSymbolLayer::Property::File );
2763}
2764
2769
2771{
2773 mSvgSelectorWidget->sourceLineEdit()->setMessageBar( context.messageBar() );
2774}
2775
2776void QgsSVGFillSymbolLayerWidget::mTextureWidthSpinBox_valueChanged( double d )
2777{
2778 if ( mLayer )
2779 {
2780 mLayer->setPatternWidth( d );
2781 emit changed();
2782 }
2783}
2784
2785void QgsSVGFillSymbolLayerWidget::svgSourceChanged( const QString &text )
2786{
2787 if ( !mLayer )
2788 {
2789 return;
2790 }
2791
2792 mLayer->setSvgFilePath( text );
2794 emit changed();
2795}
2796
2797void QgsSVGFillSymbolLayerWidget::setFile( const QString &name )
2798{
2799 mLayer->setSvgFilePath( name );
2800 whileBlocking( mSvgSelectorWidget->sourceLineEdit() )->setSource( name );
2801
2803 emit changed();
2804}
2805
2806void QgsSVGFillSymbolLayerWidget::setSvgParameters( const QMap<QString, QgsProperty> &parameters )
2807{
2808 mLayer->setParameters( parameters );
2809 whileBlocking( mSvgSelectorWidget )->setSvgParameters( parameters );
2810
2812 emit changed();
2813}
2814
2815
2816void QgsSVGFillSymbolLayerWidget::mRotationSpinBox_valueChanged( double d )
2817{
2818 if ( mLayer )
2819 {
2820 mLayer->setAngle( d );
2821 emit changed();
2822 }
2823}
2824
2826{
2827 //activate gui for svg parameters only if supported by the svg file
2828 bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2829 QColor defaultFill, defaultStroke;
2830 double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2831 bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
2832 QgsApplication::svgCache()->containsParams( mSvgSelectorWidget->sourceLineEdit()->source(), hasFillParam, hasDefaultFillColor, defaultFill, hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity, hasStrokeParam, hasDefaultStrokeColor, defaultStroke, hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth, hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
2833 if ( resetValues )
2834 {
2835 QColor fill = mChangeColorButton->color();
2836 const double newOpacity = hasFillOpacityParam ? fill.alphaF() : 1.0;
2837 if ( hasDefaultFillColor )
2838 {
2839 fill = defaultFill;
2840 }
2841 fill.setAlphaF( hasDefaultFillOpacity ? defaultFillOpacity : newOpacity );
2842 mChangeColorButton->setColor( fill );
2843 }
2844 mChangeColorButton->setEnabled( hasFillParam );
2845 mChangeColorButton->setAllowOpacity( hasFillOpacityParam );
2846 if ( resetValues )
2847 {
2848 QColor stroke = mChangeStrokeColorButton->color();
2849 const double newOpacity = hasStrokeOpacityParam ? stroke.alphaF() : 1.0;
2850 if ( hasDefaultStrokeColor )
2851 {
2852 stroke = defaultStroke;
2853 }
2854 stroke.setAlphaF( hasDefaultStrokeOpacity ? defaultStrokeOpacity : newOpacity );
2855 mChangeStrokeColorButton->setColor( stroke );
2856 }
2857 mChangeStrokeColorButton->setEnabled( hasStrokeParam );
2858 mChangeStrokeColorButton->setAllowOpacity( hasStrokeOpacityParam );
2859 if ( hasDefaultStrokeWidth && resetValues )
2860 {
2861 mStrokeWidthSpinBox->setValue( defaultStrokeWidth );
2862 }
2863 mStrokeWidthSpinBox->setEnabled( hasStrokeWidthParam );
2864}
2865
2866void QgsSVGFillSymbolLayerWidget::mChangeColorButton_colorChanged( const QColor &color )
2867{
2868 if ( !mLayer )
2869 {
2870 return;
2871 }
2872
2873 mLayer->setSvgFillColor( color );
2874 emit changed();
2875}
2876
2877void QgsSVGFillSymbolLayerWidget::mChangeStrokeColorButton_colorChanged( const QColor &color )
2878{
2879 if ( !mLayer )
2880 {
2881 return;
2882 }
2883
2884 mLayer->setSvgStrokeColor( color );
2885 emit changed();
2886}
2887
2888void QgsSVGFillSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
2889{
2890 if ( mLayer )
2891 {
2892 mLayer->setSvgStrokeWidth( d );
2893 emit changed();
2894 }
2895}
2896
2897void QgsSVGFillSymbolLayerWidget::mTextureWidthUnitWidget_changed()
2898{
2899 if ( mLayer )
2900 {
2901 mLayer->setPatternWidthUnit( mTextureWidthUnitWidget->unit() );
2902 mLayer->setPatternWidthMapUnitScale( mTextureWidthUnitWidget->getMapUnitScale() );
2903 emit changed();
2904 }
2905}
2906
2907void QgsSVGFillSymbolLayerWidget::mSvgStrokeWidthUnitWidget_changed()
2908{
2909 if ( mLayer )
2910 {
2911 mLayer->setSvgStrokeWidthUnit( mSvgStrokeWidthUnitWidget->unit() );
2912 mLayer->setSvgStrokeWidthMapUnitScale( mSvgStrokeWidthUnitWidget->getMapUnitScale() );
2913 emit changed();
2914 }
2915}
2916
2918
2920 : QgsSymbolLayerWidget( parent, vl )
2921{
2922 setupUi( this );
2923 connect( mAngleSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLinePatternFillSymbolLayerWidget::mAngleSpinBox_valueChanged );
2924 connect( mDistanceSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLinePatternFillSymbolLayerWidget::mDistanceSpinBox_valueChanged );
2925 connect( mOffsetSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLinePatternFillSymbolLayerWidget::mOffsetSpinBox_valueChanged );
2926 connect( mDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsLinePatternFillSymbolLayerWidget::mDistanceUnitWidget_changed );
2927 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsLinePatternFillSymbolLayerWidget::mOffsetUnitWidget_changed );
2930 mOffsetSpinBox->setClearValue( 0 );
2931 mAngleSpinBox->setClearValue( 0 );
2932
2933 mCoordinateReferenceComboBox->addItem( tr( "Align Pattern to Feature" ), static_cast<int>( Qgis::SymbolCoordinateReference::Feature ) );
2934 mCoordinateReferenceComboBox->addItem( tr( "Align Pattern to Map Extent" ), static_cast<int>( Qgis::SymbolCoordinateReference::Viewport ) );
2935 connect( mCoordinateReferenceComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this] {
2936 if ( mLayer )
2937 {
2938 mLayer->setCoordinateReference( static_cast<Qgis::SymbolCoordinateReference>( mCoordinateReferenceComboBox->currentData().toInt() ) );
2939 emit changed();
2940 }
2941 } );
2942
2943 mClipModeComboBox->addItem( tr( "Clip During Render Only" ), static_cast<int>( Qgis::LineClipMode::ClipPainterOnly ) );
2944 mClipModeComboBox->addItem( tr( "Clip Lines Before Render" ), static_cast<int>( Qgis::LineClipMode::ClipToIntersection ) );
2945 mClipModeComboBox->addItem( tr( "No Clipping" ), static_cast<int>( Qgis::LineClipMode::NoClipping ) );
2946 connect( mClipModeComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this] {
2947 if ( mLayer )
2948 {
2949 mLayer->setClipMode( static_cast<Qgis::LineClipMode>( mClipModeComboBox->currentData().toInt() ) );
2950 emit changed();
2951 }
2952 } );
2953}
2954
2956{
2957 if ( layer->layerType() != QLatin1String( "LinePatternFill" ) )
2958 {
2959 return;
2960 }
2961
2962 QgsLinePatternFillSymbolLayer *patternLayer = static_cast<QgsLinePatternFillSymbolLayer *>( layer );
2963 if ( patternLayer )
2964 {
2965 mLayer = patternLayer;
2966 whileBlocking( mAngleSpinBox )->setValue( mLayer->lineAngle() );
2967 whileBlocking( mDistanceSpinBox )->setValue( mLayer->distance() );
2968 whileBlocking( mOffsetSpinBox )->setValue( mLayer->offset() );
2969
2970 //units
2971 mDistanceUnitWidget->blockSignals( true );
2972 mDistanceUnitWidget->setUnit( mLayer->distanceUnit() );
2973 mDistanceUnitWidget->setMapUnitScale( mLayer->distanceMapUnitScale() );
2974 mDistanceUnitWidget->blockSignals( false );
2975 mOffsetUnitWidget->blockSignals( true );
2976 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
2977 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
2978 mOffsetUnitWidget->blockSignals( false );
2979
2980 whileBlocking( mCoordinateReferenceComboBox )->setCurrentIndex( mCoordinateReferenceComboBox->findData( static_cast<int>( mLayer->coordinateReference() ) ) );
2981
2982 whileBlocking( mClipModeComboBox )->setCurrentIndex( mClipModeComboBox->findData( static_cast<int>( mLayer->clipMode() ) ) );
2983 }
2984
2989}
2990
2995
2996void QgsLinePatternFillSymbolLayerWidget::mAngleSpinBox_valueChanged( double d )
2997{
2998 if ( mLayer )
2999 {
3000 mLayer->setLineAngle( d );
3001 emit changed();
3002 }
3003}
3004
3005void QgsLinePatternFillSymbolLayerWidget::mDistanceSpinBox_valueChanged( double d )
3006{
3007 if ( mLayer )
3008 {
3009 mLayer->setDistance( d );
3010 emit changed();
3011 }
3012}
3013
3014void QgsLinePatternFillSymbolLayerWidget::mOffsetSpinBox_valueChanged( double d )
3015{
3016 if ( mLayer )
3017 {
3018 mLayer->setOffset( d );
3019 emit changed();
3020 }
3021}
3022
3023void QgsLinePatternFillSymbolLayerWidget::mDistanceUnitWidget_changed()
3024{
3025 if ( mLayer )
3026 {
3027 mLayer->setDistanceUnit( mDistanceUnitWidget->unit() );
3028 mLayer->setDistanceMapUnitScale( mDistanceUnitWidget->getMapUnitScale() );
3029 emit changed();
3030 }
3031}
3032
3033void QgsLinePatternFillSymbolLayerWidget::mOffsetUnitWidget_changed()
3034{
3035 if ( mLayer )
3036 {
3037 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
3038 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
3039 emit changed();
3040 }
3041}
3042
3044
3046 : QgsSymbolLayerWidget( parent, vl )
3047{
3048 setupUi( this );
3049 connect( mHorizontalDistanceSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceSpinBox_valueChanged );
3050 connect( mVerticalDistanceSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceSpinBox_valueChanged );
3051 connect( mHorizontalDisplacementSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementSpinBox_valueChanged );
3052 connect( mVerticalDisplacementSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementSpinBox_valueChanged );
3053 connect( mHorizontalOffsetSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetSpinBox_valueChanged );
3054 connect( mVerticalOffsetSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetSpinBox_valueChanged );
3055 connect( mHorizontalDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceUnitWidget_changed );
3056 connect( mVerticalDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceUnitWidget_changed );
3057 connect( mHorizontalDisplacementUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementUnitWidget_changed );
3058 connect( mVerticalDisplacementUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementUnitWidget_changed );
3059 connect( mHorizontalOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetUnitWidget_changed );
3060 connect( mVerticalOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetUnitWidget_changed );
3067
3068 mClipModeComboBox->addItem( tr( "Clip to Shape" ), static_cast<int>( Qgis::MarkerClipMode::Shape ) );
3069 mClipModeComboBox->addItem( tr( "Marker Centroid Within Shape" ), static_cast<int>( Qgis::MarkerClipMode::CentroidWithin ) );
3070 mClipModeComboBox->addItem( tr( "Marker Completely Within Shape" ), static_cast<int>( Qgis::MarkerClipMode::CompletelyWithin ) );
3071 mClipModeComboBox->addItem( tr( "No Clipping" ), static_cast<int>( Qgis::MarkerClipMode::NoClipping ) );
3072 connect( mClipModeComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this] {
3073 if ( mLayer )
3074 {
3075 mLayer->setClipMode( static_cast<Qgis::MarkerClipMode>( mClipModeComboBox->currentData().toInt() ) );
3076 emit changed();
3077 }
3078 } );
3079
3080 mCoordinateReferenceComboBox->addItem( tr( "Align Pattern to Feature" ), static_cast<int>( Qgis::SymbolCoordinateReference::Feature ) );
3081 mCoordinateReferenceComboBox->addItem( tr( "Align Pattern to Map Extent" ), static_cast<int>( Qgis::SymbolCoordinateReference::Viewport ) );
3082 connect( mCoordinateReferenceComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this] {
3083 if ( mLayer )
3084 {
3085 mLayer->setCoordinateReference( static_cast<Qgis::SymbolCoordinateReference>( mCoordinateReferenceComboBox->currentData().toInt() ) );
3086 emit changed();
3087 }
3088 } );
3089
3090 mSeedSpinBox->setShowClearButton( true );
3091 mSeedSpinBox->setClearValue( 0 );
3092 mRandomXSpinBox->setClearValue( 0 );
3093 mRandomYSpinBox->setClearValue( 0 );
3094
3097 connect( mRandomXSpinBox, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double d ) {
3098 if ( mLayer )
3099 {
3100 mLayer->setMaximumRandomDeviationX( d );
3101 emit changed();
3102 }
3103 } );
3104 connect( mRandomYSpinBox, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double d ) {
3105 if ( mLayer )
3106 {
3107 mLayer->setMaximumRandomDeviationY( d );
3108 emit changed();
3109 }
3110 } );
3111 connect( mRandomXOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
3112 if ( mLayer )
3113 {
3114 mLayer->setRandomDeviationXUnit( mRandomXOffsetUnitWidget->unit() );
3115 mLayer->setRandomDeviationXMapUnitScale( mRandomXOffsetUnitWidget->getMapUnitScale() );
3116 emit changed();
3117 }
3118 } );
3119 connect( mRandomYOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
3120 if ( mLayer )
3121 {
3122 mLayer->setRandomDeviationYUnit( mRandomYOffsetUnitWidget->unit() );
3123 mLayer->setRandomDeviationYMapUnitScale( mRandomYOffsetUnitWidget->getMapUnitScale() );
3124 emit changed();
3125 }
3126 } );
3127 connect( mSeedSpinBox, qOverload<int>( &QSpinBox::valueChanged ), this, [this]( int v ) {
3128 if ( mLayer )
3129 {
3130 mLayer->setSeed( v );
3131 emit changed();
3132 }
3133 } );
3134
3135 mAngleSpinBox->setShowClearButton( true );
3136 mAngleSpinBox->setClearValue( 0 );
3137 connect( mAngleSpinBox, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double d ) {
3138 if ( mLayer )
3139 {
3140 mLayer->setAngle( d );
3141 emit changed();
3142 }
3143 } );
3144}
3145
3147{
3148 if ( !layer || layer->layerType() != QLatin1String( "PointPatternFill" ) )
3149 {
3150 return;
3151 }
3152
3153 mLayer = static_cast<QgsPointPatternFillSymbolLayer *>( layer );
3154 whileBlocking( mHorizontalDistanceSpinBox )->setValue( mLayer->distanceX() );
3155 whileBlocking( mVerticalDistanceSpinBox )->setValue( mLayer->distanceY() );
3156 whileBlocking( mHorizontalDisplacementSpinBox )->setValue( mLayer->displacementX() );
3157 whileBlocking( mVerticalDisplacementSpinBox )->setValue( mLayer->displacementY() );
3158 whileBlocking( mHorizontalOffsetSpinBox )->setValue( mLayer->offsetX() );
3159 whileBlocking( mVerticalOffsetSpinBox )->setValue( mLayer->offsetY() );
3160 whileBlocking( mAngleSpinBox )->setValue( mLayer->angle() );
3161
3162 mHorizontalDistanceUnitWidget->blockSignals( true );
3163 mHorizontalDistanceUnitWidget->setUnit( mLayer->distanceXUnit() );
3164 mHorizontalDistanceUnitWidget->setMapUnitScale( mLayer->distanceXMapUnitScale() );
3165 mHorizontalDistanceUnitWidget->blockSignals( false );
3166 mVerticalDistanceUnitWidget->blockSignals( true );
3167 mVerticalDistanceUnitWidget->setUnit( mLayer->distanceYUnit() );
3168 mVerticalDistanceUnitWidget->setMapUnitScale( mLayer->distanceYMapUnitScale() );
3169 mVerticalDistanceUnitWidget->blockSignals( false );
3170 mHorizontalDisplacementUnitWidget->blockSignals( true );
3171 mHorizontalDisplacementUnitWidget->setUnit( mLayer->displacementXUnit() );
3172 mHorizontalDisplacementUnitWidget->setMapUnitScale( mLayer->displacementXMapUnitScale() );
3173 mHorizontalDisplacementUnitWidget->blockSignals( false );
3174 mVerticalDisplacementUnitWidget->blockSignals( true );
3175 mVerticalDisplacementUnitWidget->setUnit( mLayer->displacementYUnit() );
3176 mVerticalDisplacementUnitWidget->setMapUnitScale( mLayer->displacementYMapUnitScale() );
3177 mVerticalDisplacementUnitWidget->blockSignals( false );
3178 mHorizontalOffsetUnitWidget->blockSignals( true );
3179 mHorizontalOffsetUnitWidget->setUnit( mLayer->offsetXUnit() );
3180 mHorizontalOffsetUnitWidget->setMapUnitScale( mLayer->offsetXMapUnitScale() );
3181 mHorizontalOffsetUnitWidget->blockSignals( false );
3182 mVerticalOffsetUnitWidget->blockSignals( true );
3183 mVerticalOffsetUnitWidget->setUnit( mLayer->offsetYUnit() );
3184 mVerticalOffsetUnitWidget->setMapUnitScale( mLayer->offsetYMapUnitScale() );
3185 mVerticalOffsetUnitWidget->blockSignals( false );
3186
3187 whileBlocking( mClipModeComboBox )->setCurrentIndex( mClipModeComboBox->findData( static_cast<int>( mLayer->clipMode() ) ) );
3188 whileBlocking( mCoordinateReferenceComboBox )->setCurrentIndex( mCoordinateReferenceComboBox->findData( static_cast<int>( mLayer->coordinateReference() ) ) );
3189
3190 whileBlocking( mRandomXSpinBox )->setValue( mLayer->maximumRandomDeviationX() );
3191 whileBlocking( mRandomYSpinBox )->setValue( mLayer->maximumRandomDeviationY() );
3192 whileBlocking( mRandomXOffsetUnitWidget )->setUnit( mLayer->randomDeviationXUnit() );
3193 whileBlocking( mRandomXOffsetUnitWidget )->setMapUnitScale( mLayer->randomDeviationXMapUnitScale() );
3194 whileBlocking( mRandomYOffsetUnitWidget )->setUnit( mLayer->randomDeviationYUnit() );
3195 whileBlocking( mRandomYOffsetUnitWidget )->setMapUnitScale( mLayer->randomDeviationYMapUnitScale() );
3196 whileBlocking( mSeedSpinBox )->setValue( mLayer->seed() );
3197
3210}
3211
3216
3217void QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceSpinBox_valueChanged( double d )
3218{
3219 if ( mLayer )
3220 {
3221 mLayer->setDistanceX( d );
3222 emit changed();
3223 }
3224}
3225
3226void QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceSpinBox_valueChanged( double d )
3227{
3228 if ( mLayer )
3229 {
3230 mLayer->setDistanceY( d );
3231 emit changed();
3232 }
3233}
3234
3235void QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementSpinBox_valueChanged( double d )
3236{
3237 if ( mLayer )
3238 {
3239 mLayer->setDisplacementX( d );
3240 emit changed();
3241 }
3242}
3243
3244void QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementSpinBox_valueChanged( double d )
3245{
3246 if ( mLayer )
3247 {
3248 mLayer->setDisplacementY( d );
3249 emit changed();
3250 }
3251}
3252
3253void QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetSpinBox_valueChanged( double d )
3254{
3255 if ( mLayer )
3256 {
3257 mLayer->setOffsetX( d );
3258 emit changed();
3259 }
3260}
3261
3262void QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetSpinBox_valueChanged( double d )
3263{
3264 if ( mLayer )
3265 {
3266 mLayer->setOffsetY( d );
3267 emit changed();
3268 }
3269}
3270
3271void QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceUnitWidget_changed()
3272{
3273 if ( mLayer )
3274 {
3275 mLayer->setDistanceXUnit( mHorizontalDistanceUnitWidget->unit() );
3276 mLayer->setDistanceXMapUnitScale( mHorizontalDistanceUnitWidget->getMapUnitScale() );
3277 emit changed();
3278 }
3279}
3280
3281void QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceUnitWidget_changed()
3282{
3283 if ( mLayer )
3284 {
3285 mLayer->setDistanceYUnit( mVerticalDistanceUnitWidget->unit() );
3286 mLayer->setDistanceYMapUnitScale( mVerticalDistanceUnitWidget->getMapUnitScale() );
3287 emit changed();
3288 }
3289}
3290
3291void QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementUnitWidget_changed()
3292{
3293 if ( mLayer )
3294 {
3295 mLayer->setDisplacementXUnit( mHorizontalDisplacementUnitWidget->unit() );
3296 mLayer->setDisplacementXMapUnitScale( mHorizontalDisplacementUnitWidget->getMapUnitScale() );
3297 emit changed();
3298 }
3299}
3300
3301void QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementUnitWidget_changed()
3302{
3303 if ( mLayer )
3304 {
3305 mLayer->setDisplacementYUnit( mVerticalDisplacementUnitWidget->unit() );
3306 mLayer->setDisplacementYMapUnitScale( mVerticalDisplacementUnitWidget->getMapUnitScale() );
3307 emit changed();
3308 }
3309}
3310
3311void QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetUnitWidget_changed()
3312{
3313 if ( mLayer )
3314 {
3315 mLayer->setOffsetXUnit( mHorizontalOffsetUnitWidget->unit() );
3316 mLayer->setOffsetXMapUnitScale( mHorizontalOffsetUnitWidget->getMapUnitScale() );
3317 emit changed();
3318 }
3319}
3320
3321void QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetUnitWidget_changed()
3322{
3323 if ( mLayer )
3324 {
3325 mLayer->setOffsetYUnit( mVerticalOffsetUnitWidget->unit() );
3326 mLayer->setOffsetYMapUnitScale( mVerticalOffsetUnitWidget->getMapUnitScale() );
3327 emit changed();
3328 }
3329}
3330
3332
3334 : QgsSymbolLayerWidget( parent, vl )
3335{
3336 mLayer = nullptr;
3337
3338 setupUi( this );
3339
3340 mHorizontalAnchorComboBox->addItem( tr( "Left" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Left ) );
3341 mHorizontalAnchorComboBox->addItem( tr( "Horizontal Center" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Center ) );
3342 mHorizontalAnchorComboBox->addItem( tr( "Right" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Right ) );
3343
3344 mVerticalAnchorComboBox->addItem( tr( "Top" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Top ) );
3345 mVerticalAnchorComboBox->addItem( tr( "Vertical Center" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Center ) );
3346 mVerticalAnchorComboBox->addItem( tr( "Bottom on Baseline" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Baseline ) );
3347 mVerticalAnchorComboBox->addItem( tr( "Bottom" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Bottom ) );
3348
3349 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
3350 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
3351 connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
3352 connect( mStrokeWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
3353 connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
3354 connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
3358
3360 scrollArea->setWidget( widgetChar );
3361 scrollArea->setVerticalOnly( true );
3362
3363 btnColor->setAllowOpacity( true );
3364 btnColor->setColorDialogTitle( tr( "Select Symbol Fill Color" ) );
3365 btnColor->setContext( QStringLiteral( "symbology" ) );
3366 btnStrokeColor->setAllowOpacity( true );
3367 btnStrokeColor->setColorDialogTitle( tr( "Select Symbol Stroke Color" ) );
3368 btnStrokeColor->setContext( QStringLiteral( "symbology" ) );
3369
3370 mColorDDBtn->registerLinkedWidget( btnColor );
3371 mStrokeColorDDBtn->registerLinkedWidget( btnStrokeColor );
3372
3373 spinOffsetX->setClearValue( 0.0 );
3374 spinOffsetY->setClearValue( 0.0 );
3375 spinAngle->setClearValue( 0.0 );
3376
3377 //make a temporary symbol for the size assistant preview
3378 mAssistantPreviewSymbol = std::make_shared<QgsMarkerSymbol>();
3379
3380 if ( vectorLayer() )
3381 mSizeDDBtn->setSymbol( mAssistantPreviewSymbol );
3382
3383 connect( cboFont, &QFontComboBox::currentFontChanged, this, &QgsFontMarkerSymbolLayerWidget::setFontFamily );
3384 connect( mFontStyleComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::mFontStyleComboBox_currentIndexChanged );
3385 connect( spinSize, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setSize );
3386 connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::penJoinStyleChanged );
3389 connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::penJoinStyleChanged );
3390 connect( spinAngle, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setAngle );
3391 connect( spinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setOffset );
3392 connect( spinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setOffset );
3394 connect( mCharLineEdit, &QLineEdit::textChanged, this, &QgsFontMarkerSymbolLayerWidget::setCharacterFromText );
3395
3396 connect( this, &QgsSymbolLayerWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::updateAssistantSymbol );
3397}
3398
3400
3402{
3403 if ( layer->layerType() != QLatin1String( "FontMarker" ) )
3404 return;
3405
3406 // layer type is correct, we can do the cast
3407 mLayer = static_cast<QgsFontMarkerSymbolLayer *>( layer );
3408
3409 QgsFontUtils::setFontFamily( mRefFont, mLayer->fontFamily() );
3410 mRefFont.setStyleName( QgsFontUtils::translateNamedStyle( mLayer->fontStyle() ) );
3411
3412 mFontStyleComboBox->blockSignals( true );
3413 populateFontStyleComboBox();
3414 mFontStyleComboBox->blockSignals( false );
3415
3416 // set values
3417 whileBlocking( cboFont )->setCurrentFont( mRefFont );
3418 whileBlocking( spinSize )->setValue( mLayer->size() );
3419 whileBlocking( btnColor )->setColor( mLayer->color() );
3420 whileBlocking( btnStrokeColor )->setColor( mLayer->strokeColor() );
3421 whileBlocking( mStrokeWidthSpinBox )->setValue( mLayer->strokeWidth() );
3422 whileBlocking( spinAngle )->setValue( mLayer->angle() );
3423
3424 widgetChar->blockSignals( true );
3425 widgetChar->setFont( mRefFont );
3426 if ( mLayer->character().length() == 1 )
3427 {
3428 widgetChar->setCharacter( mLayer->character().at( 0 ) );
3429 }
3430 widgetChar->blockSignals( false );
3431 whileBlocking( mCharLineEdit )->setText( mLayer->character() );
3432 mCharPreview->setFont( mRefFont );
3433
3434 //block
3435 whileBlocking( spinOffsetX )->setValue( mLayer->offset().x() );
3436 whileBlocking( spinOffsetY )->setValue( mLayer->offset().y() );
3437
3438 mSizeUnitWidget->blockSignals( true );
3439 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
3440 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
3441 mSizeUnitWidget->blockSignals( false );
3442
3443 mStrokeWidthUnitWidget->blockSignals( true );
3444 mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
3445 mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
3446 mStrokeWidthUnitWidget->blockSignals( false );
3447
3448 mOffsetUnitWidget->blockSignals( true );
3449 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
3450 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
3451 mOffsetUnitWidget->blockSignals( false );
3452
3453 whileBlocking( cboJoinStyle )->setPenJoinStyle( mLayer->penJoinStyle() );
3454
3455 //anchor points
3456 whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mHorizontalAnchorComboBox->findData( QVariant::fromValue( mLayer->horizontalAnchorPoint() ) ) );
3457 whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mVerticalAnchorComboBox->findData( QVariant::fromValue( mLayer->verticalAnchorPoint() ) ) );
3458
3471
3472 updateAssistantSymbol();
3473}
3474
3479
3481{
3482 if ( mLayer )
3483 {
3484 mLayer->setFontFamily( font.family() );
3485 QgsFontUtils::setFontFamily( mRefFont, font.family() );
3486 widgetChar->setFont( mRefFont );
3487 mCharPreview->setFont( mRefFont );
3488 populateFontStyleComboBox();
3489 emit changed();
3490 }
3491}
3492
3493void QgsFontMarkerSymbolLayerWidget::setFontStyle( const QString &style )
3494{
3495 if ( mLayer )
3496 {
3497 QgsFontUtils::updateFontViaStyle( mRefFont, style );
3499 widgetChar->setFont( mRefFont );
3500 mCharPreview->setFont( mRefFont );
3501 emit changed();
3502 }
3503}
3504
3506{
3507 mLayer->setColor( color );
3508 emit changed();
3509}
3510
3512{
3513 mLayer->setStrokeColor( color );
3514 emit changed();
3515}
3516
3518{
3519 mLayer->setSize( size );
3520 //widgetChar->updateSize(size);
3521 emit changed();
3522}
3523
3525{
3526 mLayer->setAngle( angle );
3527 emit changed();
3528}
3529
3531{
3532 mCharPreview->setText( text );
3533
3534 if ( text.isEmpty() )
3535 return;
3536
3537 // take the last character of a string for a better experience when users cycle through several characters on their keyboard
3538 QString character = text;
3539 if ( text.contains( QRegularExpression( QStringLiteral( "^0x[0-9a-fA-F]{1,4}$" ) ) ) )
3540 {
3541 bool ok = false;
3542 const unsigned int value = text.toUInt( &ok, 0 );
3543 if ( ok )
3544 {
3545 character = QChar( value );
3546 mCharPreview->setText( character );
3547 }
3548 }
3549
3550 if ( character != mLayer->character() )
3551 {
3552 mLayer->setCharacter( character );
3553 if ( mLayer->character().length() == 1 )
3554 {
3555 whileBlocking( widgetChar )->setCharacter( mLayer->character().at( 0 ) );
3556 }
3557 else
3558 {
3559 widgetChar->clearCharacter();
3560 }
3561 emit changed();
3562 }
3563}
3564
3566{
3567 if ( mLayer->character().length() > 1 || QGuiApplication::keyboardModifiers() & Qt::ControlModifier )
3568 {
3569 mCharLineEdit->insert( chr );
3570 return;
3571 }
3572
3573 mLayer->setCharacter( chr );
3574 whileBlocking( mCharLineEdit )->setText( chr );
3575 mCharPreview->setText( chr );
3576 emit changed();
3577}
3578
3579void QgsFontMarkerSymbolLayerWidget::setOffset()
3580{
3581 mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
3582 emit changed();
3583}
3584
3585void QgsFontMarkerSymbolLayerWidget::penJoinStyleChanged()
3586{
3587 mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
3588 emit changed();
3589}
3590
3591void QgsFontMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
3592{
3593 if ( mLayer )
3594 {
3595 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
3596 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
3597 emit changed();
3598 }
3599}
3600
3601void QgsFontMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
3602{
3603 if ( mLayer )
3604 {
3605 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
3606 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
3607 emit changed();
3608 }
3609}
3610
3611void QgsFontMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
3612{
3613 if ( mLayer )
3614 {
3615 mLayer->setStrokeWidthUnit( mSizeUnitWidget->unit() );
3616 mLayer->setStrokeWidthMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
3617 emit changed();
3618 }
3619}
3620
3621void QgsFontMarkerSymbolLayerWidget::populateFontStyleComboBox()
3622{
3623 mFontStyleComboBox->clear();
3624 const QStringList styles = mFontDB.styles( mRefFont.family() );
3625 const auto constStyles = styles;
3626 for ( const QString &style : constStyles )
3627 {
3628 mFontStyleComboBox->addItem( style );
3629 }
3630
3631 QString targetStyle = mFontDB.styleString( mRefFont );
3632 if ( !styles.contains( targetStyle ) )
3633 {
3634 const QFont f = QgsFontUtils::createFont( mRefFont.family() );
3635 targetStyle = QFontInfo( f ).styleName();
3636 mRefFont.setStyleName( targetStyle );
3637 }
3638 int curIndx = 0;
3639 const int stylIndx = mFontStyleComboBox->findText( targetStyle );
3640 if ( stylIndx > -1 )
3641 {
3642 curIndx = stylIndx;
3643 }
3644
3645 mFontStyleComboBox->setCurrentIndex( curIndx );
3646}
3647
3648void QgsFontMarkerSymbolLayerWidget::mFontStyleComboBox_currentIndexChanged( int index )
3649{
3650 Q_UNUSED( index );
3651 setFontStyle( mFontStyleComboBox->currentText() );
3652}
3653
3654void QgsFontMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int )
3655{
3656 if ( mLayer )
3657 {
3658 mLayer->setHorizontalAnchorPoint( mHorizontalAnchorComboBox->currentData().value< Qgis::HorizontalAnchorPoint >() );
3659 emit changed();
3660 }
3661}
3662
3663void QgsFontMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int )
3664{
3665 if ( mLayer )
3666 {
3667 mLayer->setVerticalAnchorPoint( mVerticalAnchorComboBox->currentData().value< Qgis::VerticalAnchorPoint >() );
3668 emit changed();
3669 }
3670}
3671
3672void QgsFontMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
3673{
3674 if ( mLayer )
3675 {
3676 mLayer->setStrokeWidth( d );
3677 emit changed();
3678 }
3679}
3680
3681void QgsFontMarkerSymbolLayerWidget::updateAssistantSymbol()
3682{
3683 for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1; i >= 0; --i )
3684 {
3685 mAssistantPreviewSymbol->deleteSymbolLayer( i );
3686 }
3687 mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
3688 const QgsProperty ddSize = mLayer->dataDefinedProperties().property( QgsSymbolLayer::Property::Size );
3689 if ( ddSize )
3690 mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
3691}
3692
3694
3695
3697 : QgsSymbolLayerWidget( parent, vl )
3698{
3699 mLayer = nullptr;
3700
3701 setupUi( this );
3702 connect( mDrawInsideCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mDrawInsideCheckBox_stateChanged );
3703 connect( mDrawAllPartsCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mDrawAllPartsCheckBox_stateChanged );
3704 connect( mClipPointsCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mClipPointsCheckBox_stateChanged );
3705 connect( mClipOnCurrentPartOnlyCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mClipOnCurrentPartOnlyCheckBox_stateChanged );
3706}
3707
3709{
3710 if ( layer->layerType() != QLatin1String( "CentroidFill" ) )
3711 return;
3712
3713 // layer type is correct, we can do the cast
3714 mLayer = static_cast<QgsCentroidFillSymbolLayer *>( layer );
3715
3716 // set values
3717 whileBlocking( mDrawInsideCheckBox )->setChecked( mLayer->pointOnSurface() );
3718 whileBlocking( mDrawAllPartsCheckBox )->setChecked( mLayer->pointOnAllParts() );
3719 whileBlocking( mClipPointsCheckBox )->setChecked( mLayer->clipPoints() );
3720 whileBlocking( mClipOnCurrentPartOnlyCheckBox )->setChecked( mLayer->clipOnCurrentPartOnly() );
3721}
3722
3727
3728void QgsCentroidFillSymbolLayerWidget::mDrawInsideCheckBox_stateChanged( int state )
3729{
3730 mLayer->setPointOnSurface( state == Qt::Checked );
3731 emit changed();
3732}
3733
3734void QgsCentroidFillSymbolLayerWidget::mDrawAllPartsCheckBox_stateChanged( int state )
3735{
3736 mLayer->setPointOnAllParts( state == Qt::Checked );
3737 emit changed();
3738}
3739
3740void QgsCentroidFillSymbolLayerWidget::mClipPointsCheckBox_stateChanged( int state )
3741{
3742 mLayer->setClipPoints( state == Qt::Checked );
3743 emit changed();
3744}
3745
3746void QgsCentroidFillSymbolLayerWidget::mClipOnCurrentPartOnlyCheckBox_stateChanged( int state )
3747{
3748 mLayer->setClipOnCurrentPartOnly( state == Qt::Checked );
3749 emit changed();
3750}
3751
3753
3755 : QgsSymbolLayerWidget( parent, vl )
3756{
3757 mLayer = nullptr;
3758
3759 setupUi( this );
3760
3761 mHorizontalAnchorComboBox->addItem( tr( "Left" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Left ) );
3762 mHorizontalAnchorComboBox->addItem( tr( "Horizontal Center" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Center ) );
3763 mHorizontalAnchorComboBox->addItem( tr( "Right" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Right ) );
3764
3765 mVerticalAnchorComboBox->addItem( tr( "Top" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Top ) );
3766 mVerticalAnchorComboBox->addItem( tr( "Vertical Center" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Center ) );
3767 mVerticalAnchorComboBox->addItem( tr( "Bottom" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Bottom ) );
3768
3769 mImageSourceLineEdit->setLastPathSettingsKey( QStringLiteral( "/UI/lastRasterMarkerImageDir" ) );
3770
3771 connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsRasterMarkerSymbolLayerWidget::imageSourceChanged );
3772 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
3773 connect( mRotationSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setAngle );
3774 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
3775 connect( mWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setWidth );
3776 connect( mHeightSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setHeight );
3777 connect( mLockAspectRatio, static_cast<void ( QgsRatioLockButton::* )( bool )>( &QgsRatioLockButton::lockChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setLockAspectRatio );
3778
3781
3782 mSpinOffsetX->setClearValue( 0.0 );
3783 mSpinOffsetY->setClearValue( 0.0 );
3784 mRotationSpinBox->setClearValue( 0.0 );
3785
3786 connect( mSpinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setOffset );
3787 connect( mSpinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setOffset );
3788 connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsRasterMarkerSymbolLayerWidget::setOpacity );
3789
3790 connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
3791 connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
3792}
3793
3795{
3796 if ( !layer )
3797 {
3798 return;
3799 }
3800
3801 if ( layer->layerType() != QLatin1String( "RasterMarker" ) )
3802 return;
3803
3804 // layer type is correct, we can do the cast
3805 mLayer = static_cast<QgsRasterMarkerSymbolLayer *>( layer );
3806
3807 // set values
3808 whileBlocking( mImageSourceLineEdit )->setSource( mLayer->path() );
3809
3810 whileBlocking( mWidthSpinBox )->setValue( mLayer->size() );
3811 const bool preservedAspectRatio = mLayer->preservedAspectRatio();
3812 mHeightSpinBox->blockSignals( true );
3813 if ( preservedAspectRatio )
3814 {
3815 mHeightSpinBox->setValue( mLayer->size() );
3816 }
3817 else
3818 {
3819 mHeightSpinBox->setValue( mLayer->size() * mLayer->fixedAspectRatio() );
3820 }
3821 mHeightSpinBox->setEnabled( mLayer->defaultAspectRatio() > 0.0 );
3822 mHeightSpinBox->blockSignals( false );
3823 whileBlocking( mLockAspectRatio )->setLocked( preservedAspectRatio );
3824
3825 whileBlocking( mRotationSpinBox )->setValue( mLayer->angle() );
3826 whileBlocking( mOpacityWidget )->setOpacity( mLayer->opacity() );
3827
3828 whileBlocking( mSpinOffsetX )->setValue( mLayer->offset().x() );
3829 whileBlocking( mSpinOffsetY )->setValue( mLayer->offset().y() );
3830
3831 mSizeUnitWidget->blockSignals( true );
3832 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
3833 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
3834 mSizeUnitWidget->blockSignals( false );
3835 mOffsetUnitWidget->blockSignals( true );
3836 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
3837 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
3838 mOffsetUnitWidget->blockSignals( false );
3839
3840 //anchor points
3841 whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mHorizontalAnchorComboBox->findData( QVariant::fromValue( mLayer->horizontalAnchorPoint() ) ) );
3842 whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mVerticalAnchorComboBox->findData( QVariant::fromValue( mLayer->verticalAnchorPoint() ) ) );
3843
3852
3853 updatePreviewImage();
3854}
3855
3860
3862{
3864 mImageSourceLineEdit->setMessageBar( context.messageBar() );
3865}
3866
3867void QgsRasterMarkerSymbolLayerWidget::imageSourceChanged( const QString &text )
3868{
3869 mLayer->setPath( text );
3870 updatePreviewImage();
3871 emit changed();
3872}
3873
3874void QgsRasterMarkerSymbolLayerWidget::updatePreviewImage()
3875{
3876 bool fitsInCache = false;
3877 const QImage image = QgsApplication::imageCache()->pathAsImage( mLayer->path(), QSize( 150, 150 ), true, 1.0, fitsInCache );
3878 if ( image.isNull() )
3879 {
3880 mLabelImagePreview->setPixmap( QPixmap() );
3881 return;
3882 }
3883
3884 QImage previewImage( 150, 150, QImage::Format_ARGB32 );
3885 previewImage.fill( Qt::transparent );
3886 const QRect imageRect( ( 150 - image.width() ) / 2.0, ( 150 - image.height() ) / 2.0, image.width(), image.height() );
3887 QPainter p;
3888 p.begin( &previewImage );
3889 //draw a checkerboard background
3890 uchar pixDataRGB[] = { 150, 150, 150, 150, 100, 100, 100, 150, 100, 100, 100, 150, 150, 150, 150, 150 };
3891 const QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
3892 const QPixmap pix = QPixmap::fromImage( img.scaled( 8, 8 ) );
3893 QBrush checkerBrush;
3894 checkerBrush.setTexture( pix );
3895 p.fillRect( imageRect, checkerBrush );
3896
3897 if ( mLayer->opacity() < 1.0 )
3898 {
3899 p.setOpacity( mLayer->opacity() );
3900 }
3901
3902 p.drawImage( imageRect.left(), imageRect.top(), image );
3903 p.end();
3904 mLabelImagePreview->setPixmap( QPixmap::fromImage( previewImage ) );
3905}
3906
3907void QgsRasterMarkerSymbolLayerWidget::setWidth()
3908{
3909 const double defaultAspectRatio = mLayer->defaultAspectRatio();
3910 double fixedAspectRatio = 0.0;
3911 mHeightSpinBox->blockSignals( true );
3912 if ( defaultAspectRatio <= 0.0 )
3913 {
3914 mHeightSpinBox->setValue( mWidthSpinBox->value() );
3915 }
3916 else if ( mLockAspectRatio->locked() )
3917 {
3918 mHeightSpinBox->setValue( mWidthSpinBox->value() * defaultAspectRatio );
3919 }
3920 else
3921 {
3922 fixedAspectRatio = mHeightSpinBox->value() / mWidthSpinBox->value();
3923 }
3924 mHeightSpinBox->blockSignals( false );
3925 mLayer->setSize( mWidthSpinBox->value() );
3926 mLayer->setFixedAspectRatio( fixedAspectRatio );
3927 emit changed();
3928}
3929
3930void QgsRasterMarkerSymbolLayerWidget::setHeight()
3931{
3932 const double defaultAspectRatio = mLayer->defaultAspectRatio();
3933 double fixedAspectRatio = 0.0;
3934 mWidthSpinBox->blockSignals( true );
3935 if ( defaultAspectRatio <= 0.0 )
3936 {
3937 mWidthSpinBox->setValue( mHeightSpinBox->value() );
3938 }
3939 else if ( mLockAspectRatio->locked() )
3940 {
3941 mWidthSpinBox->setValue( mHeightSpinBox->value() / defaultAspectRatio );
3942 }
3943 else
3944 {
3945 fixedAspectRatio = mHeightSpinBox->value() / mWidthSpinBox->value();
3946 }
3947 mWidthSpinBox->blockSignals( false );
3948 mLayer->setSize( mWidthSpinBox->value() );
3949 mLayer->setFixedAspectRatio( fixedAspectRatio );
3950 emit changed();
3951}
3952
3953void QgsRasterMarkerSymbolLayerWidget::setLockAspectRatio( const bool locked )
3954{
3955 const double defaultAspectRatio = mLayer->defaultAspectRatio();
3956 if ( defaultAspectRatio <= 0.0 )
3957 {
3958 whileBlocking( mLockAspectRatio )->setLocked( true );
3959 }
3960 else if ( locked )
3961 {
3962 mLayer->setFixedAspectRatio( 0.0 );
3963 setWidth();
3964 }
3965 else
3966 {
3967 mLayer->setFixedAspectRatio( mHeightSpinBox->value() / mWidthSpinBox->value() );
3968 }
3969}
3970
3971void QgsRasterMarkerSymbolLayerWidget::setAngle()
3972{
3973 mLayer->setAngle( mRotationSpinBox->value() );
3974 emit changed();
3975}
3976
3977void QgsRasterMarkerSymbolLayerWidget::setOpacity( double value )
3978{
3979 mLayer->setOpacity( value );
3980 emit changed();
3981 updatePreviewImage();
3982}
3983
3984void QgsRasterMarkerSymbolLayerWidget::setOffset()
3985{
3986 mLayer->setOffset( QPointF( mSpinOffsetX->value(), mSpinOffsetY->value() ) );
3987 emit changed();
3988}
3989
3990void QgsRasterMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
3991{
3992 if ( mLayer )
3993 {
3994 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
3995 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
3996 emit changed();
3997 }
3998}
3999
4000void QgsRasterMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
4001{
4002 if ( mLayer )
4003 {
4004 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
4005 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
4006 emit changed();
4007 }
4008}
4009
4010void QgsRasterMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int )
4011{
4012 if ( mLayer )
4013 {
4014 mLayer->setHorizontalAnchorPoint( mHorizontalAnchorComboBox->currentData().value< Qgis::HorizontalAnchorPoint >() );
4015 emit changed();
4016 }
4017}
4018
4019void QgsRasterMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int )
4020{
4021 if ( mLayer )
4022 {
4023 mLayer->setVerticalAnchorPoint( mVerticalAnchorComboBox->currentData().value< Qgis::VerticalAnchorPoint >() );
4024 emit changed();
4025 }
4026}
4027
4028
4030
4032 : QgsSymbolLayerWidget( parent, vl )
4033{
4034 mLayer = nullptr;
4035
4036 setupUi( this );
4037
4038 mHorizontalAnchorComboBox->addItem( tr( "Left" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Left ) );
4039 mHorizontalAnchorComboBox->addItem( tr( "Horizontal Center" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Center ) );
4040 mHorizontalAnchorComboBox->addItem( tr( "Right" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Right ) );
4041
4042 mVerticalAnchorComboBox->addItem( tr( "Top" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Top ) );
4043 mVerticalAnchorComboBox->addItem( tr( "Vertical Center" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Center ) );
4044 mVerticalAnchorComboBox->addItem( tr( "Bottom" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Bottom ) );
4045
4046 mImageSourceLineEdit->setLastPathSettingsKey( QStringLiteral( "/UI/lastAnimatedMarkerImageDir" ) );
4047
4048 connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsAnimatedMarkerSymbolLayerWidget::imageSourceChanged );
4049 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsAnimatedMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
4050 connect( mRotationSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::setAngle );
4051 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsAnimatedMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
4052 connect( mWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::setWidth );
4053 connect( mHeightSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::setHeight );
4054 connect( mLockAspectRatio, static_cast<void ( QgsRatioLockButton::* )( bool )>( &QgsRatioLockButton::lockChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::setLockAspectRatio );
4055
4056 mFrameRateSpin->setClearValue( 10 );
4057 mFrameRateSpin->setShowClearButton( true );
4058 connect( mFrameRateSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double value ) {
4059 mLayer->setFrameRate( value );
4060 emit changed();
4061 } );
4062
4065
4066 mSpinOffsetX->setClearValue( 0.0 );
4067 mSpinOffsetY->setClearValue( 0.0 );
4068 mRotationSpinBox->setClearValue( 0.0 );
4069
4070 connect( mSpinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::setOffset );
4071 connect( mSpinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::setOffset );
4072 connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsAnimatedMarkerSymbolLayerWidget::setOpacity );
4073
4074 connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
4075 connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
4076}
4077
4079{
4080 if ( !layer )
4081 {
4082 return;
4083 }
4084
4085 if ( layer->layerType() != QLatin1String( "AnimatedMarker" ) )
4086 return;
4087
4088 // layer type is correct, we can do the cast
4089 mLayer = static_cast<QgsAnimatedMarkerSymbolLayer *>( layer );
4090
4091 // set values
4092 whileBlocking( mImageSourceLineEdit )->setSource( mLayer->path() );
4093
4094 const double firstFrameTime = QgsApplication::imageCache()->nextFrameDelay( mLayer->path() );
4095 if ( firstFrameTime > 0 )
4096 {
4097 mFrameRateSpin->setClearValue( 1000 / firstFrameTime );
4098 }
4099 else
4100 {
4101 mFrameRateSpin->setClearValue( 10 );
4102 }
4103
4104 whileBlocking( mWidthSpinBox )->setValue( mLayer->size() );
4105 const bool preservedAspectRatio = mLayer->preservedAspectRatio();
4106 mHeightSpinBox->blockSignals( true );
4107 if ( preservedAspectRatio )
4108 {
4109 mHeightSpinBox->setValue( mLayer->size() );
4110 }
4111 else
4112 {
4113 mHeightSpinBox->setValue( mLayer->size() * mLayer->fixedAspectRatio() );
4114 }
4115 mHeightSpinBox->setEnabled( mLayer->defaultAspectRatio() > 0.0 );
4116 mHeightSpinBox->blockSignals( false );
4117 whileBlocking( mLockAspectRatio )->setLocked( preservedAspectRatio );
4118
4119 whileBlocking( mRotationSpinBox )->setValue( mLayer->angle() );
4120 whileBlocking( mOpacityWidget )->setOpacity( mLayer->opacity() );
4121
4122 whileBlocking( mSpinOffsetX )->setValue( mLayer->offset().x() );
4123 whileBlocking( mSpinOffsetY )->setValue( mLayer->offset().y() );
4124
4125 whileBlocking( mFrameRateSpin )->setValue( mLayer->frameRate() );
4126
4127 mSizeUnitWidget->blockSignals( true );
4128 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
4129 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
4130 mSizeUnitWidget->blockSignals( false );
4131 mOffsetUnitWidget->blockSignals( true );
4132 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
4133 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
4134 mOffsetUnitWidget->blockSignals( false );
4135
4136 //anchor points
4137 whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mHorizontalAnchorComboBox->findData( QVariant::fromValue( mLayer->horizontalAnchorPoint() ) ) );
4138 whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mVerticalAnchorComboBox->findData( QVariant::fromValue( mLayer->verticalAnchorPoint() ) ) );
4139
4148
4149 updatePreviewImage();
4150}
4151
4156
4158{
4160 mImageSourceLineEdit->setMessageBar( context.messageBar() );
4161}
4162
4163void QgsAnimatedMarkerSymbolLayerWidget::imageSourceChanged( const QString &text )
4164{
4165 mLayer->setPath( text );
4166
4167 const double firstFrameTime = QgsApplication::imageCache()->nextFrameDelay( text );
4168 if ( firstFrameTime > 0 )
4169 {
4170 mFrameRateSpin->setClearValue( 1000 / firstFrameTime );
4171 }
4172 else
4173 {
4174 mFrameRateSpin->setClearValue( 10 );
4175 }
4176 updatePreviewImage();
4177 emit changed();
4178}
4179
4180void QgsAnimatedMarkerSymbolLayerWidget::updatePreviewImage()
4181{
4182 if ( mPreviewMovie )
4183 {
4184 mLabelImagePreview->setMovie( nullptr );
4185 mPreviewMovie->deleteLater();
4186 mPreviewMovie = nullptr;
4187 }
4188
4189 mPreviewMovie = new QMovie( mLayer->path(), QByteArray(), this );
4190 mPreviewMovie->setScaledSize( QSize( 150, 150 ) );
4191 mLabelImagePreview->setMovie( mPreviewMovie );
4192 mPreviewMovie->start();
4193}
4194
4195void QgsAnimatedMarkerSymbolLayerWidget::setWidth()
4196{
4197 const double defaultAspectRatio = mLayer->defaultAspectRatio();
4198 double fixedAspectRatio = 0.0;
4199 mHeightSpinBox->blockSignals( true );
4200 if ( defaultAspectRatio <= 0.0 )
4201 {
4202 mHeightSpinBox->setValue( mWidthSpinBox->value() );
4203 }
4204 else if ( mLockAspectRatio->locked() )
4205 {
4206 mHeightSpinBox->setValue( mWidthSpinBox->value() * defaultAspectRatio );
4207 }
4208 else
4209 {
4210 fixedAspectRatio = mHeightSpinBox->value() / mWidthSpinBox->value();
4211 }
4212 mHeightSpinBox->blockSignals( false );
4213 mLayer->setSize( mWidthSpinBox->value() );
4214 mLayer->setFixedAspectRatio( fixedAspectRatio );
4215 emit changed();
4216}
4217
4218void QgsAnimatedMarkerSymbolLayerWidget::setHeight()
4219{
4220 const double defaultAspectRatio = mLayer->defaultAspectRatio();
4221 double fixedAspectRatio = 0.0;
4222 mWidthSpinBox->blockSignals( true );
4223 if ( defaultAspectRatio <= 0.0 )
4224 {
4225 mWidthSpinBox->setValue( mHeightSpinBox->value() );
4226 }
4227 else if ( mLockAspectRatio->locked() )
4228 {
4229 mWidthSpinBox->setValue( mHeightSpinBox->value() / defaultAspectRatio );
4230 }
4231 else
4232 {
4233 fixedAspectRatio = mHeightSpinBox->value() / mWidthSpinBox->value();
4234 }
4235 mWidthSpinBox->blockSignals( false );
4236 mLayer->setSize( mWidthSpinBox->value() );
4237 mLayer->setFixedAspectRatio( fixedAspectRatio );
4238 emit changed();
4239}
4240
4241void QgsAnimatedMarkerSymbolLayerWidget::setLockAspectRatio( const bool locked )
4242{
4243 const double defaultAspectRatio = mLayer->defaultAspectRatio();
4244 if ( defaultAspectRatio <= 0.0 )
4245 {
4246 whileBlocking( mLockAspectRatio )->setLocked( true );
4247 }
4248 else if ( locked )
4249 {
4250 mLayer->setFixedAspectRatio( 0.0 );
4251 setWidth();
4252 }
4253 else
4254 {
4255 mLayer->setFixedAspectRatio( mHeightSpinBox->value() / mWidthSpinBox->value() );
4256 }
4257}
4258
4259void QgsAnimatedMarkerSymbolLayerWidget::setAngle()
4260{
4261 mLayer->setAngle( mRotationSpinBox->value() );
4262 emit changed();
4263}
4264
4265void QgsAnimatedMarkerSymbolLayerWidget::setOpacity( double value )
4266{
4267 mLayer->setOpacity( value );
4268 emit changed();
4269 updatePreviewImage();
4270}
4271
4272void QgsAnimatedMarkerSymbolLayerWidget::setOffset()
4273{
4274 mLayer->setOffset( QPointF( mSpinOffsetX->value(), mSpinOffsetY->value() ) );
4275 emit changed();
4276}
4277
4278void QgsAnimatedMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
4279{
4280 if ( mLayer )
4281 {
4282 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
4283 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
4284 emit changed();
4285 }
4286}
4287
4288void QgsAnimatedMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
4289{
4290 if ( mLayer )
4291 {
4292 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
4293 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
4294 emit changed();
4295 }
4296}
4297
4298void QgsAnimatedMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int )
4299{
4300 if ( mLayer )
4301 {
4302 mLayer->setHorizontalAnchorPoint( mHorizontalAnchorComboBox->currentData().value< Qgis::HorizontalAnchorPoint >() );
4303 emit changed();
4304 }
4305}
4306
4307void QgsAnimatedMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int )
4308{
4309 if ( mLayer )
4310 {
4311 mLayer->setVerticalAnchorPoint( mVerticalAnchorComboBox->currentData().value< Qgis::VerticalAnchorPoint >() );
4312 emit changed();
4313 }
4314}
4315
4317
4319 : QgsSymbolLayerWidget( parent, vl )
4320{
4321 mLayer = nullptr;
4322 setupUi( this );
4323
4324 mImageSourceLineEdit->setLastPathSettingsKey( QStringLiteral( "/UI/lastRasterMarkerImageDir" ) );
4325 connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsRasterFillSymbolLayerWidget::imageSourceChanged );
4326
4327 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterFillSymbolLayerWidget::mOffsetUnitWidget_changed );
4328 connect( mRotationSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::mRotationSpinBox_valueChanged );
4329
4330 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
4331 if ( !mLayer )
4332 {
4333 return;
4334 }
4335 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
4336 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
4337 emit changed();
4338 } );
4339 connect( mWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, [this]( double d ) {
4340 if ( !mLayer )
4341 {
4342 return;
4343 }
4344 mLayer->setWidth( d );
4345 emit changed();
4346 } );
4347
4348 connect( mHeightSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, [this]( double d ) {
4349 if ( !mLayer )
4350 {
4351 return;
4352 }
4353 mLayer->setHeight( d );
4354 emit changed();
4355 } );
4356
4359
4360 mSpinOffsetX->setClearValue( 0.0 );
4361 mSpinOffsetY->setClearValue( 0.0 );
4362 mRotationSpinBox->setClearValue( 0.0 );
4363
4364 connect( cboCoordinateMode, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterFillSymbolLayerWidget::setCoordinateMode );
4365 connect( mSpinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::offsetChanged );
4366 connect( mSpinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::offsetChanged );
4367 connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsRasterFillSymbolLayerWidget::opacityChanged );
4368}
4369
4370
4372{
4373 if ( !layer )
4374 {
4375 return;
4376 }
4377
4378 if ( layer->layerType() != QLatin1String( "RasterFill" ) )
4379 {
4380 return;
4381 }
4382
4383 mLayer = dynamic_cast<QgsRasterFillSymbolLayer *>( layer );
4384 if ( !mLayer )
4385 {
4386 return;
4387 }
4388
4389 whileBlocking( mImageSourceLineEdit )->setSource( mLayer->imageFilePath() );
4390
4391 cboCoordinateMode->blockSignals( true );
4392 switch ( mLayer->coordinateMode() )
4393 {
4395 cboCoordinateMode->setCurrentIndex( 1 );
4396 break;
4398 default:
4399 cboCoordinateMode->setCurrentIndex( 0 );
4400 break;
4401 }
4402 cboCoordinateMode->blockSignals( false );
4403 whileBlocking( mOpacityWidget )->setOpacity( mLayer->opacity() );
4404 whileBlocking( mRotationSpinBox )->setValue( mLayer->angle() );
4405
4406 whileBlocking( mSpinOffsetX )->setValue( mLayer->offset().x() );
4407 whileBlocking( mSpinOffsetY )->setValue( mLayer->offset().y() );
4408 mOffsetUnitWidget->blockSignals( true );
4409 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
4410 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
4411 mOffsetUnitWidget->blockSignals( false );
4412
4413 whileBlocking( mWidthSpinBox )->setValue( mLayer->width() );
4414 mSizeUnitWidget->blockSignals( true );
4415 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
4416 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
4417 mSizeUnitWidget->blockSignals( false );
4418
4419 whileBlocking( mHeightSpinBox )->setValue( mLayer->height() );
4420
4421 updatePreviewImage();
4422
4429}
4430
4435
4436void QgsRasterFillSymbolLayerWidget::imageSourceChanged( const QString &text )
4437{
4438 mLayer->setImageFilePath( text );
4439 updatePreviewImage();
4440 emit changed();
4441}
4442
4443void QgsRasterFillSymbolLayerWidget::setCoordinateMode( int index )
4444{
4445 switch ( index )
4446 {
4447 case 0:
4448 //feature coordinate mode
4450 break;
4451 case 1:
4452 //viewport coordinate mode
4454 break;
4455 }
4456
4457 emit changed();
4458}
4459
4460void QgsRasterFillSymbolLayerWidget::opacityChanged( double value )
4461{
4462 if ( !mLayer )
4463 {
4464 return;
4465 }
4466
4467 mLayer->setOpacity( value );
4468 emit changed();
4469 updatePreviewImage();
4470}
4471
4472void QgsRasterFillSymbolLayerWidget::offsetChanged()
4473{
4474 mLayer->setOffset( QPointF( mSpinOffsetX->value(), mSpinOffsetY->value() ) );
4475 emit changed();
4476}
4477
4478void QgsRasterFillSymbolLayerWidget::mOffsetUnitWidget_changed()
4479{
4480 if ( !mLayer )
4481 {
4482 return;
4483 }
4484 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
4485 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
4486 emit changed();
4487}
4488
4489void QgsRasterFillSymbolLayerWidget::mRotationSpinBox_valueChanged( double d )
4490{
4491 if ( mLayer )
4492 {
4493 mLayer->setAngle( d );
4494 emit changed();
4495 }
4496}
4497
4498void QgsRasterFillSymbolLayerWidget::updatePreviewImage()
4499{
4500 bool fitsInCache = false;
4501 const QImage image = QgsApplication::imageCache()->pathAsImage( mLayer->imageFilePath(), QSize( 150, 150 ), true, 1.0, fitsInCache );
4502 if ( image.isNull() )
4503 {
4504 mLabelImagePreview->setPixmap( QPixmap() );
4505 return;
4506 }
4507
4508 QImage previewImage( 150, 150, QImage::Format_ARGB32 );
4509 previewImage.fill( Qt::transparent );
4510 const QRect imageRect( ( 150 - image.width() ) / 2.0, ( 150 - image.height() ) / 2.0, image.width(), image.height() );
4511 QPainter p;
4512 p.begin( &previewImage );
4513 //draw a checkerboard background
4514 uchar pixDataRGB[] = { 150, 150, 150, 150, 100, 100, 100, 150, 100, 100, 100, 150, 150, 150, 150, 150 };
4515 const QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
4516 const QPixmap pix = QPixmap::fromImage( img.scaled( 8, 8 ) );
4517 QBrush checkerBrush;
4518 checkerBrush.setTexture( pix );
4519 p.fillRect( imageRect, checkerBrush );
4520
4521 if ( mLayer->opacity() < 1.0 )
4522 {
4523 p.setOpacity( mLayer->opacity() );
4524 }
4525
4526 p.drawImage( imageRect.left(), imageRect.top(), image );
4527 p.end();
4528 mLabelImagePreview->setPixmap( QPixmap::fromImage( previewImage ) );
4529}
4530
4531//
4532// QgsRasterLineSymbolLayerWidget
4533//
4534
4535
4537 : QgsSymbolLayerWidget( parent, vl )
4538{
4539 mLayer = nullptr;
4540 setupUi( this );
4541
4542 mImageSourceLineEdit->setLastPathSettingsKey( QStringLiteral( "/UI/lastRasterMarkerImageDir" ) );
4543
4546
4547 connect( mPenWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
4548 if ( mLayer )
4549 {
4550 mLayer->setWidthUnit( mPenWidthUnitWidget->unit() );
4551 mLayer->setWidthMapUnitScale( mPenWidthUnitWidget->getMapUnitScale() );
4552 emit changed();
4553 }
4554 } );
4555
4556 connect( spinWidth, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this] {
4557 if ( mLayer )
4558 {
4559 mLayer->setWidth( spinWidth->value() );
4560 emit changed();
4561 }
4562 } );
4563
4564 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
4565 if ( mLayer )
4566 {
4567 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
4568 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
4569 emit changed();
4570 }
4571 } );
4572
4573
4574 spinOffset->setClearValue( 0.0 );
4575 connect( spinOffset, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double val ) {
4576 if ( mLayer )
4577 {
4578 mLayer->setOffset( val );
4579 emit changed();
4580 }
4581 } );
4582
4583 connect( cboCapStyle, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this] {
4584 if ( mLayer )
4585 {
4586 mLayer->setPenCapStyle( cboCapStyle->penCapStyle() );
4587 emit changed();
4588 }
4589 } );
4590 connect( cboJoinStyle, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this] {
4591 if ( mLayer )
4592 {
4593 mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
4594 emit changed();
4595 }
4596 } );
4597
4598 connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsRasterLineSymbolLayerWidget::imageSourceChanged );
4599 connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, [this]( double opacity ) {
4600 if ( mLayer )
4601 {
4602 mLayer->setOpacity( opacity );
4603 updatePreviewImage();
4604 emit changed();
4605 }
4606 } );
4607}
4608
4610{
4611 if ( !layer )
4612 {
4613 return;
4614 }
4615
4616 if ( layer->layerType() != QLatin1String( "RasterLine" ) )
4617 {
4618 return;
4619 }
4620
4621 mLayer = dynamic_cast<QgsRasterLineSymbolLayer *>( layer );
4622 if ( !mLayer )
4623 {
4624 return;
4625 }
4626
4627 whileBlocking( mImageSourceLineEdit )->setSource( mLayer->path() );
4628 whileBlocking( mOpacityWidget )->setOpacity( mLayer->opacity() );
4629
4630 whileBlocking( spinWidth )->setValue( mLayer->width() );
4631 whileBlocking( mPenWidthUnitWidget )->setUnit( mLayer->widthUnit() );
4632 whileBlocking( mPenWidthUnitWidget )->setMapUnitScale( mLayer->widthMapUnitScale() );
4633 whileBlocking( cboJoinStyle )->setPenJoinStyle( mLayer->penJoinStyle() );
4634 whileBlocking( cboCapStyle )->setPenCapStyle( mLayer->penCapStyle() );
4635
4636 whileBlocking( mOffsetUnitWidget )->setUnit( mLayer->offsetUnit() );
4637 whileBlocking( mOffsetUnitWidget )->setMapUnitScale( mLayer->offsetMapUnitScale() );
4638 whileBlocking( spinOffset )->setValue( mLayer->offset() );
4639
4640 updatePreviewImage();
4641
4648}
4649
4654
4655void QgsRasterLineSymbolLayerWidget::imageSourceChanged( const QString &text )
4656{
4657 mLayer->setPath( text );
4658 updatePreviewImage();
4659 emit changed();
4660}
4661
4662void QgsRasterLineSymbolLayerWidget::updatePreviewImage()
4663{
4664 bool fitsInCache = false;
4665 const QImage image = QgsApplication::imageCache()->pathAsImage( mLayer->path(), QSize( 150, 150 ), true, 1.0, fitsInCache );
4666 if ( image.isNull() )
4667 {
4668 mLabelImagePreview->setPixmap( QPixmap() );
4669 return;
4670 }
4671
4672 QImage previewImage( 150, 150, QImage::Format_ARGB32 );
4673 previewImage.fill( Qt::transparent );
4674 const QRect imageRect( ( 150 - image.width() ) / 2.0, ( 150 - image.height() ) / 2.0, image.width(), image.height() );
4675 QPainter p;
4676 p.begin( &previewImage );
4677 //draw a checkerboard background
4678 uchar pixDataRGB[] = { 150, 150, 150, 150, 100, 100, 100, 150, 100, 100, 100, 150, 150, 150, 150, 150 };
4679 const QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
4680 const QPixmap pix = QPixmap::fromImage( img.scaled( 8, 8 ) );
4681 QBrush checkerBrush;
4682 checkerBrush.setTexture( pix );
4683 p.fillRect( imageRect, checkerBrush );
4684
4685 if ( mLayer->opacity() < 1.0 )
4686 {
4687 p.setOpacity( mLayer->opacity() );
4688 }
4689
4690 p.drawImage( imageRect.left(), imageRect.top(), image );
4691 p.end();
4692 mLabelImagePreview->setPixmap( QPixmap::fromImage( previewImage ) );
4693}
4694
4695
4696//
4697// QgsGeometryGeneratorSymbolLayerWidget
4698//
4699
4701 : QgsSymbolLayerWidget( parent, vl )
4702
4703{
4704 setupUi( this );
4705 modificationExpressionSelector->setMultiLine( true );
4706 modificationExpressionSelector->setLayer( const_cast<QgsVectorLayer *>( vl ) );
4707 modificationExpressionSelector->registerExpressionContextGenerator( this );
4708 cbxGeometryType->addItem( QgsIconUtils::iconPolygon(), tr( "Polygon / MultiPolygon" ), static_cast<int>( Qgis::SymbolType::Fill ) );
4709 cbxGeometryType->addItem( QgsIconUtils::iconLine(), tr( "LineString / MultiLineString" ), static_cast<int>( Qgis::SymbolType::Line ) );
4710 cbxGeometryType->addItem( QgsIconUtils::iconPoint(), tr( "Point / MultiPoint" ), static_cast<int>( Qgis::SymbolType::Marker ) );
4711
4713 mUnitWidget->setShowMapScaleButton( false );
4714
4715 connect( modificationExpressionSelector, &QgsExpressionLineEdit::expressionChanged, this, &QgsGeometryGeneratorSymbolLayerWidget::updateExpression );
4716 connect( cbxGeometryType, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGeometryGeneratorSymbolLayerWidget::updateSymbolType );
4717 connect( mUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
4718 if ( !mBlockSignals )
4719 {
4720 mLayer->setUnits( mUnitWidget->unit() );
4721 emit symbolChanged();
4722 }
4723 } );
4724}
4725
4727{
4728 mBlockSignals++;
4729 mLayer = static_cast<QgsGeometryGeneratorSymbolLayer *>( l );
4730 modificationExpressionSelector->setExpression( mLayer->geometryExpression() );
4731 cbxGeometryType->setCurrentIndex( cbxGeometryType->findData( static_cast<int>( mLayer->symbolType() ) ) );
4732 mUnitWidget->setUnit( mLayer->units() );
4733 mBlockSignals--;
4734}
4735
4740
4741void QgsGeometryGeneratorSymbolLayerWidget::updateExpression( const QString &string )
4742{
4743 mLayer->setGeometryExpression( string );
4744
4745 emit changed();
4746}
4747
4748void QgsGeometryGeneratorSymbolLayerWidget::updateSymbolType()
4749{
4750 // we try to keep the subsymbol, if we can!
4751 std::unique_ptr<QgsSymbol> subSymbol( mLayer->subSymbol()->clone() );
4752
4753 mLayer->setSymbolType( static_cast<Qgis::SymbolType>( cbxGeometryType->currentData().toInt() ) );
4754
4755 switch ( mLayer->symbolType() )
4756 {
4759 break;
4761 {
4762 if ( subSymbol->type() == Qgis::SymbolType::Fill )
4763 {
4764 // going from fill -> line type, so we can copy any LINE symbol layers across
4765 QgsSymbolLayerList layers;
4766 for ( int i = 0; i < subSymbol->symbolLayerCount(); ++i )
4767 {
4768 if ( dynamic_cast<const QgsLineSymbolLayer *>( subSymbol->symbolLayer( i ) ) )
4769 layers << subSymbol->symbolLayer( i )->clone();
4770 }
4771
4772 if ( !layers.empty() )
4773 mLayer->setSubSymbol( new QgsLineSymbol( layers ) );
4774 }
4775 break;
4776 }
4778 if ( subSymbol->type() == Qgis::SymbolType::Line )
4779 {
4780 // going from line -> fill type, so copy ALL line symbol layers across
4781 QgsSymbolLayerList layers;
4782 for ( int i = 0; i < subSymbol->symbolLayerCount(); ++i )
4783 layers << subSymbol->symbolLayer( i )->clone();
4784 mLayer->setSubSymbol( new QgsFillSymbol( layers ) );
4785 }
4786 break;
4787 }
4788
4789 emit symbolChanged();
4790}
4791
4792//
4793// QgsRandomMarkerFillSymbolLayerWidget
4794//
4795
4796
4798 : QgsSymbolLayerWidget( parent, vl )
4799{
4800 setupUi( this );
4801
4802 mCountMethodComboBox->addItem( tr( "Absolute Count" ), static_cast<int>( Qgis::PointCountMethod::Absolute ) );
4803 mCountMethodComboBox->addItem( tr( "Density-based Count" ), static_cast<int>( Qgis::PointCountMethod::DensityBased ) );
4804
4805 mPointCountSpinBox->setShowClearButton( true );
4806 mPointCountSpinBox->setClearValue( 100 );
4807 mSeedSpinBox->setShowClearButton( true );
4808 mSeedSpinBox->setClearValue( 0 );
4809
4810 connect( mCountMethodComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRandomMarkerFillSymbolLayerWidget::countMethodChanged );
4811 connect( mPointCountSpinBox, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ), this, &QgsRandomMarkerFillSymbolLayerWidget::countChanged );
4812 connect( mDensityAreaSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRandomMarkerFillSymbolLayerWidget::densityAreaChanged );
4813 connect( mSeedSpinBox, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ), this, &QgsRandomMarkerFillSymbolLayerWidget::seedChanged );
4814 connect( mClipPointsCheckBox, &QCheckBox::toggled, this, [this]( bool checked ) {
4815 if ( mLayer )
4816 {
4817 mLayer->setClipPoints( checked );
4818 emit changed();
4819 }
4820 } );
4821
4823
4824 connect( mDensityAreaUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRandomMarkerFillSymbolLayerWidget::densityAreaUnitChanged );
4825}
4826
4828{
4829 if ( !layer || layer->layerType() != QLatin1String( "RandomMarkerFill" ) )
4830 {
4831 return;
4832 }
4833
4834 mLayer = static_cast<QgsRandomMarkerFillSymbolLayer *>( layer );
4835 whileBlocking( mPointCountSpinBox )->setValue( mLayer->pointCount() );
4836 whileBlocking( mSeedSpinBox )->setValue( mLayer->seed() );
4837 whileBlocking( mClipPointsCheckBox )->setChecked( mLayer->clipPoints() );
4838
4839 bool showDensityBasedCountWidgets = false;
4840 switch ( mLayer->countMethod() )
4841 {
4843 showDensityBasedCountWidgets = true;
4844 break;
4846 break;
4847 }
4848 mDensityAreaLabel->setVisible( showDensityBasedCountWidgets );
4849 mDensityAreaSpinBox->setVisible( showDensityBasedCountWidgets );
4850 mDensityAreaUnitWidget->setVisible( showDensityBasedCountWidgets );
4851 mDensityAreaDdbtn->setVisible( showDensityBasedCountWidgets );
4852
4853 whileBlocking( mCountMethodComboBox )->setCurrentIndex( mCountMethodComboBox->findData( static_cast<int>( mLayer->countMethod() ) ) );
4854 whileBlocking( mDensityAreaSpinBox )->setValue( mLayer->densityArea() );
4855 mDensityAreaUnitWidget->blockSignals( true );
4856 mDensityAreaUnitWidget->setUnit( mLayer->densityAreaUnit() );
4857 mDensityAreaUnitWidget->setMapUnitScale( mLayer->densityAreaUnitScale() );
4858 mDensityAreaUnitWidget->blockSignals( false );
4859
4864}
4865
4870
4871void QgsRandomMarkerFillSymbolLayerWidget::countMethodChanged( int )
4872{
4873 bool showDensityBasedCountWidgets = false;
4874 switch ( static_cast<Qgis::PointCountMethod>( mCountMethodComboBox->currentData().toInt() ) )
4875 {
4877 showDensityBasedCountWidgets = true;
4878 break;
4880 break;
4881 }
4882 mDensityAreaLabel->setVisible( showDensityBasedCountWidgets );
4883 mDensityAreaSpinBox->setVisible( showDensityBasedCountWidgets );
4884 mDensityAreaUnitWidget->setVisible( showDensityBasedCountWidgets );
4885 mDensityAreaDdbtn->setVisible( showDensityBasedCountWidgets );
4886
4887 if ( mLayer )
4888 {
4889 mLayer->setCountMethod( static_cast<Qgis::PointCountMethod>( mCountMethodComboBox->currentData().toInt() ) );
4890 emit changed();
4891 }
4892}
4893
4894void QgsRandomMarkerFillSymbolLayerWidget::countChanged( int d )
4895{
4896 if ( mLayer )
4897 {
4898 mLayer->setPointCount( d );
4899 emit changed();
4900 }
4901}
4902
4903void QgsRandomMarkerFillSymbolLayerWidget::densityAreaChanged( double d )
4904{
4905 if ( mLayer )
4906 {
4907 mLayer->setDensityArea( d );
4908 emit changed();
4909 }
4910}
4911
4912void QgsRandomMarkerFillSymbolLayerWidget::densityAreaUnitChanged()
4913{
4914 if ( mLayer )
4915 {
4916 mLayer->setDensityAreaUnit( mDensityAreaUnitWidget->unit() );
4917 mLayer->setDensityAreaUnitScale( mDensityAreaUnitWidget->getMapUnitScale() );
4918 emit changed();
4919 }
4920}
4921
4922void QgsRandomMarkerFillSymbolLayerWidget::seedChanged( int d )
4923{
4924 if ( mLayer )
4925 {
4926 mLayer->setSeed( d );
4927 emit changed();
4928 }
4929}
4930
4931//
4932// QgsGradientLineSymbolLayerWidget
4933//
4934
4936 : QgsSymbolLayerWidget( parent, vl )
4937{
4938 mLayer = nullptr;
4939 setupUi( this );
4940
4941 btnColorRamp->setShowGradientOnly( true );
4942
4943 btnChangeColor->setAllowOpacity( true );
4944 btnChangeColor->setColorDialogTitle( tr( "Select Gradient Color" ) );
4945 btnChangeColor->setContext( QStringLiteral( "symbology" ) );
4946 btnChangeColor->setShowNoColor( true );
4947 btnChangeColor->setNoColorString( tr( "Transparent" ) );
4948 btnChangeColor2->setAllowOpacity( true );
4949 btnChangeColor2->setColorDialogTitle( tr( "Select Gradient Color" ) );
4950 btnChangeColor2->setContext( QStringLiteral( "symbology" ) );
4951 btnChangeColor2->setShowNoColor( true );
4952 btnChangeColor2->setNoColorString( tr( "Transparent" ) );
4953
4954 mStartColorDDBtn->registerLinkedWidget( btnChangeColor );
4955 mEndColorDDBtn->registerLinkedWidget( btnChangeColor2 );
4956
4957 connect( btnChangeColor, &QgsColorButton::colorChanged, this, [this]( const QColor &color ) {
4958 if ( mLayer )
4959 {
4960 mLayer->setColor( color );
4961 emit changed();
4962 }
4963 } );
4964 connect( btnChangeColor2, &QgsColorButton::colorChanged, this, [this]( const QColor &color ) {
4965 if ( mLayer )
4966 {
4967 mLayer->setColor2( color );
4968 emit changed();
4969 }
4970 } );
4971 connect( btnColorRamp, &QgsColorRampButton::colorRampChanged, this, [this] {
4972 if ( btnColorRamp->isNull() )
4973 return;
4974
4975 if ( mLayer )
4976 {
4977 mLayer->setColorRamp( btnColorRamp->colorRamp()->clone() );
4978 emit changed();
4979 }
4980 } );
4981
4982 connect( radioTwoColor, &QAbstractButton::toggled, this, [this] {
4983 if ( mLayer )
4984 {
4985 if ( radioTwoColor->isChecked() )
4986 {
4987 mLayer->setGradientColorType( Qgis::GradientColorSource::SimpleTwoColor );
4988 btnChangeColor->setEnabled( true );
4989 btnChangeColor2->setEnabled( true );
4990 btnColorRamp->setEnabled( false );
4991 }
4992 else
4993 {
4994 mLayer->setGradientColorType( Qgis::GradientColorSource::ColorRamp );
4995 btnColorRamp->setEnabled( true );
4996 btnChangeColor->setEnabled( false );
4997 btnChangeColor2->setEnabled( false );
4998 }
4999 emit changed();
5000 }
5001 } );
5002
5005
5006 connect( mPenWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
5007 if ( mLayer )
5008 {
5009 mLayer->setWidthUnit( mPenWidthUnitWidget->unit() );
5010 mLayer->setWidthMapUnitScale( mPenWidthUnitWidget->getMapUnitScale() );
5011 emit changed();
5012 }
5013 } );
5014
5015 connect( spinWidth, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, [this] {
5016 if ( mLayer )
5017 {
5018 mLayer->setWidth( spinWidth->value() );
5019 emit changed();
5020 }
5021 } );
5022
5023 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
5024 if ( mLayer )
5025 {
5026 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
5027 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
5028 emit changed();
5029 }
5030 } );
5031
5032 spinOffset->setClearValue( 0.0 );
5033 connect( spinOffset, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double val ) {
5034 if ( mLayer )
5035 {
5036 mLayer->setOffset( val );
5037 emit changed();
5038 }
5039 } );
5040
5041 connect( cboCapStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [this] {
5042 if ( mLayer )
5043 {
5044 mLayer->setPenCapStyle( cboCapStyle->penCapStyle() );
5045 emit changed();
5046 }
5047 } );
5048 connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [this] {
5049 if ( mLayer )
5050 {
5051 mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
5052 emit changed();
5053 }
5054 } );
5055}
5056
5058{
5059 if ( !layer )
5060 {
5061 return;
5062 }
5063
5064 if ( layer->layerType() != QLatin1String( "Lineburst" ) )
5065 {
5066 return;
5067 }
5068
5069 mLayer = dynamic_cast<QgsLineburstSymbolLayer *>( layer );
5070 if ( !mLayer )
5071 {
5072 return;
5073 }
5074
5075 btnChangeColor->blockSignals( true );
5076 btnChangeColor->setColor( mLayer->color() );
5077 btnChangeColor->blockSignals( false );
5078 btnChangeColor2->blockSignals( true );
5079 btnChangeColor2->setColor( mLayer->color2() );
5080 btnChangeColor2->blockSignals( false );
5081
5082 if ( mLayer->gradientColorType() == Qgis::GradientColorSource::SimpleTwoColor )
5083 {
5084 radioTwoColor->setChecked( true );
5085 btnColorRamp->setEnabled( false );
5086 }
5087 else
5088 {
5089 radioColorRamp->setChecked( true );
5090 btnChangeColor->setEnabled( false );
5091 btnChangeColor2->setEnabled( false );
5092 }
5093
5094 // set source color ramp
5095 if ( mLayer->colorRamp() )
5096 {
5097 btnColorRamp->blockSignals( true );
5098 btnColorRamp->setColorRamp( mLayer->colorRamp() );
5099 btnColorRamp->blockSignals( false );
5100 }
5101
5102 whileBlocking( spinWidth )->setValue( mLayer->width() );
5103 whileBlocking( mPenWidthUnitWidget )->setUnit( mLayer->widthUnit() );
5104 whileBlocking( mPenWidthUnitWidget )->setMapUnitScale( mLayer->widthMapUnitScale() );
5105
5106 whileBlocking( mOffsetUnitWidget )->setUnit( mLayer->offsetUnit() );
5107 whileBlocking( mOffsetUnitWidget )->setMapUnitScale( mLayer->offsetMapUnitScale() );
5108 whileBlocking( spinOffset )->setValue( mLayer->offset() );
5109
5110 whileBlocking( cboJoinStyle )->setPenJoinStyle( mLayer->penJoinStyle() );
5111 whileBlocking( cboCapStyle )->setPenCapStyle( mLayer->penCapStyle() );
5112
5119}
5120
5125
5126//
5127// QgsFilledLineSymbolLayerWidget
5128//
5129
5131 : QgsSymbolLayerWidget( parent, vl )
5132{
5133 mLayer = nullptr;
5134 setupUi( this );
5135
5138
5139 connect( mPenWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
5140 if ( mLayer )
5141 {
5142 mLayer->setWidthUnit( mPenWidthUnitWidget->unit() );
5143 mLayer->setWidthMapUnitScale( mPenWidthUnitWidget->getMapUnitScale() );
5144 emit changed();
5145 }
5146 } );
5147
5148 connect( spinWidth, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, [this] {
5149 if ( mLayer )
5150 {
5151 mLayer->setWidth( spinWidth->value() );
5152 emit changed();
5153 }
5154 } );
5155
5156 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
5157 if ( mLayer )
5158 {
5159 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
5160 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
5161 emit changed();
5162 }
5163 } );
5164
5165 spinOffset->setClearValue( 0.0 );
5166 connect( spinOffset, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double val ) {
5167 if ( mLayer )
5168 {
5169 mLayer->setOffset( val );
5170 emit changed();
5171 }
5172 } );
5173
5174 connect( cboCapStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [this] {
5175 if ( mLayer )
5176 {
5177 mLayer->setPenCapStyle( cboCapStyle->penCapStyle() );
5178 emit changed();
5179 }
5180 } );
5181 connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [this] {
5182 if ( mLayer )
5183 {
5184 mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
5185 emit changed();
5186 }
5187 } );
5188}
5189
5191
5193{
5194 if ( !layer )
5195 {
5196 return;
5197 }
5198
5199 if ( layer->layerType() != QLatin1String( "FilledLine" ) )
5200 {
5201 return;
5202 }
5203
5204 mLayer = dynamic_cast<QgsFilledLineSymbolLayer *>( layer );
5205 if ( !mLayer )
5206 {
5207 return;
5208 }
5209
5210 whileBlocking( spinWidth )->setValue( mLayer->width() );
5211 whileBlocking( mPenWidthUnitWidget )->setUnit( mLayer->widthUnit() );
5212 whileBlocking( mPenWidthUnitWidget )->setMapUnitScale( mLayer->widthMapUnitScale() );
5213
5214 whileBlocking( mOffsetUnitWidget )->setUnit( mLayer->offsetUnit() );
5215 whileBlocking( mOffsetUnitWidget )->setMapUnitScale( mLayer->offsetMapUnitScale() );
5216 whileBlocking( spinOffset )->setValue( mLayer->offset() );
5217
5218 whileBlocking( cboJoinStyle )->setPenJoinStyle( mLayer->penJoinStyle() );
5219 whileBlocking( cboCapStyle )->setPenCapStyle( mLayer->penCapStyle() );
5220
5225}
5226
5231
5232//
5233// QgsLinearReferencingSymbolLayerWidget
5234//
5235
5237 : QgsSymbolLayerWidget( parent, vl )
5238{
5239 mLayer = nullptr;
5240
5241 setupUi( this );
5242
5243 mComboPlacement->addItem( tr( "Interval (Cartesian 2D Distances)" ), QVariant::fromValue( Qgis::LinearReferencingPlacement::IntervalCartesian2D ) );
5244 mComboPlacement->addItem( tr( "Interval (Z Values)" ), QVariant::fromValue( Qgis::LinearReferencingPlacement::IntervalZ ) );
5245 mComboPlacement->addItem( tr( "Interval (M Values)" ), QVariant::fromValue( Qgis::LinearReferencingPlacement::IntervalM ) );
5246 mComboPlacement->addItem( tr( "On Every Vertex" ), QVariant::fromValue( Qgis::LinearReferencingPlacement::Vertex ) );
5247
5248 mComboQuantity->addItem( tr( "Cartesian 2D Distance" ), QVariant::fromValue( Qgis::LinearReferencingLabelSource::CartesianDistance2D ) );
5249 mComboQuantity->addItem( tr( "Z Values" ), QVariant::fromValue( Qgis::LinearReferencingLabelSource::Z ) );
5250 mComboQuantity->addItem( tr( "M Values" ), QVariant::fromValue( Qgis::LinearReferencingLabelSource::M ) );
5251
5252 mSpinSkipMultiples->setClearValue( 0, tr( "Not set" ) );
5253 mSpinLabelOffsetX->setClearValue( 0 );
5254 mSpinLabelOffsetY->setClearValue( 0 );
5255 mSpinAverageAngleLength->setClearValue( 4.0 );
5258
5259 connect( mComboQuantity, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this] {
5260 if ( mLayer && !mBlockChangesSignal )
5261 {
5262 mLayer->setLabelSource( mComboQuantity->currentData().value<Qgis::LinearReferencingLabelSource>() );
5263 emit changed();
5264 }
5265 } );
5266 connect( mTextFormatButton, &QgsFontButton::changed, this, [this] {
5267 if ( mLayer && !mBlockChangesSignal )
5268 {
5269 mLayer->setTextFormat( mTextFormatButton->textFormat() );
5270 emit changed();
5271 }
5272 } );
5273 connect( spinInterval, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, [this] {
5274 if ( mLayer && !mBlockChangesSignal )
5275 {
5276 mLayer->setInterval( spinInterval->value() );
5277 emit changed();
5278 }
5279 } );
5280 connect( mSpinSkipMultiples, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, [this] {
5281 if ( mLayer && !mBlockChangesSignal )
5282 {
5283 mLayer->setSkipMultiplesOf( mSpinSkipMultiples->value() );
5284 emit changed();
5285 }
5286 } );
5287 connect( mCheckRotate, &QCheckBox::toggled, this, [this]( bool checked ) {
5288 if ( mLayer && !mBlockChangesSignal )
5289 {
5290 mLayer->setRotateLabels( checked );
5291 emit changed();
5292 }
5293 mSpinAverageAngleLength->setEnabled( checked );
5294 mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
5295 } );
5296 connect( mCheckShowMarker, &QCheckBox::toggled, this, [this]( bool checked ) {
5297 if ( mLayer && !mBlockChangesSignal )
5298 {
5299 mLayer->setShowMarker( checked );
5300 emit symbolChanged();
5301 }
5302 } );
5303
5304 connect( mSpinLabelOffsetX, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, [this] {
5305 if ( mLayer && !mBlockChangesSignal )
5306 {
5307 mLayer->setLabelOffset( QPointF( mSpinLabelOffsetX->value(), mSpinLabelOffsetY->value() ) );
5308 emit changed();
5309 }
5310 } );
5311 connect( mSpinLabelOffsetY, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, [this] {
5312 if ( mLayer && !mBlockChangesSignal )
5313 {
5314 mLayer->setLabelOffset( QPointF( mSpinLabelOffsetX->value(), mSpinLabelOffsetY->value() ) );
5315 emit changed();
5316 }
5317 } );
5318 connect( mLabelOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
5319 if ( mLayer && !mBlockChangesSignal )
5320 {
5321 mLayer->setLabelOffsetUnit( mLabelOffsetUnitWidget->unit() );
5322 mLayer->setLabelOffsetMapUnitScale( mLabelOffsetUnitWidget->getMapUnitScale() );
5323 emit changed();
5324 }
5325 } );
5326
5327 connect( mComboPlacement, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this] {
5328 if ( mLayer && !mBlockChangesSignal )
5329 {
5330 const Qgis::LinearReferencingPlacement placement = mComboPlacement->currentData().value<Qgis::LinearReferencingPlacement>();
5331 mLayer->setPlacement( placement );
5332 switch ( placement )
5333 {
5337 mIntervalWidget->show();
5338 break;
5340 mIntervalWidget->hide();
5341 break;
5342 }
5343 emit changed();
5344 }
5345 } );
5346
5347 connect( mSpinAverageAngleLength, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, [this] {
5348 if ( mLayer && !mBlockChangesSignal )
5349 {
5350 mLayer->setAverageAngleLength( mSpinAverageAngleLength->value() );
5351 emit changed();
5352 }
5353 } );
5354 connect( mAverageAngleUnit, &QgsUnitSelectionWidget::changed, this, [this] {
5355 if ( mLayer && !mBlockChangesSignal )
5356 {
5357 mLayer->setAverageAngleUnit( mAverageAngleUnit->unit() );
5358 mLayer->setAverageAngleMapUnitScale( mAverageAngleUnit->getMapUnitScale() );
5359 emit changed();
5360 }
5361 } );
5362
5363 connect( mNumberFormatPushButton, &QPushButton::clicked, this, &QgsLinearReferencingSymbolLayerWidget::changeNumberFormat );
5364
5365 mTextFormatButton->registerExpressionContextGenerator( this );
5366}
5367
5369
5370
5372{
5373 if ( !layer || layer->layerType() != QLatin1String( "LinearReferencing" ) )
5374 return;
5375
5376 // layer type is correct, we can do the cast
5377 mLayer = qgis::down_cast<QgsLinearReferencingSymbolLayer *>( layer );
5378
5379 mBlockChangesSignal = true;
5380
5381 mComboPlacement->setCurrentIndex( mComboPlacement->findData( QVariant::fromValue( mLayer->placement() ) ) );
5382 switch ( mLayer->placement() )
5383 {
5387 mIntervalWidget->show();
5388 break;
5390 mIntervalWidget->hide();
5391 break;
5392 }
5393
5394 mComboQuantity->setCurrentIndex( mComboQuantity->findData( QVariant::fromValue( mLayer->labelSource() ) ) );
5395
5396 mTextFormatButton->setTextFormat( mLayer->textFormat() );
5397 spinInterval->setValue( mLayer->interval() );
5398 mSpinSkipMultiples->setValue( mLayer->skipMultiplesOf() );
5399 mCheckRotate->setChecked( mLayer->rotateLabels() );
5400 mCheckShowMarker->setChecked( mLayer->showMarker() );
5401 mSpinLabelOffsetX->setValue( mLayer->labelOffset().x() );
5402 mSpinLabelOffsetY->setValue( mLayer->labelOffset().y() );
5403 mLabelOffsetUnitWidget->setUnit( mLayer->labelOffsetUnit() );
5404 mLabelOffsetUnitWidget->setMapUnitScale( mLayer->labelOffsetMapUnitScale() );
5405
5406 mAverageAngleUnit->setUnit( mLayer->averageAngleUnit() );
5407 mAverageAngleUnit->setMapUnitScale( mLayer->averageAngleMapUnitScale() );
5408 mSpinAverageAngleLength->setValue( mLayer->averageAngleLength() );
5409
5410 mSpinAverageAngleLength->setEnabled( mCheckRotate->isChecked() );
5411 mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
5412
5417
5418 mBlockChangesSignal = false;
5419}
5420
5425
5427{
5429 mTextFormatButton->setMapCanvas( context.mapCanvas() );
5430 mTextFormatButton->setMessageBar( context.messageBar() );
5431}
5432
5433void QgsLinearReferencingSymbolLayerWidget::changeNumberFormat()
5434{
5436 if ( panel && panel->dockMode() )
5437 {
5439 widget->setPanelTitle( tr( "Number Format" ) );
5440 widget->setFormat( mLayer->numericFormat() );
5441 widget->registerExpressionContextGenerator( this );
5442 connect( widget, &QgsNumericFormatSelectorWidget::changed, this, [this, widget] {
5443 if ( !mBlockChangesSignal )
5444 {
5445 mLayer->setNumericFormat( widget->format() );
5446 emit changed();
5447 }
5448 } );
5449 panel->openPanel( widget );
5450 }
5451 else
5452 {
5453 QgsNumericFormatSelectorDialog dialog( this );
5454 dialog.setFormat( mLayer->numericFormat() );
5455 dialog.registerExpressionContextGenerator( this );
5456 if ( dialog.exec() )
5457 {
5458 mLayer->setNumericFormat( dialog.format() );
5459 emit changed();
5460 }
5461 }
5462}
A widget for displaying characters available in a preset font, and allowing users to select an indivi...
void characterSelected(QChar character)
Emitted when a character is selected in the widget.
void setFont(const QFont &font)
Sets the font to show in the widget.
@ CurvePoint
Place symbols at every virtual curve point in the line (used when rendering curved geometry types onl...
Definition qgis.h:3135
@ InnerVertices
Inner vertices (i.e. all vertices except the first and last vertex).
Definition qgis.h:3137
@ LastVertex
Place symbols on the last vertex in the line.
Definition qgis.h:3132
@ CentralPoint
Place symbols at the mid point of the line.
Definition qgis.h:3134
@ SegmentCenter
Place symbols at the center of every line segment.
Definition qgis.h:3136
@ Vertex
Place symbols on every vertex in the line.
Definition qgis.h:3131
@ Interval
Place symbols at regular intervals.
Definition qgis.h:3130
@ FirstVertex
Place symbols on the first vertex in the line.
Definition qgis.h:3133
MarkerClipMode
Marker clipping modes.
Definition qgis.h:3249
@ CompletelyWithin
Render complete markers wherever the completely fall within the polygon shape.
Definition qgis.h:3253
@ NoClipping
No clipping, render complete markers.
Definition qgis.h:3250
@ Shape
Clip to polygon shape.
Definition qgis.h:3251
@ CentroidWithin
Render complete markers wherever their centroid falls within the polygon shape.
Definition qgis.h:3252
LineClipMode
Line clipping modes.
Definition qgis.h:3263
@ NoClipping
Lines are not clipped, will extend to shape's bounding box.
Definition qgis.h:3266
@ ClipPainterOnly
Applying clipping on the painter only (i.e. line endpoints will coincide with polygon bounding box,...
Definition qgis.h:3264
@ ClipToIntersection
Clip lines to intersection with polygon shape (slower) (i.e. line endpoints will coincide with polygo...
Definition qgis.h:3265
@ ColorRamp
Gradient color ramp.
Definition qgis.h:3180
@ SimpleTwoColor
Simple two color gradient.
Definition qgis.h:3179
@ Repeat
Repeat gradient.
Definition qgis.h:3225
@ Reflect
Reflect gradient.
Definition qgis.h:3224
@ Pad
Pad out gradient using colors at endpoint of gradient.
Definition qgis.h:3223
PointCountMethod
Methods which define the number of points randomly filling a polygon.
Definition qgis.h:3237
@ Absolute
The point count is used as an absolute count of markers.
Definition qgis.h:3238
@ DensityBased
The point count is part of a marker density count.
Definition qgis.h:3239
MarkerShape
Marker shapes.
Definition qgis.h:3080
VerticalAnchorPoint
Marker symbol vertical anchor points.
Definition qgis.h:814
@ Bottom
Align to bottom of symbol.
Definition qgis.h:817
@ Center
Align to vertical center of symbol.
Definition qgis.h:816
@ Baseline
Align to baseline of symbol, e.g. font baseline for font marker symbol layers. Treated as Bottom if n...
Definition qgis.h:818
@ Top
Align to top of symbol.
Definition qgis.h:815
LinearReferencingPlacement
Defines how/where the labels should be placed in a linear referencing symbol layer.
Definition qgis.h:3149
@ IntervalZ
Place labels at regular intervals, linearly interpolated using Z values.
Definition qgis.h:3151
@ Vertex
Place labels on every vertex in the line.
Definition qgis.h:3153
@ IntervalM
Place labels at regular intervals, linearly interpolated using M values.
Definition qgis.h:3152
@ IntervalCartesian2D
Place labels at regular intervals, using Cartesian distance calculations on a 2D plane.
Definition qgis.h:3150
LinearReferencingLabelSource
Defines what quantity to use for the labels shown in a linear referencing symbol layer.
Definition qgis.h:3163
@ CartesianDistance2D
Distance along line, calculated using Cartesian calculations on a 2D plane.
Definition qgis.h:3164
@ Percentage
Percentage of another measurement (e.g., canvas size, feature size).
Definition qgis.h:5187
@ Millimeters
Millimeters.
Definition qgis.h:5184
@ Points
Points (e.g., for font sizes).
Definition qgis.h:5188
@ MapUnits
Map units.
Definition qgis.h:5185
@ Pixels
Pixels.
Definition qgis.h:5186
@ Inches
Inches.
Definition qgis.h:5189
@ MetersInMapUnits
Meters value as Map units.
Definition qgis.h:5191
@ Linear
Linear gradient.
Definition qgis.h:3193
@ Conical
Conical (polar) gradient.
Definition qgis.h:3195
@ Radial
Radial (circular) gradient.
Definition qgis.h:3194
SymbolType
Symbol types.
Definition qgis.h:610
@ Marker
Marker symbol.
Definition qgis.h:611
@ Line
Line symbol.
Definition qgis.h:612
@ Fill
Fill symbol.
Definition qgis.h:613
@ Hybrid
Hybrid symbol.
Definition qgis.h:614
SymbolCoordinateReference
Symbol coordinate reference modes.
Definition qgis.h:3207
@ Feature
Relative to feature/shape being rendered.
Definition qgis.h:3208
@ Viewport
Relative to the whole viewport/output device.
Definition qgis.h:3209
QFlags< MarkerLinePlacement > MarkerLinePlacements
Definition qgis.h:3140
HorizontalAnchorPoint
Marker symbol horizontal anchor points.
Definition qgis.h:800
@ Center
Align to horizontal center of symbol.
Definition qgis.h:802
@ Right
Align to right side of symbol.
Definition qgis.h:803
@ Left
Align to left side of symbol.
Definition qgis.h:801
static const double UI_SCALE_FACTOR
UI scaling factor.
Definition qgis.h:6222
void sourceChanged(const QString &source)
Emitted whenever the file source is changed in the widget.
void setContext(const QgsSymbolWidgetContext &context) override
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
QgsAnimatedMarkerSymbolLayer * mLayer
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsAnimatedMarkerSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsAnimatedMarkerSymbolLayerWidget.
Animated marker symbol layer class.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QgsImageCache * imageCache()
Returns the application's image cache, used for caching resampled versions of raster images.
static QgsSvgCache * svgCache()
Returns the application's SVG cache, used for caching SVG images and handling parameter replacement w...
static QString nameFromProperty(const QgsPropertyDefinition &def, bool joined=false)
Returns the name of the auxiliary field for a property definition.
QgsSymbolLayer * symbolLayer() override
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsCentroidFillSymbolLayer * mLayer
QgsCentroidFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsCentroidFillSymbolLayerWidget.
A fill symbol layer which renders a marker symbol at the centroid of a polygon geometry.
void setPointOnSurface(bool pointOnSurface)
void colorChanged(const QColor &color)
Emitted whenever a new color is set for the button.
void colorRampChanged()
Emitted whenever a new color ramp is set for the button.
QVector< qreal > dashDotVector() const
Returns the dash pattern as a list of numbers.
void setUnit(Qgis::RenderUnit unit)
Sets the unit type used for the dash space pattern (used to update interface labels).
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
static QgsExpressionContextScope * updateSymbolScope(const QgsSymbol *symbol, QgsExpressionContextScope *symbolScope=nullptr)
Updates a symbol scope related to a QgsSymbol to an expression context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
static const QString EXPR_GEOMETRY_PART_COUNT
Inbuilt variable name for geometry part count variable.
static const QString EXPR_GEOMETRY_POINT_COUNT
Inbuilt variable name for point count variable.
static const QString EXPR_CLUSTER_SIZE
Inbuilt variable name for cluster size variable.
static const QString EXPR_GEOMETRY_POINT_NUM
Inbuilt variable name for point number variable.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
static const QString EXPR_GEOMETRY_RING_NUM
Inbuilt variable name for geometry ring number variable.
static const QString EXPR_GEOMETRY_PART_NUM
Inbuilt variable name for geometry part number variable.
static const QString EXPR_SYMBOL_COLOR
Inbuilt variable name for symbol color variable.
QgsExpressionContextScope * lastScope()
Returns the last scope added to the context.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
bool hasVariable(const QString &name) const
Check whether a variable is specified by any scope within the context.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user.
static const QString EXPR_ORIGINAL_VALUE
Inbuilt variable name for value original value variable.
static const QString EXPR_CLUSTER_COLOR
Inbuilt variable name for cluster color variable.
void expressionChanged(const QString &expression)
Emitted when the expression is changed.
~QgsFilledLineSymbolLayerWidget() override
QgsSymbolLayer * symbolLayer() override
QgsFilledLineSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsFilledLineSymbolLayerWidget.
void setSymbolLayer(QgsSymbolLayer *layer) override
A line symbol layer type which fills a stroked line with a QgsFillSymbol.
void setMapUnitScale(const QgsMapUnitScale &scale) override
QgsFilledMarkerSymbolLayer * mLayer
QgsSymbolLayer * symbolLayer() override
QgsFilledMarkerSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsFilledMarkerSymbolLayerWidget.
void setSymbolLayer(QgsSymbolLayer *layer) override
Filled marker symbol layer, consisting of a shape which is rendered using a QgsFillSymbol.
void changed()
Emitted when the widget's text format settings are changed.
QgsFontMarkerSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsFontMarkerSymbolLayerWidget.
void setCharacter(QChar chr)
Set the font marker character from char.
void setSymbolLayer(QgsSymbolLayer *layer) override
~QgsFontMarkerSymbolLayerWidget() override
QgsSymbolLayer * symbolLayer() override
QgsFontMarkerSymbolLayer * mLayer
void setCharacterFromText(const QString &text)
Set the font marker character from a text string.
void setColorStroke(const QColor &color)
Set stroke color.
A marker symbol layer which displays characters rendered using a font.
void setFontStyle(const QString &style)
Sets the font style for the font which will be used to render the point.
static QString translateNamedStyle(const QString &namedStyle)
Returns the localized named style of a font, if such a translation is available.
static QString untranslateNamedStyle(const QString &namedStyle)
Returns the english named style of a font, if possible.
static QFont createFont(const QString &family, int pointSize=-1, int weight=-1, bool italic=false)
Creates a font with the specified family.
static bool updateFontViaStyle(QFont &f, const QString &fontstyle, bool fallback=false)
Updates font with named style and retain all font properties.
static void setFontFamily(QFont &font, const QString &family)
Sets the family for a font object.
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsGeometryGeneratorSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsGeometryGeneratorSymbolLayerWidget.
A symbol layer subclass which alters rendered feature shapes through the use of QGIS expressions.
void setGeometryExpression(const QString &exp)
Set the expression to generate this geometry.
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsGradientFillSymbolLayer * mLayer
QgsSymbolLayer * symbolLayer() override
void applyColorRamp()
Applies the color ramp passed on by the color ramp button.
QgsGradientFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsGradientFillSymbolLayerWidget.
A fill symbol layer which draws a smooth color gradient over a polygon.
void setOffset(QPointF offset)
Sets an offset by which polygons will be translated during rendering.
void setGradientColorType(Qgis::GradientColorSource gradientColorType)
Sets the gradient color mode, which controls how gradient color stops are created.
QgsHashedLineSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsHashedLineSymbolLayerWidget.
Line symbol layer type which draws repeating line sections along a line feature.
void setHashLength(double length)
Sets the length of hash symbols.
double hashAngle() const
Returns the angle to use when drawing the hashed lines sections, in degrees clockwise.
const QgsMapUnitScale & hashLengthMapUnitScale() const
Returns the map unit scale for the hash length.
void setHashLengthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the hash length.
Qgis::RenderUnit hashLengthUnit() const
Returns the units for the length of hash symbols.
double hashLength() const
Returns the length of hash symbols.
void setHashLengthUnit(Qgis::RenderUnit unit)
Sets the unit for the length of hash symbols.
void setHashAngle(double angle)
Sets the angle to use when drawing the hashed lines sections, in degrees clockwise.
static QIcon iconLine()
Returns an icon representing line geometries.
static QIcon iconPolygon()
Returns an icon representing polygon geometries.
static QIcon iconPoint()
Returns an icon representing point geometries.
int nextFrameDelay(const QString &path, int currentFrame=0, bool blocking=false)
For image formats that support animation, this function returns the number of milliseconds to wait un...
QImage pathAsImage(const QString &path, const QSize size, const bool keepAspectRatio, const double opacity, bool &fitsInCache, bool blocking=false, double targetDpi=96, int frameNumber=-1, bool *isMissing=nullptr)
Returns the specified path rendered as an image.
QgsLinePatternFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsLinePatternFillSymbolLayerWidget.
QgsLinePatternFillSymbolLayer * mLayer
void setSymbolLayer(QgsSymbolLayer *layer) override
A symbol fill consisting of repeated parallel lines.
void setMapUnitScale(const QgsMapUnitScale &scale) override
void setLineAngle(double a)
Sets the angle for the parallel lines used to fill the symbol.
RenderRingFilter
Options for filtering rings when the line symbol layer is being used to render a polygon's rings.
@ ExteriorRingOnly
Render the exterior ring only.
@ InteriorRingsOnly
Render the interior rings only.
@ AllRings
Render both exterior and interior rings.
virtual void setWidth(double width)
Sets the width of the line symbol layer.
void setSymbolLayer(QgsSymbolLayer *layer) override
void setContext(const QgsSymbolWidgetContext &context) override
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
QgsLinearReferencingSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsLinearReferencingSymbolLayerWidget.
void setNumericFormat(QgsNumericFormat *format)
Sets the numeric format used to format the labels for the layer.
QgsNumericFormat * numericFormat() const
Returns the numeric format used to format the labels for the layer.
QgsLineburstSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsLineburstSymbolLayerWidget.
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsLineburstSymbolLayer * mLayer
QgsSymbolLayer * symbolLayer() override
Line symbol layer type which draws a gradient pattern perpendicularly along a line.
Struct for storing maximum and minimum scales for measurements in map units.
QgsMarkerLineSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsMarkerLineSymbolLayerWidget.
void setOffset(QPointF offset)
Sets the marker's offset, which is the horizontal and vertical displacement which the rendered marker...
double size() const
Returns the symbol size.
void setSizeUnit(Qgis::RenderUnit unit)
Sets the units for the symbol's size.
A dialog to create a new auxiliary layer.
A widget which allows choice of numeric formats and the properties of them.
QgsNumericFormat * format() const
Returns a new format object representing the settings currently configured in the widget.
void changed()
Emitted whenever the format configured55 in the widget is changed.
void registerExpressionContextGenerator(QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
void setFormat(const QgsNumericFormat *format)
Sets the format to show in the widget.
void opacityChanged(double opacity)
Emitted when the opacity is changed in the widget, where opacity ranges from 0.0 (transparent) to 1....
Base class for any widget that can be shown as an inline panel.
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
bool dockMode() const
Returns the dock mode state.
void widgetChanged()
Emitted when the widget state changes.
static QgsPanelWidget * findParentPanel(QWidget *widget)
Traces through the parents of a widget to find if it is contained within a QgsPanelWidget widget.
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
QgsPointPatternFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsPointPatternFillSymbolLayerWidget.
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsPointPatternFillSymbolLayer * mLayer
A fill symbol layer which fills polygon shapes with repeating marker symbols.
void setMapUnitScale(const QgsMapUnitScale &scale) override
void setDistanceX(double d)
Sets the horizontal distance between rendered markers in the fill.
A button for controlling property overrides which may apply to a widget.
QgsProperty toProperty() const
Returns a QgsProperty object encapsulating the current state of the widget.
void updateFieldLists()
Updates list of fields.
void changed()
Emitted when property definition changes.
void init(int propertyKey, const QgsProperty &property, const QgsPropertiesDefinition &definitions, const QgsVectorLayer *layer=nullptr, bool auxiliaryStorageEnabled=false)
Initialize a newly constructed property button (useful if button was included in a UI layout).
void registerExpressionContextGenerator(QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
int propertyKey() const
Returns the property key linked to the button.
void setToProperty(const QgsProperty &property)
Sets the widget to reflect the current state of a QgsProperty.
void createAuxiliaryField()
Emitted when creating a new auxiliary field.
void setField(const QString &field)
Sets the field name the property references.
QgsRandomMarkerFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsRandomMarkerFillSymbolLayerWidget.
void setSymbolLayer(QgsSymbolLayer *layer) override
A fill symbol layer which places markers at random locations within polygons.
void setMapUnitScale(const QgsMapUnitScale &scale) override
QgsRasterFillSymbolLayer * mLayer
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsSymbolLayer * symbolLayer() override
QgsRasterFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsRasterFillSymbolLayerWidget.
A fill symbol layer which fills polygons with a repeated raster image.
void setOpacity(double opacity)
Sets the opacity for the raster image used in the fill.
void setImageFilePath(const QString &imagePath)
Sets the path to the raster image used for the fill.
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsSymbolLayer * symbolLayer() override
QgsRasterLineSymbolLayer * mLayer
QgsRasterLineSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsRasterLineSymbolLayerWidget.
Line symbol layer type which draws line sections using a raster image file.
void setPath(const QString &path)
Set the raster image path.
void setOpacity(double opacity)
Set the line opacity.
QgsRasterMarkerSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsRasterMarkerSymbolLayerWidget.
QgsRasterMarkerSymbolLayer * mLayer
void setSymbolLayer(QgsSymbolLayer *layer) override
void setContext(const QgsSymbolWidgetContext &context) override
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
QgsSymbolLayer * symbolLayer() override
Raster marker symbol layer class.
void setPath(const QString &path)
Set the marker raster image path.
A cross platform button subclass used to represent a locked / unlocked ratio state.
void lockChanged(bool locked)
Emitted whenever the lock state changes.
QgsSymbolLayer * symbolLayer() override
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsSVGFillSymbolLayer * mLayer
void updateParamGui(bool resetValues=true)
Enables or disables svg fill color, stroke color and stroke width based on whether the svg file suppo...
QgsSVGFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsSVGFillSymbolLayerWidget.
void setContext(const QgsSymbolWidgetContext &context) override
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
A fill symbol layer which fills polygons with a repeated SVG file.
void setPatternWidth(double width)
Sets the width to render the SVG content as within the fill (i.e.
Stores properties relating to a screen.
QgsShapeburstFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsShapeburstFillSymbolLayerWidget.
QgsShapeburstFillSymbolLayer * mLayer
void setSymbolLayer(QgsSymbolLayer *layer) override
A fill symbol layer which applies a gradient from the outer edges of a symbol to the inside.
QgsSimpleFillSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsSimpleFillSymbolLayerWidget.
void setStrokeColor(const QColor &color)
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsSimpleFillSymbolLayer * mLayer
QgsSymbolLayer * symbolLayer() override
Renders polygons using a single fill and stroke color.
void setBrushStyle(Qt::BrushStyle style)
void setContext(const QgsSymbolWidgetContext &context) override
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
~QgsSimpleLineSymbolLayerWidget() override
QgsSimpleLineSymbolLayer * mLayer
void setSymbolLayer(QgsSymbolLayer *layer) override
QgsSymbolLayer * symbolLayer() override
QgsSimpleLineSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsSimpleLineSymbolLayerWidget.
void resizeEvent(QResizeEvent *event) override
A simple line symbol layer, which renders lines using a line in a variety of styles (e....
void setMapUnitScale(const QgsMapUnitScale &scale) override
static QList< Qgis::MarkerShape > availableShapes()
Returns a list of all available shape types.
static bool shapeIsFilled(Qgis::MarkerShape shape)
Returns true if a symbol shape has a fill.
Qgis::MarkerShape shape() const
Returns the shape for the rendered marker symbol.
static QString encodeShape(Qgis::MarkerShape shape)
Encodes a shape to its string representation.
void setShape(Qgis::MarkerShape shape)
Sets the rendered marker shape.
QgsSymbolLayer * symbolLayer() override
void setColorStroke(const QColor &color)
QgsSimpleMarkerSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsSimpleMarkerSymbolLayerWidget.
QgsSimpleMarkerSymbolLayer * mLayer
void setSymbolLayer(QgsSymbolLayer *layer) override
Simple marker symbol layer, consisting of a rendered shape with solid fill color and a stroke.
void setColor(const QColor &color) override
Sets the "representative" color for the symbol layer.
void setPenJoinStyle(Qt::PenJoinStyle style)
Sets the marker's stroke join style (e.g., miter, bevel, etc).
void setStrokeColor(const QColor &color) override
Sets the marker's stroke color.
void containsParams(const QString &path, bool &hasFillParam, QColor &defaultFillColor, bool &hasStrokeParam, QColor &defaultStrokeColor, bool &hasStrokeWidthParam, double &defaultStrokeWidth, bool blocking=false) const
Tests if an SVG file contains parameters for fill, stroke color, stroke width.
void setContext(const QgsSymbolWidgetContext &context) override
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
QgsSymbolLayer * symbolLayer() override
void setSymbolLayer(QgsSymbolLayer *layer) override
void setGuiForSvg(const QgsSvgMarkerSymbolLayer *layer, bool skipDefaultColors=false)
Updates the GUI to reflect the SVG marker symbol layer.
void setSvgPath(const QString &name)
Sets the SVG path.
QgsSvgMarkerSymbolLayer * mLayer
QgsSvgMarkerSymbolLayerWidget(QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsSvgMarkerSymbolLayerWidget.
void setSvgParameters(const QMap< QString, QgsProperty > &parameters)
Sets the dynamic SVG parameters.
~QgsSvgMarkerSymbolLayerWidget() override
A marker symbol layer which renders an SVG graphic.
QColor fillColor() const override
Returns the fill color for the symbol layer.
QString path() const
Returns the marker SVG path.
bool preservedAspectRatio() const
Returns the preserved aspect ratio value, true if fixed aspect ratio has been lower or equal to 0.
double fixedAspectRatio() const
Returns the marker aspect ratio between width and height to be used in rendering, if the value set is...
void setMapUnitScale(const QgsMapUnitScale &scale) override
QColor strokeColor() const override
Returns the stroke color for the symbol layer.
double defaultAspectRatio() const
Returns the default marker aspect ratio between width and height, 0 if not yet calculated.
void svgParametersChanged(const QMap< QString, QgsProperty > &parameters)
Emitted when the parameters have changed.
void svgSelected(const QString &path)
Emitted when an SVG is selected in the widget.
static QIcon symbolLayerPreviewIcon(const QgsSymbolLayer *layer, Qgis::RenderUnit u, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::SymbolType parentSymbolType=Qgis::SymbolType::Hybrid, QgsMapLayer *mapLayer=nullptr, const QgsScreenProperties &screen=QgsScreenProperties())
Draws a symbol layer preview to an icon.
static QPixmap symbolPreviewPixmap(const QgsSymbol *symbol, QSize size, int padding=0, QgsRenderContext *customContext=nullptr, bool selected=false, const QgsExpressionContext *expressionContext=nullptr, const QgsLegendPatchShape *shape=nullptr, const QgsScreenProperties &screen=QgsScreenProperties())
Returns a pixmap preview for a color ramp.
static QIcon symbolPreviewIcon(const QgsSymbol *symbol, QSize size, int padding=0, QgsLegendPatchShape *shape=nullptr, const QgsScreenProperties &screen=QgsScreenProperties())
Returns an icon preview for a color ramp.
void registerDataDefinedButton(QgsPropertyOverrideButton *button, QgsSymbolLayer::Property key)
Registers a data defined override button.
QgsSymbolLayerWidget(QWidget *parent, QgsVectorLayer *vl=nullptr)
Constructor for QgsSymbolLayerWidget.
void changed()
Should be emitted whenever configuration changes happened on this symbol layer configuration.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
void symbolChanged()
Should be emitted whenever the sub symbol changed on this symbol layer configuration.
virtual void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
virtual QgsSymbolLayer * symbolLayer()=0
QgsSymbolWidgetContext context() const
Returns the context in which the symbol widget is shown, e.g., the associated map canvas and expressi...
const QgsVectorLayer * vectorLayer() const
Returns the vector layer associated with the widget.
Abstract base class for symbol layers.
Property
Data definable properties.
@ SkipMultiples
Skip multiples of.
@ GradientType
Gradient fill type.
@ SecondaryColor
Secondary color (eg for gradient fills).
@ File
Filename, eg for svg files.
@ VerticalAnchor
Vertical anchor point.
@ GradientReference2Y
Gradient reference point 2 y.
@ GradientReference1X
Gradient reference point 1 x.
@ OffsetY
Vertical offset.
@ OffsetX
Horizontal offset.
@ GradientReference1Y
Gradient reference point 1 y.
@ DashPatternOffset
Dash pattern offset,.
@ GradientSpread
Gradient spread mode.
@ OffsetAlongLine
Offset along line.
@ CustomDash
Custom dash pattern.
@ ShapeburstMaxDistance
Shapeburst fill from edge distance.
@ HorizontalAnchor
Horizontal anchor point.
@ StrokeStyle
Stroke style (eg solid, dashed).
@ Name
Name, eg shape name for simple markers.
@ DistanceY
Vertical distance between points.
@ ClipPoints
Whether markers should be clipped to polygon boundaries.
@ LineClipping
Line clipping mode.
@ ShapeburstIgnoreRings
Shapeburst ignore rings.
@ Character
Character, eg for font marker symbol layers.
@ ShapeburstUseWholeShape
Shapeburst use whole shape.
@ DisplacementX
Horizontal displacement.
@ CoordinateMode
Gradient coordinate mode.
@ FillStyle
Fill style (eg solid, dots).
@ GradientReference2X
Gradient reference point 2 x.
@ TrimStart
Trim distance from start of line.
@ CapStyle
Line cap style.
@ BlurRadius
Shapeburst blur radius.
@ Placement
Line marker placement.
@ MarkerClipping
Marker clipping mode.
@ RandomSeed
Random number seed.
@ LineAngle
Line angle, or angle of hash lines for hash line symbols.
@ JoinStyle
Line join style.
@ RandomOffsetY
Random offset Y.
@ DisplacementY
Vertical displacement.
@ DistanceX
Horizontal distance between points.
@ AverageAngleLength
Length to average symbol angles over.
@ GradientReference1IsCentroid
Gradient reference point 1 is centroid.
@ Interval
Line marker interval.
@ GradientReference2IsCentroid
Gradient reference point 2 is centroid.
@ LineDistance
Distance between lines, or length of lines for hash line symbols.
@ RandomOffsetX
Random offset X.
@ TrimEnd
Trim distance from end of line.
virtual QString layerType() const =0
Returns a string that represents this layer type.
virtual void setDataDefinedProperty(Property key, const QgsProperty &property)
Sets a data defined property for the layer.
virtual void setColor(const QColor &color)
Sets the "representative" color for the symbol layer.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the symbol layer property definitions.
Contains settings which reflect the context in which a symbol (or renderer) widget is shown,...
Base class for templated line symbols, e.g.
void setMapUnitScale(const QgsMapUnitScale &scale) final
void setInterval(double val)
Set templated line interval.
QgsSymbolLayer * symbolLayer() override
void setOffsetAlongLine(double val)
Set offset along line.
QgsTemplatedLineSymbolLayerWidget(TemplatedSymbolType symbolType, QgsVectorLayer *vl, QWidget *parent=nullptr)
Constructor for QgsTemplatedLineSymbolLayerWidget.
void setSymbolLayer(QgsSymbolLayer *layer) override
void setContext(const QgsSymbolWidgetContext &context) override
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
A widget displaying a combobox allowing the user to choose between various display units,...
void changed()
Emitted when the selected unit is changed, or the definition of the map unit scale is changed.
QList< Qgis::RenderUnit > RenderUnitList
List of render units.
Represents a vector layer which manages a vector based dataset.
QgsAuxiliaryLayer * auxiliaryLayer()
Returns the current auxiliary layer.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition qgis.h:6511
QList< QgsSymbolLayer * > QgsSymbolLayerList
Definition qgssymbol.h:30
Single variable definition for use within a QgsExpressionContextScope.