QGIS API Documentation 3.99.0-Master (a8f284845db)
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"
37#include "qgsmarkersymbol.h"
42#include "qgsproperty.h"
44#include "qgssvgcache.h"
46#include "qgssymbollayerutils.h"
47#include "qgsvectorlayer.h"
48
49#include <QAbstractButton>
50#include <QAction>
51#include <QBuffer>
52#include <QButtonGroup>
53#include <QColorDialog>
54#include <QCursor>
55#include <QDir>
56#include <QFileDialog>
57#include <QInputDialog>
58#include <QMenu>
59#include <QMessageBox>
60#include <QMovie>
61#include <QPainter>
62#include <QRegularExpression>
63#include <QStandardItemModel>
64#include <QString>
65#include <QSvgRenderer>
66
67#include "moc_qgssymbollayerwidget.cpp"
68
69using namespace Qt::StringLiterals;
70
72{
73 if ( auto *lExpressionContext = mContext.expressionContext() )
74 return *lExpressionContext;
75
76 QgsExpressionContext expContext( mContext.globalProjectAtlasMapLayerScopes( vectorLayer() ) );
77
79 if ( const QgsSymbolLayer *symbolLayer = const_cast<QgsSymbolLayerWidget *>( this )->symbolLayer() )
80 {
81 //cheat a bit - set the symbol color variable to match the symbol layer's color (when we should really be using the *symbols*
82 //color, but that's not accessible here). 99% of the time these will be the same anyway
84 }
85 expContext << symbolScope;
91 expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( u"symbol_layer_count"_s, 1, true ) );
92 expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( u"symbol_layer_index"_s, 1, true ) );
93 expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( u"symbol_marker_row"_s, 1, true ) );
94 expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( u"symbol_marker_column"_s, 1, true ) );
95 expContext.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( u"symbol_frame"_s, 1, true ) );
96
97 // additional scopes
98 const auto constAdditionalExpressionContextScopes = mContext.additionalExpressionContextScopes();
99 for ( const QgsExpressionContextScope &scope : constAdditionalExpressionContextScopes )
100 {
101 expContext.appendScope( new QgsExpressionContextScope( scope ) );
102 }
103
104 //TODO - show actual value
105 expContext.setOriginalValueVariable( QVariant() );
106
107 QStringList highlights;
113 << u"symbol_layer_count"_s << u"symbol_layer_index"_s << u"symbol_frame"_s;
114
115
116 if ( expContext.hasVariable( u"zoom_level"_s ) )
117 {
118 highlights << u"zoom_level"_s;
119 }
120 if ( expContext.hasVariable( u"vector_tile_zoom"_s ) )
121 {
122 highlights << u"vector_tile_zoom"_s;
123 }
124
125 expContext.setHighlightedVariables( highlights );
126
127 return expContext;
128}
129
131{
132 mContext = context;
133 const auto unitSelectionWidgets = findChildren<QgsUnitSelectionWidget *>();
134 for ( QgsUnitSelectionWidget *unitWidget : unitSelectionWidgets )
135 {
136 unitWidget->setMapCanvas( mContext.mapCanvas() );
137 }
138}
139
141{
142 return mContext;
143}
144
146{
147 button->init( static_cast<int>( key ), symbolLayer()->dataDefinedProperties(), QgsSymbolLayer::propertyDefinitions(), mVectorLayer, true );
149 connect( button, &QgsPropertyOverrideButton::createAuxiliaryField, this, &QgsSymbolLayerWidget::createAuxiliaryField );
150
152}
153
154void QgsSymbolLayerWidget::createAuxiliaryField()
155{
156 // try to create an auxiliary layer if not yet created
157 if ( !mVectorLayer->auxiliaryLayer() )
158 {
159 QgsNewAuxiliaryLayerDialog dlg( mVectorLayer, this );
160 dlg.exec();
161 }
162
163 // return if still not exists
164 if ( !mVectorLayer->auxiliaryLayer() )
165 return;
166
167 QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
168 QgsSymbolLayer::Property key = static_cast<QgsSymbolLayer::Property>( button->propertyKey() );
169 QgsPropertyDefinition def = QgsSymbolLayer::propertyDefinitions()[static_cast<int>( key )];
170
171 // create property in auxiliary storage if necessary
172 if ( !mVectorLayer->auxiliaryLayer()->exists( def ) )
173 {
174 QgsNewAuxiliaryFieldDialog dlg( def, mVectorLayer, true, this );
175 if ( dlg.exec() == QDialog::Accepted )
176 def = dlg.propertyDefinition();
177 }
178
179 // return if still not exist
180 if ( !mVectorLayer->auxiliaryLayer()->exists( def ) )
181 return;
182
183 // update property with join field name from auxiliary storage
184 QgsProperty property = button->toProperty();
185 property.setField( QgsAuxiliaryLayer::nameFromProperty( def, true ) );
186 property.setActive( true );
187 button->updateFieldLists();
188 button->setToProperty( property );
189 symbolLayer()->setDataDefinedProperty( key, button->toProperty() );
190
191 emit changed();
192}
193
195{
196 QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
197 const QgsSymbolLayer::Property key = static_cast<QgsSymbolLayer::Property>( button->propertyKey() );
198 symbolLayer()->setDataDefinedProperty( key, button->toProperty() );
199 emit changed();
200}
201
203 : QgsSymbolLayerWidget( parent, vl )
204{
205 mLayer = nullptr;
206
207 setupUi( this );
208 connect( mCustomCheckBox, &QCheckBox::stateChanged, this, &QgsSimpleLineSymbolLayerWidget::mCustomCheckBox_stateChanged );
209 connect( mChangePatternButton, &QPushButton::clicked, this, &QgsSimpleLineSymbolLayerWidget::mChangePatternButton_clicked );
210 connect( mPenWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::mPenWidthUnitWidget_changed );
211 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::mOffsetUnitWidget_changed );
212 connect( mDashPatternUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::mDashPatternUnitWidget_changed );
213 connect( mDrawInsideCheckBox, &QCheckBox::stateChanged, this, &QgsSimpleLineSymbolLayerWidget::mDrawInsideCheckBox_stateChanged );
214 connect( mPatternOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::patternOffsetUnitChanged );
215 connect( mCheckAlignDash, &QCheckBox::toggled, this, [this] {
216 mCheckDashCorners->setEnabled( mCheckAlignDash->isChecked() );
217 if ( !mCheckAlignDash->isChecked() )
218 mCheckDashCorners->setChecked( false );
219
220 if ( mLayer )
221 {
222 mLayer->setAlignDashPattern( mCheckAlignDash->isChecked() );
223 emit changed();
224 }
225 } );
226 connect( mCheckDashCorners, &QCheckBox::toggled, this, [this] {
227 if ( mLayer )
228 {
229 mLayer->setTweakDashPatternOnCorners( mCheckDashCorners->isChecked() );
230 emit changed();
231 }
232 } );
233
240
241 btnChangeColor->setAllowOpacity( true );
242 btnChangeColor->setColorDialogTitle( tr( "Select Line Color" ) );
243 btnChangeColor->setContext( u"symbology"_s );
244
245 mColorDDBtn->registerLinkedWidget( btnChangeColor );
246
247 mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( u"mIconAllRings.svg"_s ), tr( "All Rings" ), QgsLineSymbolLayer::AllRings );
248 mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( u"mIconExteriorRing.svg"_s ), tr( "Exterior Ring Only" ), QgsLineSymbolLayer::ExteriorRingOnly );
249 mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( u"mIconInteriorRings.svg"_s ), tr( "Interior Rings Only" ), QgsLineSymbolLayer::InteriorRingsOnly );
250 connect( mRingFilterComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
251 if ( mLayer )
252 {
253 mLayer->setRingFilter( static_cast<QgsLineSymbolLayer::RenderRingFilter>( mRingFilterComboBox->currentData().toInt() ) );
254 emit changed();
255 }
256 } );
257
258 spinOffset->setClearValue( 0.0 );
259 spinPatternOffset->setClearValue( 0.0 );
260
261 mTrimStartDistanceSpin->setClearValue( 0.0 );
262 mTrimDistanceEndSpin->setClearValue( 0.0 );
263
264 //make a temporary symbol for the size assistant preview
265 mAssistantPreviewSymbol = std::make_shared<QgsLineSymbol>();
266
267 if ( vectorLayer() )
268 mPenWidthDDBtn->setSymbol( mAssistantPreviewSymbol );
269
270 connect( spinWidth, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleLineSymbolLayerWidget::penWidthChanged );
271 connect( btnChangeColor, &QgsColorButton::colorChanged, this, &QgsSimpleLineSymbolLayerWidget::colorChanged );
272 connect( cboPenStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleLineSymbolLayerWidget::penStyleChanged );
273 connect( spinOffset, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleLineSymbolLayerWidget::offsetChanged );
274 connect( cboCapStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleLineSymbolLayerWidget::penStyleChanged );
275 connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleLineSymbolLayerWidget::penStyleChanged );
276 connect( spinPatternOffset, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleLineSymbolLayerWidget::patternOffsetChanged );
277
278 connect( mTrimStartDistanceSpin, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, [this]( double value ) {
279 if ( !mLayer )
280 return;
281
282 mLayer->setTrimDistanceStart( value );
283 emit changed();
284 } );
285 connect( mTrimDistanceStartUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
286 if ( !mLayer )
287 return;
288
289 mLayer->setTrimDistanceStartUnit( mTrimDistanceStartUnitWidget->unit() );
290 mLayer->setTrimDistanceStartMapUnitScale( mTrimDistanceStartUnitWidget->getMapUnitScale() );
291 emit changed();
292 } );
293 connect( mTrimDistanceEndSpin, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, [this]( double value ) {
294 if ( !mLayer )
295 return;
296
297 mLayer->setTrimDistanceEnd( value );
298 emit changed();
299 } );
300 connect( mTrimDistanceEndUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
301 if ( !mLayer )
302 return;
303
304 mLayer->setTrimDistanceEndUnit( mTrimDistanceEndUnitWidget->unit() );
305 mLayer->setTrimDistanceEndMapUnitScale( mTrimDistanceEndUnitWidget->getMapUnitScale() );
306 emit changed();
307 } );
308
309
311
312 connect( this, &QgsSymbolLayerWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::updateAssistantSymbol );
313}
314
316
317void QgsSimpleLineSymbolLayerWidget::updateAssistantSymbol()
318{
319 for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1; i >= 0; --i )
320 {
321 mAssistantPreviewSymbol->deleteSymbolLayer( i );
322 }
323 mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
324 const QgsProperty ddWidth = mLayer->dataDefinedProperties().property( QgsSymbolLayer::Property::StrokeWidth );
325 if ( ddWidth )
326 mAssistantPreviewSymbol->setDataDefinedWidth( ddWidth );
327}
328
329
331{
332 if ( !layer || layer->layerType() != "SimpleLine"_L1 )
333 return;
334
335 // layer type is correct, we can do the cast
336 mLayer = static_cast<QgsSimpleLineSymbolLayer *>( layer );
337
338 // set units
339 mPenWidthUnitWidget->blockSignals( true );
340 mPenWidthUnitWidget->setUnit( mLayer->widthUnit() );
341 mPenWidthUnitWidget->setMapUnitScale( mLayer->widthMapUnitScale() );
342 mPenWidthUnitWidget->blockSignals( false );
343 mOffsetUnitWidget->blockSignals( true );
344 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
345 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
346 mOffsetUnitWidget->blockSignals( false );
347 mDashPatternUnitWidget->blockSignals( true );
348 mDashPatternUnitWidget->setUnit( mLayer->customDashPatternUnit() );
349 mDashPatternUnitWidget->setMapUnitScale( mLayer->customDashPatternMapUnitScale() );
350 mDashPatternUnitWidget->blockSignals( false );
351
352 whileBlocking( mPatternOffsetUnitWidget )->setUnit( mLayer->dashPatternOffsetUnit() );
353 whileBlocking( mPatternOffsetUnitWidget )->setMapUnitScale( mLayer->dashPatternOffsetMapUnitScale() );
354 whileBlocking( mTrimDistanceStartUnitWidget )->setUnit( mLayer->trimDistanceStartUnit() );
355 whileBlocking( mTrimDistanceStartUnitWidget )->setMapUnitScale( mLayer->trimDistanceStartMapUnitScale() );
356 whileBlocking( mTrimDistanceEndUnitWidget )->setUnit( mLayer->trimDistanceEndUnit() );
357 whileBlocking( mTrimDistanceEndUnitWidget )->setMapUnitScale( mLayer->trimDistanceEndMapUnitScale() );
358
359 // set values
360 spinWidth->blockSignals( true );
361 spinWidth->setValue( mLayer->width() );
362 spinWidth->blockSignals( false );
363 btnChangeColor->blockSignals( true );
364 btnChangeColor->setColor( mLayer->color() );
365 btnChangeColor->blockSignals( false );
366 spinOffset->blockSignals( true );
367 spinOffset->setValue( mLayer->offset() );
368 spinOffset->blockSignals( false );
369 cboPenStyle->blockSignals( true );
370 cboJoinStyle->blockSignals( true );
371 cboCapStyle->blockSignals( true );
372 cboPenStyle->setPenStyle( mLayer->penStyle() );
373 cboJoinStyle->setPenJoinStyle( mLayer->penJoinStyle() );
374 cboCapStyle->setPenCapStyle( mLayer->penCapStyle() );
375 cboPenStyle->blockSignals( false );
376 cboJoinStyle->blockSignals( false );
377 cboCapStyle->blockSignals( false );
378 whileBlocking( spinPatternOffset )->setValue( mLayer->dashPatternOffset() );
379 whileBlocking( mTrimStartDistanceSpin )->setValue( mLayer->trimDistanceStart() );
380 whileBlocking( mTrimDistanceEndSpin )->setValue( mLayer->trimDistanceEnd() );
381
382 //use a custom dash pattern?
383 const bool useCustomDashPattern = mLayer->useCustomDashPattern();
384 mChangePatternButton->setEnabled( useCustomDashPattern );
385 label_3->setEnabled( !useCustomDashPattern );
386 cboPenStyle->setEnabled( !useCustomDashPattern );
387 mCustomCheckBox->blockSignals( true );
388 mCustomCheckBox->setCheckState( useCustomDashPattern ? Qt::Checked : Qt::Unchecked );
389 mCustomCheckBox->blockSignals( false );
390
391 //make sure height of custom dash button looks good under different platforms
392 const QSize size = mChangePatternButton->minimumSizeHint();
393 const int fontHeight = static_cast<int>( Qgis::UI_SCALE_FACTOR * fontMetrics().height() * 1.4 );
394 mChangePatternButton->setMinimumSize( QSize( size.width(), std::max( size.height(), fontHeight ) ) );
395
396 //draw inside polygon?
397 const bool drawInsidePolygon = mLayer->drawInsidePolygon();
398 whileBlocking( mDrawInsideCheckBox )->setCheckState( drawInsidePolygon ? Qt::Checked : Qt::Unchecked );
399
400 whileBlocking( mRingFilterComboBox )->setCurrentIndex( mRingFilterComboBox->findData( mLayer->ringFilter() ) );
401
402 whileBlocking( mCheckAlignDash )->setChecked( mLayer->alignDashPattern() );
403 mCheckDashCorners->setEnabled( mLayer->alignDashPattern() );
404 whileBlocking( mCheckDashCorners )->setChecked( mLayer->tweakDashPatternOnCorners() && mLayer->alignDashPattern() );
405
407
418
419 updateAssistantSymbol();
420}
421
426
428{
430
431 switch ( context.symbolType() )
432 {
435 //these settings only have an effect when the symbol layers is part of a fill symbol
436 mDrawInsideCheckBox->hide();
437 mRingFilterComboBox->hide();
438 mRingsLabel->hide();
439 break;
440
443 break;
444 }
445}
446
447void QgsSimpleLineSymbolLayerWidget::penWidthChanged()
448{
449 mLayer->setWidth( spinWidth->value() );
451 emit changed();
452}
453
454void QgsSimpleLineSymbolLayerWidget::colorChanged( const QColor &color )
455{
456 mLayer->setColor( color );
457 emit changed();
458}
459
460void QgsSimpleLineSymbolLayerWidget::penStyleChanged()
461{
462 mLayer->setPenStyle( cboPenStyle->penStyle() );
463 mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
464 mLayer->setPenCapStyle( cboCapStyle->penCapStyle() );
466 emit changed();
467}
468
469void QgsSimpleLineSymbolLayerWidget::offsetChanged()
470{
471 mLayer->setOffset( spinOffset->value() );
473 emit changed();
474}
475
476void QgsSimpleLineSymbolLayerWidget::patternOffsetChanged()
477{
478 mLayer->setDashPatternOffset( spinPatternOffset->value() );
480 emit changed();
481}
482
483void QgsSimpleLineSymbolLayerWidget::mCustomCheckBox_stateChanged( int state )
484{
485 const bool checked = ( state == Qt::Checked );
486 mChangePatternButton->setEnabled( checked );
487 label_3->setEnabled( !checked );
488 cboPenStyle->setEnabled( !checked );
489
490 mLayer->setUseCustomDashPattern( checked );
491 emit changed();
492}
493
494void QgsSimpleLineSymbolLayerWidget::mChangePatternButton_clicked()
495{
496 QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( this );
497 if ( panel && panel->dockMode() )
498 {
499 QgsDashSpaceWidget *widget = new QgsDashSpaceWidget( mLayer->customDashVector(), panel );
500 widget->setPanelTitle( tr( "Custom Dash Pattern" ) );
501 widget->setUnit( mDashPatternUnitWidget->unit() );
502 connect( widget, &QgsPanelWidget::widgetChanged, this, [this, widget]() {
503 mLayer->setCustomDashVector( widget->dashDotVector() );
505 } );
507 panel->openPanel( widget );
508 return;
509 }
510
511 QgsDashSpaceDialog d( mLayer->customDashVector() );
512 d.setUnit( mDashPatternUnitWidget->unit() );
513 if ( d.exec() == QDialog::Accepted )
514 {
515 mLayer->setCustomDashVector( d.dashDotVector() );
517 emit changed();
518 }
519}
520
521void QgsSimpleLineSymbolLayerWidget::mPenWidthUnitWidget_changed()
522{
523 if ( mLayer )
524 {
525 mLayer->setWidthUnit( mPenWidthUnitWidget->unit() );
526 mLayer->setWidthMapUnitScale( mPenWidthUnitWidget->getMapUnitScale() );
528 emit changed();
529 }
530}
531
532void QgsSimpleLineSymbolLayerWidget::mOffsetUnitWidget_changed()
533{
534 if ( mLayer )
535 {
536 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
537 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
538 emit changed();
539 }
540}
541
542void QgsSimpleLineSymbolLayerWidget::mDashPatternUnitWidget_changed()
543{
544 if ( mLayer )
545 {
546 mLayer->setCustomDashPatternUnit( mDashPatternUnitWidget->unit() );
547 mLayer->setCustomDashPatternMapUnitScale( mDashPatternUnitWidget->getMapUnitScale() );
549 emit changed();
550 }
551}
552
553void QgsSimpleLineSymbolLayerWidget::mDrawInsideCheckBox_stateChanged( int state )
554{
555 const bool checked = ( state == Qt::Checked );
556 mLayer->setDrawInsidePolygon( checked );
557 emit changed();
558}
559
560void QgsSimpleLineSymbolLayerWidget::patternOffsetUnitChanged()
561{
562 if ( mLayer )
563 {
564 mLayer->setDashPatternOffsetUnit( mPatternOffsetUnitWidget->unit() );
565 mLayer->setDashPatternOffsetMapUnitScale( mPatternOffsetUnitWidget->getMapUnitScale() );
567 emit changed();
568 }
569}
570
572{
573 if ( !mLayer )
574 {
575 return;
576 }
577 std::unique_ptr<QgsSimpleLineSymbolLayer> layerCopy( mLayer->clone() );
578 if ( !layerCopy )
579 {
580 return;
581 }
582 const QColor color = qApp->palette().color( QPalette::WindowText );
583 layerCopy->setColor( color );
584 // reset offset, we don't want to show that in the preview
585 layerCopy->setOffset( 0 );
586 layerCopy->setUseCustomDashPattern( true );
587
588 QSize currentIconSize;
589 //icon size is button size with a small margin
590#ifdef Q_OS_WIN
591 currentIconSize = QSize( mChangePatternButton->width() - 10, mChangePatternButton->height() - 6 );
592#else
593 currentIconSize = QSize( mChangePatternButton->width() - 10, mChangePatternButton->height() - 12 );
594#endif
595
596 if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 )
597 {
598 return;
599 }
600
601 //create an icon pixmap
602 const std::unique_ptr<QgsLineSymbol> previewSymbol = std::make_unique<QgsLineSymbol>( QgsSymbolLayerList() << layerCopy.release() );
603 const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( previewSymbol.get(), currentIconSize, 0, nullptr, QgsScreenProperties( screen() ) );
604 mChangePatternButton->setIconSize( currentIconSize );
605 mChangePatternButton->setIcon( icon );
606
607 // set tooltip
608 // create very large preview image
609 const int width = static_cast<int>( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 23 );
610 const int height = static_cast<int>( width / 1.61803398875 ); // golden ratio
611
612 const QPixmap pm = QgsSymbolLayerUtils::symbolPreviewPixmap( previewSymbol.get(), QSize( width, height ), height / 20, nullptr, false, nullptr, nullptr, QgsScreenProperties( screen() ) );
613 QByteArray data;
614 QBuffer buffer( &data );
615 pm.save( &buffer, "PNG", 100 );
616 mChangePatternButton->setToolTip( u"<img src='data:image/png;base64, %3' width=\"%4\">"_s.arg( QString( data.toBase64() ) ).arg( width ) );
617}
618
620{
621 QgsSymbolLayerWidget::resizeEvent( event );
622 // redraw custom dash pattern icon -- the button size has changed
624}
625
626
628
629
631 : QgsSymbolLayerWidget( parent, vl )
632{
633 mLayer = nullptr;
634
635 setupUi( this );
636
637 mHorizontalAnchorComboBox->addItem( tr( "Left" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Left ) );
638 mHorizontalAnchorComboBox->addItem( tr( "Horizontal Center" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Center ) );
639 mHorizontalAnchorComboBox->addItem( tr( "Right" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Right ) );
640
641 mVerticalAnchorComboBox->addItem( tr( "Top" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Top ) );
642 mVerticalAnchorComboBox->addItem( tr( "Vertical Center" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Center ) );
643 mVerticalAnchorComboBox->addItem( tr( "Bottom" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Bottom ) );
644
645 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
646 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
647 connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
648 connect( mStrokeStyleComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mStrokeStyleComboBox_currentIndexChanged );
649 connect( mStrokeWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
650 connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
651 connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
655
656 btnChangeColorFill->setAllowOpacity( true );
657 btnChangeColorFill->setColorDialogTitle( tr( "Select Fill Color" ) );
658 btnChangeColorFill->setContext( u"symbology"_s );
659 btnChangeColorFill->setShowNoColor( true );
660 btnChangeColorFill->setNoColorString( tr( "Transparent Fill" ) );
661 btnChangeColorStroke->setAllowOpacity( true );
662 btnChangeColorStroke->setColorDialogTitle( tr( "Select Stroke Color" ) );
663 btnChangeColorStroke->setContext( u"symbology"_s );
664 btnChangeColorStroke->setShowNoColor( true );
665 btnChangeColorStroke->setNoColorString( tr( "Transparent Stroke" ) );
666
667 mFillColorDDBtn->registerLinkedWidget( btnChangeColorFill );
668 mStrokeColorDDBtn->registerLinkedWidget( btnChangeColorStroke );
669
670 spinOffsetX->setClearValue( 0.0 );
671 spinOffsetY->setClearValue( 0.0 );
672 spinAngle->setClearValue( 0.0 );
673
674 //make a temporary symbol for the size assistant preview
675 mAssistantPreviewSymbol = std::make_shared<QgsMarkerSymbol>();
676
677 if ( vectorLayer() )
678 mSizeDDBtn->setSymbol( mAssistantPreviewSymbol );
679
680 int size = lstNames->iconSize().width();
681
682 size = std::max( 30, static_cast<int>( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 3 ) ) );
683
684 lstNames->setGridSize( QSize( size * 1.2, size * 1.2 ) );
685 lstNames->setIconSize( QSize( size, size ) );
686
687 const double markerSize = size * 0.8;
689 for ( const Qgis::MarkerShape shape : shapes )
690 {
691 QgsSimpleMarkerSymbolLayer *lyr = new QgsSimpleMarkerSymbolLayer( shape, markerSize );
693 lyr->setColor( QColor( 200, 200, 200 ) );
694 lyr->setStrokeColor( QColor( 0, 0, 0 ) );
695 const QIcon icon = QgsSymbolLayerUtils::symbolLayerPreviewIcon( lyr, Qgis::RenderUnit::Pixels, QSize( size, size ), QgsMapUnitScale(), Qgis::SymbolType::Hybrid, nullptr, QgsScreenProperties( screen() ) );
696 QListWidgetItem *item = new QListWidgetItem( icon, QString(), lstNames );
697 item->setData( Qt::UserRole, static_cast<int>( shape ) );
698 item->setToolTip( QgsSimpleMarkerSymbolLayerBase::encodeShape( shape ) );
699 delete lyr;
700 }
701 // show at least 3 rows
702 lstNames->setMinimumHeight( lstNames->gridSize().height() * 3.1 );
703
704 connect( lstNames, &QListWidget::currentRowChanged, this, &QgsSimpleMarkerSymbolLayerWidget::setShape );
707 connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::penJoinStyleChanged );
708 connect( cboCapStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::penCapStyleChanged );
709 connect( spinSize, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setSize );
710 connect( spinAngle, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setAngle );
711 connect( spinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setOffset );
712 connect( spinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setOffset );
713 connect( this, &QgsSymbolLayerWidget::changed, this, &QgsSimpleMarkerSymbolLayerWidget::updateAssistantSymbol );
714}
715
717
719{
720 if ( layer->layerType() != "SimpleMarker"_L1 )
721 return;
722
723 // layer type is correct, we can do the cast
724 mLayer = static_cast<QgsSimpleMarkerSymbolLayer *>( layer );
725
726 // set values
727 const Qgis::MarkerShape shape = mLayer->shape();
728 for ( int i = 0; i < lstNames->count(); ++i )
729 {
730 if ( static_cast<Qgis::MarkerShape>( lstNames->item( i )->data( Qt::UserRole ).toInt() ) == shape )
731 {
732 lstNames->setCurrentRow( i );
733 break;
734 }
735 }
736 btnChangeColorStroke->blockSignals( true );
737 btnChangeColorStroke->setColor( mLayer->strokeColor() );
738 btnChangeColorStroke->blockSignals( false );
739 btnChangeColorFill->blockSignals( true );
740 btnChangeColorFill->setColor( mLayer->fillColor() );
741 btnChangeColorFill->setEnabled( QgsSimpleMarkerSymbolLayerBase::shapeIsFilled( mLayer->shape() ) );
742 btnChangeColorFill->blockSignals( false );
743 spinSize->blockSignals( true );
744 spinSize->setValue( mLayer->size() );
745 spinSize->blockSignals( false );
746 spinAngle->blockSignals( true );
747 spinAngle->setValue( mLayer->angle() );
748 spinAngle->blockSignals( false );
749 mStrokeStyleComboBox->blockSignals( true );
750 mStrokeStyleComboBox->setPenStyle( mLayer->strokeStyle() );
751 mStrokeStyleComboBox->blockSignals( false );
752 mStrokeWidthSpinBox->blockSignals( true );
753 mStrokeWidthSpinBox->setValue( mLayer->strokeWidth() );
754 mStrokeWidthSpinBox->blockSignals( false );
755 cboJoinStyle->blockSignals( true );
756 cboJoinStyle->setPenJoinStyle( mLayer->penJoinStyle() );
757 cboJoinStyle->blockSignals( false );
758 cboCapStyle->blockSignals( true );
759 cboCapStyle->setPenCapStyle( mLayer->penCapStyle() );
760 cboCapStyle->blockSignals( false );
761
762 // without blocking signals the value gets changed because of slot setOffset()
763 spinOffsetX->blockSignals( true );
764 spinOffsetX->setValue( mLayer->offset().x() );
765 spinOffsetX->blockSignals( false );
766 spinOffsetY->blockSignals( true );
767 spinOffsetY->setValue( mLayer->offset().y() );
768 spinOffsetY->blockSignals( false );
769
770 mSizeUnitWidget->blockSignals( true );
771 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
772 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
773 mSizeUnitWidget->blockSignals( false );
774 mOffsetUnitWidget->blockSignals( true );
775 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
776 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
777 mOffsetUnitWidget->blockSignals( false );
778 mStrokeWidthUnitWidget->blockSignals( true );
779 mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
780 mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
781 mStrokeWidthUnitWidget->blockSignals( false );
782
783 //anchor points
784 mHorizontalAnchorComboBox->blockSignals( true );
785 mVerticalAnchorComboBox->blockSignals( true );
786 mHorizontalAnchorComboBox->setCurrentIndex( mHorizontalAnchorComboBox->findData( QVariant::fromValue( mLayer->horizontalAnchorPoint() ) ) );
787 mVerticalAnchorComboBox->setCurrentIndex( mVerticalAnchorComboBox->findData( QVariant::fromValue( mLayer->verticalAnchorPoint() ) ) );
788 mHorizontalAnchorComboBox->blockSignals( false );
789 mVerticalAnchorComboBox->blockSignals( false );
790
803
804 updateAssistantSymbol();
805}
806
811
812void QgsSimpleMarkerSymbolLayerWidget::setShape()
813{
814 mLayer->setShape( static_cast<Qgis::MarkerShape>( lstNames->currentItem()->data( Qt::UserRole ).toInt() ) );
815 btnChangeColorFill->setEnabled( QgsSimpleMarkerSymbolLayerBase::shapeIsFilled( mLayer->shape() ) );
816 emit changed();
817}
818
820{
821 mLayer->setStrokeColor( color );
822 emit changed();
823}
824
826{
827 mLayer->setColor( color );
828 emit changed();
829}
830
831void QgsSimpleMarkerSymbolLayerWidget::penJoinStyleChanged()
832{
833 mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
834 emit changed();
835}
836
837void QgsSimpleMarkerSymbolLayerWidget::penCapStyleChanged()
838{
839 mLayer->setPenCapStyle( cboCapStyle->penCapStyle() );
840 emit changed();
841}
842
843void QgsSimpleMarkerSymbolLayerWidget::setSize()
844{
845 mLayer->setSize( spinSize->value() );
846 emit changed();
847}
848
849void QgsSimpleMarkerSymbolLayerWidget::setAngle()
850{
851 mLayer->setAngle( spinAngle->value() );
852 emit changed();
853}
854
855void QgsSimpleMarkerSymbolLayerWidget::setOffset()
856{
857 mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
858 emit changed();
859}
860
861void QgsSimpleMarkerSymbolLayerWidget::mStrokeStyleComboBox_currentIndexChanged( int index )
862{
863 Q_UNUSED( index )
864
865 if ( mLayer )
866 {
867 mLayer->setStrokeStyle( mStrokeStyleComboBox->penStyle() );
868 emit changed();
869 }
870}
871
872void QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
873{
874 if ( mLayer )
875 {
876 mLayer->setStrokeWidth( d );
877 emit changed();
878 }
879}
880
881void QgsSimpleMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
882{
883 if ( mLayer )
884 {
885 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
886 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
887 emit changed();
888 }
889}
890
891void QgsSimpleMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
892{
893 if ( mLayer )
894 {
895 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
896 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
897 emit changed();
898 }
899}
900
901void QgsSimpleMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
902{
903 if ( mLayer )
904 {
905 mLayer->setStrokeWidthUnit( mStrokeWidthUnitWidget->unit() );
906 mLayer->setStrokeWidthMapUnitScale( mStrokeWidthUnitWidget->getMapUnitScale() );
907 emit changed();
908 }
909}
910
911void QgsSimpleMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int )
912{
913 if ( mLayer )
914 {
915 mLayer->setHorizontalAnchorPoint( mHorizontalAnchorComboBox->currentData().value< Qgis::HorizontalAnchorPoint >() );
916 emit changed();
917 }
918}
919
920void QgsSimpleMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int )
921{
922 if ( mLayer )
923 {
924 mLayer->setVerticalAnchorPoint( mVerticalAnchorComboBox->currentData().value< Qgis::VerticalAnchorPoint >() );
925 emit changed();
926 }
927}
928
929void QgsSimpleMarkerSymbolLayerWidget::updateAssistantSymbol()
930{
931 for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1; i >= 0; --i )
932 {
933 mAssistantPreviewSymbol->deleteSymbolLayer( i );
934 }
935 mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
936 const QgsProperty ddSize = mLayer->dataDefinedProperties().property( QgsSymbolLayer::Property::Size );
937 if ( ddSize )
938 mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
939}
940
941
943
945 : QgsSymbolLayerWidget( parent, vl )
946{
947 mLayer = nullptr;
948
949 setupUi( this );
950 connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleFillSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
951 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSimpleFillSymbolLayerWidget::mOffsetUnitWidget_changed );
954
955 btnChangeColor->setAllowOpacity( true );
956 btnChangeColor->setColorDialogTitle( tr( "Select Fill Color" ) );
957 btnChangeColor->setContext( u"symbology"_s );
958 btnChangeColor->setShowNoColor( true );
959 btnChangeColor->setNoColorString( tr( "Transparent Fill" ) );
960 btnChangeStrokeColor->setAllowOpacity( true );
961 btnChangeStrokeColor->setColorDialogTitle( tr( "Select Stroke Color" ) );
962 btnChangeStrokeColor->setContext( u"symbology"_s );
963 btnChangeStrokeColor->setShowNoColor( true );
964 btnChangeStrokeColor->setNoColorString( tr( "Transparent Stroke" ) );
965
966 spinOffsetX->setClearValue( 0.0 );
967 spinOffsetY->setClearValue( 0.0 );
968
970 connect( cboFillStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleFillSymbolLayerWidget::setBrushStyle );
972 connect( spinStrokeWidth, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleFillSymbolLayerWidget::strokeWidthChanged );
973 connect( cboStrokeStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleFillSymbolLayerWidget::strokeStyleChanged );
974 connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSimpleFillSymbolLayerWidget::strokeStyleChanged );
975 connect( spinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleFillSymbolLayerWidget::offsetChanged );
976 connect( spinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleFillSymbolLayerWidget::offsetChanged );
977
978 mFillColorDDBtn->registerLinkedWidget( btnChangeColor );
979 mStrokeColorDDBtn->registerLinkedWidget( btnChangeStrokeColor );
980}
981
983{
984 if ( layer->layerType() != "SimpleFill"_L1 )
985 return;
986
987 // layer type is correct, we can do the cast
988 mLayer = static_cast<QgsSimpleFillSymbolLayer *>( layer );
989
990 // set values
991 btnChangeColor->blockSignals( true );
992 btnChangeColor->setColor( mLayer->color() );
993 btnChangeColor->blockSignals( false );
994 cboFillStyle->blockSignals( true );
995 cboFillStyle->setBrushStyle( mLayer->brushStyle() );
996 cboFillStyle->blockSignals( false );
997 btnChangeStrokeColor->blockSignals( true );
998 btnChangeStrokeColor->setColor( mLayer->strokeColor() );
999 btnChangeStrokeColor->blockSignals( false );
1000 cboStrokeStyle->blockSignals( true );
1001 cboStrokeStyle->setPenStyle( mLayer->strokeStyle() );
1002 cboStrokeStyle->blockSignals( false );
1003 spinStrokeWidth->blockSignals( true );
1004 spinStrokeWidth->setValue( mLayer->strokeWidth() );
1005 spinStrokeWidth->blockSignals( false );
1006 cboJoinStyle->blockSignals( true );
1007 cboJoinStyle->setPenJoinStyle( mLayer->penJoinStyle() );
1008 cboJoinStyle->blockSignals( false );
1009 spinOffsetX->blockSignals( true );
1010 spinOffsetX->setValue( mLayer->offset().x() );
1011 spinOffsetX->blockSignals( false );
1012 spinOffsetY->blockSignals( true );
1013 spinOffsetY->setValue( mLayer->offset().y() );
1014 spinOffsetY->blockSignals( false );
1015
1016 mStrokeWidthUnitWidget->blockSignals( true );
1017 mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
1018 mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
1019 mStrokeWidthUnitWidget->blockSignals( false );
1020 mOffsetUnitWidget->blockSignals( true );
1021 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1022 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1023 mOffsetUnitWidget->blockSignals( false );
1024
1032}
1033
1038
1040{
1041 mLayer->setColor( color );
1042 emit changed();
1043}
1044
1046{
1047 mLayer->setStrokeColor( color );
1048 emit changed();
1049}
1050
1051void QgsSimpleFillSymbolLayerWidget::setBrushStyle()
1052{
1053 mLayer->setBrushStyle( cboFillStyle->brushStyle() );
1054 emit changed();
1055}
1056
1057void QgsSimpleFillSymbolLayerWidget::strokeWidthChanged()
1058{
1059 mLayer->setStrokeWidth( spinStrokeWidth->value() );
1060 emit changed();
1061}
1062
1063void QgsSimpleFillSymbolLayerWidget::strokeStyleChanged()
1064{
1065 mLayer->setStrokeStyle( cboStrokeStyle->penStyle() );
1066 mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
1067 emit changed();
1068}
1069
1070void QgsSimpleFillSymbolLayerWidget::offsetChanged()
1071{
1072 mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1073 emit changed();
1074}
1075
1076void QgsSimpleFillSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
1077{
1078 if ( mLayer )
1079 {
1080 mLayer->setStrokeWidthUnit( mStrokeWidthUnitWidget->unit() );
1081 mLayer->setStrokeWidthMapUnitScale( mStrokeWidthUnitWidget->getMapUnitScale() );
1082 emit changed();
1083 }
1084}
1085
1086void QgsSimpleFillSymbolLayerWidget::mOffsetUnitWidget_changed()
1087{
1088 if ( mLayer )
1089 {
1090 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1091 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1092 emit changed();
1093 }
1094}
1095
1097
1099 : QgsSymbolLayerWidget( parent, vl )
1100{
1101 mLayer = nullptr;
1102
1103 setupUi( this );
1104
1105 mHorizontalAnchorComboBox->addItem( tr( "Left" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Left ) );
1106 mHorizontalAnchorComboBox->addItem( tr( "Horizontal Center" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Center ) );
1107 mHorizontalAnchorComboBox->addItem( tr( "Right" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Right ) );
1108
1109 mVerticalAnchorComboBox->addItem( tr( "Top" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Top ) );
1110 mVerticalAnchorComboBox->addItem( tr( "Vertical Center" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Center ) );
1111 mVerticalAnchorComboBox->addItem( tr( "Bottom" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Bottom ) );
1112
1113 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFilledMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
1114 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFilledMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
1115 connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFilledMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
1116 connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFilledMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
1119
1120 spinOffsetX->setClearValue( 0.0 );
1121 spinOffsetY->setClearValue( 0.0 );
1122 spinAngle->setClearValue( 0.0 );
1123
1124 //make a temporary symbol for the size assistant preview
1125 mAssistantPreviewSymbol = std::make_shared<QgsMarkerSymbol>();
1126
1127 if ( vectorLayer() )
1128 mSizeDDBtn->setSymbol( mAssistantPreviewSymbol );
1129
1130 int size = lstNames->iconSize().width();
1131 size = std::max( 30, static_cast<int>( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 3 ) ) );
1132 lstNames->setGridSize( QSize( size * 1.2, size * 1.2 ) );
1133 lstNames->setIconSize( QSize( size, size ) );
1134
1135 const double markerSize = size * 0.8;
1137 for ( const Qgis::MarkerShape shape : shapes )
1138 {
1139 QgsSimpleMarkerSymbolLayer *lyr = new QgsSimpleMarkerSymbolLayer( shape, markerSize );
1141 lyr->setColor( QColor( 200, 200, 200 ) );
1142 lyr->setStrokeColor( QColor( 0, 0, 0 ) );
1143 const QIcon icon = QgsSymbolLayerUtils::symbolLayerPreviewIcon( lyr, Qgis::RenderUnit::Pixels, QSize( size, size ), QgsMapUnitScale(), Qgis::SymbolType::Hybrid, nullptr, QgsScreenProperties( screen() ) );
1144 QListWidgetItem *item = new QListWidgetItem( icon, QString(), lstNames );
1145 item->setData( Qt::UserRole, static_cast<int>( shape ) );
1146 item->setToolTip( QgsSimpleMarkerSymbolLayerBase::encodeShape( shape ) );
1147 delete lyr;
1148 }
1149 // show at least 3 rows
1150 lstNames->setMinimumHeight( lstNames->gridSize().height() * 3.1 );
1151
1152 connect( lstNames, &QListWidget::currentRowChanged, this, &QgsFilledMarkerSymbolLayerWidget::setShape );
1153 connect( spinSize, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setSize );
1154 connect( spinAngle, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setAngle );
1155 connect( spinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setOffset );
1156 connect( spinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsFilledMarkerSymbolLayerWidget::setOffset );
1157 connect( this, &QgsSymbolLayerWidget::changed, this, &QgsFilledMarkerSymbolLayerWidget::updateAssistantSymbol );
1158}
1159
1161
1163{
1164 if ( layer->layerType() != "FilledMarker"_L1 )
1165 return;
1166
1167 // layer type is correct, we can do the cast
1168 mLayer = static_cast<QgsFilledMarkerSymbolLayer *>( layer );
1169
1170 // set values
1171 const Qgis::MarkerShape shape = mLayer->shape();
1172 for ( int i = 0; i < lstNames->count(); ++i )
1173 {
1174 if ( static_cast<Qgis::MarkerShape>( lstNames->item( i )->data( Qt::UserRole ).toInt() ) == shape )
1175 {
1176 lstNames->setCurrentRow( i );
1177 break;
1178 }
1179 }
1180 whileBlocking( spinSize )->setValue( mLayer->size() );
1181 whileBlocking( spinAngle )->setValue( mLayer->angle() );
1182 whileBlocking( spinOffsetX )->setValue( mLayer->offset().x() );
1183 whileBlocking( spinOffsetY )->setValue( mLayer->offset().y() );
1184
1185 mSizeUnitWidget->blockSignals( true );
1186 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
1187 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
1188 mSizeUnitWidget->blockSignals( false );
1189 mOffsetUnitWidget->blockSignals( true );
1190 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1191 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1192 mOffsetUnitWidget->blockSignals( false );
1193
1194 //anchor points
1195 whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mHorizontalAnchorComboBox->findData( QVariant::fromValue( mLayer->horizontalAnchorPoint() ) ) );
1196 whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mVerticalAnchorComboBox->findData( QVariant::fromValue( mLayer->verticalAnchorPoint() ) ) );
1197
1204
1205 updateAssistantSymbol();
1206}
1207
1212
1213void QgsFilledMarkerSymbolLayerWidget::setShape()
1214{
1215 mLayer->setShape( static_cast<Qgis::MarkerShape>( lstNames->currentItem()->data( Qt::UserRole ).toInt() ) );
1216 emit changed();
1217}
1218
1219void QgsFilledMarkerSymbolLayerWidget::setSize()
1220{
1221 mLayer->setSize( spinSize->value() );
1222 emit changed();
1223}
1224
1225void QgsFilledMarkerSymbolLayerWidget::setAngle()
1226{
1227 mLayer->setAngle( spinAngle->value() );
1228 emit changed();
1229}
1230
1231void QgsFilledMarkerSymbolLayerWidget::setOffset()
1232{
1233 mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1234 emit changed();
1235}
1236
1237void QgsFilledMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
1238{
1239 if ( mLayer )
1240 {
1241 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
1242 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
1243 emit changed();
1244 }
1245}
1246
1247void QgsFilledMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
1248{
1249 if ( mLayer )
1250 {
1251 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1252 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1253 emit changed();
1254 }
1255}
1256
1257void QgsFilledMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int )
1258{
1259 if ( mLayer )
1260 {
1261 mLayer->setHorizontalAnchorPoint( mHorizontalAnchorComboBox->currentData().value<Qgis::HorizontalAnchorPoint>() );
1262 emit changed();
1263 }
1264}
1265
1266void QgsFilledMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int )
1267{
1268 if ( mLayer )
1269 {
1270 mLayer->setVerticalAnchorPoint( mVerticalAnchorComboBox->currentData().value< Qgis::VerticalAnchorPoint >() );
1271 emit changed();
1272 }
1273}
1274
1275void QgsFilledMarkerSymbolLayerWidget::updateAssistantSymbol()
1276{
1277 for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1; i >= 0; --i )
1278 {
1279 mAssistantPreviewSymbol->deleteSymbolLayer( i );
1280 }
1281 mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
1282 const QgsProperty ddSize = mLayer->dataDefinedProperties().property( QgsSymbolLayer::Property::Size );
1283 if ( ddSize )
1284 mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
1285}
1286
1287
1289
1291 : QgsSymbolLayerWidget( parent, vl )
1292{
1293 mLayer = nullptr;
1294
1295 setupUi( this );
1296 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsGradientFillSymbolLayerWidget::mOffsetUnitWidget_changed );
1297 connect( mSpinAngle, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::mSpinAngle_valueChanged );
1299
1300 btnColorRamp->setShowGradientOnly( true );
1301
1302 btnChangeColor->setAllowOpacity( true );
1303 btnChangeColor->setColorDialogTitle( tr( "Select Gradient Color" ) );
1304 btnChangeColor->setContext( u"symbology"_s );
1305 btnChangeColor->setShowNoColor( true );
1306 btnChangeColor->setNoColorString( tr( "Transparent" ) );
1307 btnChangeColor2->setAllowOpacity( true );
1308 btnChangeColor2->setColorDialogTitle( tr( "Select Gradient Color" ) );
1309 btnChangeColor2->setContext( u"symbology"_s );
1310 btnChangeColor2->setShowNoColor( true );
1311 btnChangeColor2->setNoColorString( tr( "Transparent" ) );
1312
1313 mStartColorDDBtn->registerLinkedWidget( btnChangeColor );
1314 mEndColorDDBtn->registerLinkedWidget( btnChangeColor2 );
1315
1316 spinOffsetX->setClearValue( 0.0 );
1317 spinOffsetY->setClearValue( 0.0 );
1318 mSpinAngle->setClearValue( 0.0 );
1319
1323 connect( cboGradientType, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGradientFillSymbolLayerWidget::setGradientType );
1324 connect( cboCoordinateMode, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGradientFillSymbolLayerWidget::setCoordinateMode );
1325 connect( cboGradientSpread, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGradientFillSymbolLayerWidget::setGradientSpread );
1326 connect( radioTwoColor, &QAbstractButton::toggled, this, &QgsGradientFillSymbolLayerWidget::colorModeChanged );
1327 connect( spinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::offsetChanged );
1328 connect( spinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::offsetChanged );
1329 connect( spinRefPoint1X, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1330 connect( spinRefPoint1Y, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1331 connect( checkRefPoint1Centroid, &QAbstractButton::toggled, this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1332 connect( spinRefPoint2X, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1333 connect( spinRefPoint2Y, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1334 connect( checkRefPoint2Centroid, &QAbstractButton::toggled, this, &QgsGradientFillSymbolLayerWidget::referencePointChanged );
1335}
1336
1338{
1339 if ( layer->layerType() != "GradientFill"_L1 )
1340 return;
1341
1342 // layer type is correct, we can do the cast
1343 mLayer = static_cast<QgsGradientFillSymbolLayer *>( layer );
1344
1345 // set values
1346 btnChangeColor->blockSignals( true );
1347 btnChangeColor->setColor( mLayer->color() );
1348 btnChangeColor->blockSignals( false );
1349 btnChangeColor2->blockSignals( true );
1350 btnChangeColor2->setColor( mLayer->color2() );
1351 btnChangeColor2->blockSignals( false );
1352
1353 if ( mLayer->gradientColorType() == Qgis::GradientColorSource::SimpleTwoColor )
1354 {
1355 radioTwoColor->setChecked( true );
1356 btnColorRamp->setEnabled( false );
1357 }
1358 else
1359 {
1360 radioColorRamp->setChecked( true );
1361 btnChangeColor->setEnabled( false );
1362 btnChangeColor2->setEnabled( false );
1363 }
1364
1365 // set source color ramp
1366 if ( mLayer->colorRamp() )
1367 {
1368 btnColorRamp->blockSignals( true );
1369 btnColorRamp->setColorRamp( mLayer->colorRamp() );
1370 btnColorRamp->blockSignals( false );
1371 }
1372
1373 cboGradientType->blockSignals( true );
1374 switch ( mLayer->gradientType() )
1375 {
1377 cboGradientType->setCurrentIndex( 0 );
1378 break;
1380 cboGradientType->setCurrentIndex( 1 );
1381 break;
1383 cboGradientType->setCurrentIndex( 2 );
1384 break;
1385 }
1386 cboGradientType->blockSignals( false );
1387
1388 cboCoordinateMode->blockSignals( true );
1389 switch ( mLayer->coordinateMode() )
1390 {
1392 cboCoordinateMode->setCurrentIndex( 1 );
1393 checkRefPoint1Centroid->setEnabled( false );
1394 checkRefPoint2Centroid->setEnabled( false );
1395 break;
1397 default:
1398 cboCoordinateMode->setCurrentIndex( 0 );
1399 break;
1400 }
1401 cboCoordinateMode->blockSignals( false );
1402
1403 cboGradientSpread->blockSignals( true );
1404 switch ( mLayer->gradientSpread() )
1405 {
1407 cboGradientSpread->setCurrentIndex( 0 );
1408 break;
1410 cboGradientSpread->setCurrentIndex( 1 );
1411 break;
1413 cboGradientSpread->setCurrentIndex( 2 );
1414 break;
1415 }
1416 cboGradientSpread->blockSignals( false );
1417
1418 spinRefPoint1X->blockSignals( true );
1419 spinRefPoint1X->setValue( mLayer->referencePoint1().x() );
1420 spinRefPoint1X->blockSignals( false );
1421 spinRefPoint1Y->blockSignals( true );
1422 spinRefPoint1Y->setValue( mLayer->referencePoint1().y() );
1423 spinRefPoint1Y->blockSignals( false );
1424 checkRefPoint1Centroid->blockSignals( true );
1425 checkRefPoint1Centroid->setChecked( mLayer->referencePoint1IsCentroid() );
1426 if ( mLayer->referencePoint1IsCentroid() )
1427 {
1428 spinRefPoint1X->setEnabled( false );
1429 spinRefPoint1Y->setEnabled( false );
1430 }
1431 checkRefPoint1Centroid->blockSignals( false );
1432 spinRefPoint2X->blockSignals( true );
1433 spinRefPoint2X->setValue( mLayer->referencePoint2().x() );
1434 spinRefPoint2X->blockSignals( false );
1435 spinRefPoint2Y->blockSignals( true );
1436 spinRefPoint2Y->setValue( mLayer->referencePoint2().y() );
1437 spinRefPoint2Y->blockSignals( false );
1438 checkRefPoint2Centroid->blockSignals( true );
1439 checkRefPoint2Centroid->setChecked( mLayer->referencePoint2IsCentroid() );
1440 if ( mLayer->referencePoint2IsCentroid() )
1441 {
1442 spinRefPoint2X->setEnabled( false );
1443 spinRefPoint2Y->setEnabled( false );
1444 }
1445 checkRefPoint2Centroid->blockSignals( false );
1446
1447 spinOffsetX->blockSignals( true );
1448 spinOffsetX->setValue( mLayer->offset().x() );
1449 spinOffsetX->blockSignals( false );
1450 spinOffsetY->blockSignals( true );
1451 spinOffsetY->setValue( mLayer->offset().y() );
1452 spinOffsetY->blockSignals( false );
1453 mSpinAngle->blockSignals( true );
1454 mSpinAngle->setValue( mLayer->angle() );
1455 mSpinAngle->blockSignals( false );
1456
1457 mOffsetUnitWidget->blockSignals( true );
1458 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1459 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1460 mOffsetUnitWidget->blockSignals( false );
1461
1475}
1476
1481
1483{
1484 mLayer->setColor( color );
1485 emit changed();
1486}
1487
1489{
1490 mLayer->setColor2( color );
1491 emit changed();
1492}
1493
1494void QgsGradientFillSymbolLayerWidget::colorModeChanged()
1495{
1496 if ( radioTwoColor->isChecked() )
1497 {
1499 }
1500 else
1501 {
1502 mLayer->setGradientColorType( Qgis::GradientColorSource::ColorRamp );
1503 }
1504 emit changed();
1505}
1506
1508{
1509 if ( btnColorRamp->isNull() )
1510 return;
1511
1512 mLayer->setColorRamp( btnColorRamp->colorRamp()->clone() );
1513 emit changed();
1514}
1515
1517{
1518 switch ( index )
1519 {
1520 case 0:
1521 mLayer->setGradientType( Qgis::GradientType::Linear );
1522 //set sensible default reference points
1523 spinRefPoint1X->setValue( 0.5 );
1524 spinRefPoint1Y->setValue( 0 );
1525 spinRefPoint2X->setValue( 0.5 );
1526 spinRefPoint2Y->setValue( 1 );
1527 break;
1528 case 1:
1529 mLayer->setGradientType( Qgis::GradientType::Radial );
1530 //set sensible default reference points
1531 spinRefPoint1X->setValue( 0 );
1532 spinRefPoint1Y->setValue( 0 );
1533 spinRefPoint2X->setValue( 1 );
1534 spinRefPoint2Y->setValue( 1 );
1535 break;
1536 case 2:
1537 mLayer->setGradientType( Qgis::GradientType::Conical );
1538 spinRefPoint1X->setValue( 0.5 );
1539 spinRefPoint1Y->setValue( 0.5 );
1540 spinRefPoint2X->setValue( 1 );
1541 spinRefPoint2Y->setValue( 1 );
1542 break;
1543 }
1544 emit changed();
1545}
1546
1548{
1549 switch ( index )
1550 {
1551 case 0:
1552 //feature coordinate mode
1554 //allow choice of centroid reference positions
1555 checkRefPoint1Centroid->setEnabled( true );
1556 checkRefPoint2Centroid->setEnabled( true );
1557 break;
1558 case 1:
1559 //viewport coordinate mode
1561 //disable choice of centroid reference positions
1562 checkRefPoint1Centroid->setChecked( Qt::Unchecked );
1563 checkRefPoint1Centroid->setEnabled( false );
1564 checkRefPoint2Centroid->setChecked( Qt::Unchecked );
1565 checkRefPoint2Centroid->setEnabled( false );
1566 break;
1567 }
1568
1569 emit changed();
1570}
1571
1573{
1574 switch ( index )
1575 {
1576 case 0:
1577 mLayer->setGradientSpread( Qgis::GradientSpread::Pad );
1578 break;
1579 case 1:
1580 mLayer->setGradientSpread( Qgis::GradientSpread::Repeat );
1581 break;
1582 case 2:
1583 mLayer->setGradientSpread( Qgis::GradientSpread::Reflect );
1584 break;
1585 }
1586
1587 emit changed();
1588}
1589
1590void QgsGradientFillSymbolLayerWidget::offsetChanged()
1591{
1592 mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1593 emit changed();
1594}
1595
1596void QgsGradientFillSymbolLayerWidget::referencePointChanged()
1597{
1598 mLayer->setReferencePoint1( QPointF( spinRefPoint1X->value(), spinRefPoint1Y->value() ) );
1599 mLayer->setReferencePoint1IsCentroid( checkRefPoint1Centroid->isChecked() );
1600 mLayer->setReferencePoint2( QPointF( spinRefPoint2X->value(), spinRefPoint2Y->value() ) );
1601 mLayer->setReferencePoint2IsCentroid( checkRefPoint2Centroid->isChecked() );
1602 emit changed();
1603}
1604
1605void QgsGradientFillSymbolLayerWidget::mSpinAngle_valueChanged( double value )
1606{
1607 mLayer->setAngle( value );
1608 emit changed();
1609}
1610
1611void QgsGradientFillSymbolLayerWidget::mOffsetUnitWidget_changed()
1612{
1613 if ( mLayer )
1614 {
1615 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1616 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1617 emit changed();
1618 }
1619}
1620
1622
1624 : QgsSymbolLayerWidget( parent, vl )
1625{
1626 mLayer = nullptr;
1627
1628 setupUi( this );
1629 connect( mSpinBlurRadius, qOverload<int>( &QSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::mSpinBlurRadius_valueChanged );
1630 connect( mSpinMaxDistance, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::mSpinMaxDistance_valueChanged );
1631 connect( mDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsShapeburstFillSymbolLayerWidget::mDistanceUnitWidget_changed );
1632 connect( mRadioUseWholeShape, &QRadioButton::toggled, this, &QgsShapeburstFillSymbolLayerWidget::mRadioUseWholeShape_toggled );
1633 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsShapeburstFillSymbolLayerWidget::mOffsetUnitWidget_changed );
1634 connect( mIgnoreRingsCheckBox, &QCheckBox::stateChanged, this, &QgsShapeburstFillSymbolLayerWidget::mIgnoreRingsCheckBox_stateChanged );
1637
1638 QButtonGroup *group1 = new QButtonGroup( this );
1639 group1->addButton( radioColorRamp );
1640 group1->addButton( radioTwoColor );
1641 QButtonGroup *group2 = new QButtonGroup( this );
1642 group2->addButton( mRadioUseMaxDistance );
1643 group2->addButton( mRadioUseWholeShape );
1644 btnChangeColor->setAllowOpacity( true );
1645 btnChangeColor->setColorDialogTitle( tr( "Select Gradient Color" ) );
1646 btnChangeColor->setContext( u"symbology"_s );
1647 btnChangeColor->setShowNoColor( true );
1648 btnChangeColor->setNoColorString( tr( "Transparent" ) );
1649 btnChangeColor2->setAllowOpacity( true );
1650 btnChangeColor2->setColorDialogTitle( tr( "Select Gradient Color" ) );
1651 btnChangeColor2->setContext( u"symbology"_s );
1652 btnChangeColor2->setShowNoColor( true );
1653 btnChangeColor2->setNoColorString( tr( "Transparent" ) );
1654
1655 mStartColorDDBtn->registerLinkedWidget( btnChangeColor );
1656 mEndColorDDBtn->registerLinkedWidget( btnChangeColor2 );
1657
1658 spinOffsetX->setClearValue( 0.0 );
1659 spinOffsetY->setClearValue( 0.0 );
1660 mSpinMaxDistance->setClearValue( 5.0 );
1661
1662 btnColorRamp->setShowGradientOnly( true );
1663
1664 connect( btnColorRamp, &QgsColorRampButton::colorRampChanged, this, &QgsShapeburstFillSymbolLayerWidget::applyColorRamp );
1665
1668 connect( radioTwoColor, &QAbstractButton::toggled, this, &QgsShapeburstFillSymbolLayerWidget::colorModeChanged );
1669 connect( spinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::offsetChanged );
1670 connect( spinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::offsetChanged );
1671
1672 connect( mBlurSlider, &QAbstractSlider::valueChanged, mSpinBlurRadius, &QSpinBox::setValue );
1673 connect( mSpinBlurRadius, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ), mBlurSlider, &QAbstractSlider::setValue );
1674}
1675
1677{
1678 if ( layer->layerType() != "ShapeburstFill"_L1 )
1679 return;
1680
1681 // layer type is correct, we can do the cast
1682 mLayer = static_cast<QgsShapeburstFillSymbolLayer *>( layer );
1683
1684 // set values
1685 btnChangeColor->blockSignals( true );
1686 btnChangeColor->setColor( mLayer->color() );
1687 btnChangeColor->blockSignals( false );
1688 btnChangeColor2->blockSignals( true );
1689 btnChangeColor2->setColor( mLayer->color2() );
1690 btnChangeColor2->blockSignals( false );
1691
1693 {
1694 radioTwoColor->setChecked( true );
1695 btnColorRamp->setEnabled( false );
1696 }
1697 else
1698 {
1699 radioColorRamp->setChecked( true );
1700 btnChangeColor->setEnabled( false );
1701 btnChangeColor2->setEnabled( false );
1702 }
1703
1704 mSpinBlurRadius->blockSignals( true );
1705 mBlurSlider->blockSignals( true );
1706 mSpinBlurRadius->setValue( mLayer->blurRadius() );
1707 mBlurSlider->setValue( mLayer->blurRadius() );
1708 mSpinBlurRadius->blockSignals( false );
1709 mBlurSlider->blockSignals( false );
1710
1711 mSpinMaxDistance->blockSignals( true );
1712 mSpinMaxDistance->setValue( mLayer->maxDistance() );
1713 mSpinMaxDistance->blockSignals( false );
1714
1715 mRadioUseWholeShape->blockSignals( true );
1716 mRadioUseMaxDistance->blockSignals( true );
1717 if ( mLayer->useWholeShape() )
1718 {
1719 mRadioUseWholeShape->setChecked( true );
1720 mSpinMaxDistance->setEnabled( false );
1721 mDistanceUnitWidget->setEnabled( false );
1722 }
1723 else
1724 {
1725 mRadioUseMaxDistance->setChecked( true );
1726 mSpinMaxDistance->setEnabled( true );
1727 mDistanceUnitWidget->setEnabled( true );
1728 }
1729 mRadioUseWholeShape->blockSignals( false );
1730 mRadioUseMaxDistance->blockSignals( false );
1731
1732 mDistanceUnitWidget->blockSignals( true );
1733 mDistanceUnitWidget->setUnit( mLayer->distanceUnit() );
1734 mDistanceUnitWidget->setMapUnitScale( mLayer->distanceMapUnitScale() );
1735 mDistanceUnitWidget->blockSignals( false );
1736
1737 mIgnoreRingsCheckBox->blockSignals( true );
1738 mIgnoreRingsCheckBox->setCheckState( mLayer->ignoreRings() ? Qt::Checked : Qt::Unchecked );
1739 mIgnoreRingsCheckBox->blockSignals( false );
1740
1741 // set source color ramp
1742 if ( mLayer->colorRamp() )
1743 {
1744 btnColorRamp->blockSignals( true );
1745 btnColorRamp->setColorRamp( mLayer->colorRamp() );
1746 btnColorRamp->blockSignals( false );
1747 }
1748
1749 spinOffsetX->blockSignals( true );
1750 spinOffsetX->setValue( mLayer->offset().x() );
1751 spinOffsetX->blockSignals( false );
1752 spinOffsetY->blockSignals( true );
1753 spinOffsetY->setValue( mLayer->offset().y() );
1754 spinOffsetY->blockSignals( false );
1755 mOffsetUnitWidget->blockSignals( true );
1756 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
1757 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
1758 mOffsetUnitWidget->blockSignals( false );
1759
1767}
1768
1773
1775{
1776 if ( mLayer )
1777 {
1778 mLayer->setColor( color );
1779 emit changed();
1780 }
1781}
1782
1784{
1785 if ( mLayer )
1786 {
1787 mLayer->setColor2( color );
1788 emit changed();
1789 }
1790}
1791
1792void QgsShapeburstFillSymbolLayerWidget::colorModeChanged()
1793{
1794 if ( !mLayer )
1795 {
1796 return;
1797 }
1798
1799 if ( radioTwoColor->isChecked() )
1800 {
1802 }
1803 else
1804 {
1806 }
1807 emit changed();
1808}
1809
1810void QgsShapeburstFillSymbolLayerWidget::mSpinBlurRadius_valueChanged( int value )
1811{
1812 if ( mLayer )
1813 {
1814 mLayer->setBlurRadius( value );
1815 emit changed();
1816 }
1817}
1818
1819void QgsShapeburstFillSymbolLayerWidget::mSpinMaxDistance_valueChanged( double value )
1820{
1821 if ( mLayer )
1822 {
1823 mLayer->setMaxDistance( value );
1824 emit changed();
1825 }
1826}
1827
1828void QgsShapeburstFillSymbolLayerWidget::mDistanceUnitWidget_changed()
1829{
1830 if ( mLayer )
1831 {
1832 mLayer->setDistanceUnit( mDistanceUnitWidget->unit() );
1833 mLayer->setDistanceMapUnitScale( mDistanceUnitWidget->getMapUnitScale() );
1834 emit changed();
1835 }
1836}
1837
1838void QgsShapeburstFillSymbolLayerWidget::mRadioUseWholeShape_toggled( bool value )
1839{
1840 if ( mLayer )
1841 {
1842 mLayer->setUseWholeShape( value );
1843 mDistanceUnitWidget->setEnabled( !value );
1844 emit changed();
1845 }
1846}
1847
1848void QgsShapeburstFillSymbolLayerWidget::applyColorRamp()
1849{
1850 QgsColorRamp *ramp = btnColorRamp->colorRamp();
1851 if ( !ramp )
1852 return;
1853
1854 mLayer->setColorRamp( ramp );
1855 emit changed();
1856}
1857
1858void QgsShapeburstFillSymbolLayerWidget::offsetChanged()
1859{
1860 if ( mLayer )
1861 {
1862 mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
1863 emit changed();
1864 }
1865}
1866
1867void QgsShapeburstFillSymbolLayerWidget::mOffsetUnitWidget_changed()
1868{
1869 if ( mLayer )
1870 {
1871 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
1872 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
1873 emit changed();
1874 }
1875}
1876
1877
1878void QgsShapeburstFillSymbolLayerWidget::mIgnoreRingsCheckBox_stateChanged( int state )
1879{
1880 const bool checked = ( state == Qt::Checked );
1881 mLayer->setIgnoreRings( checked );
1882 emit changed();
1883}
1884
1886
1888 : QgsSymbolLayerWidget( parent, vl )
1889 , mSymbolType( symbolType )
1890{
1891 mLayer = nullptr;
1892
1893 setupUi( this );
1894 connect( mIntervalUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsTemplatedLineSymbolLayerWidget::mIntervalUnitWidget_changed );
1895 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsTemplatedLineSymbolLayerWidget::mOffsetUnitWidget_changed );
1896 connect( mOffsetAlongLineUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsTemplatedLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed );
1897 connect( mAverageAngleUnit, &QgsUnitSelectionWidget::changed, this, &QgsTemplatedLineSymbolLayerWidget::averageAngleUnitChanged );
1898 connect( mBlankSegmentsUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsTemplatedLineSymbolLayerWidget::blankSegmentsUnitChanged );
1899
1901 mIntervalUnitWidget->setUnits( units );
1902 mOffsetUnitWidget->setUnits( units );
1903 mOffsetAlongLineUnitWidget->setUnits( QgsUnitTypes::RenderUnitList( units ) << Qgis::RenderUnit::Percentage );
1904 mAverageAngleUnit->setUnits( units );
1905 mIntervalUnitWidget->setUnits( units );
1906 mBlankSegmentsUnitWidget->setUnits( units );
1907
1908 mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( u"mIconAllRings.svg"_s ), tr( "All Rings" ), QgsLineSymbolLayer::AllRings );
1909 mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( u"mIconExteriorRing.svg"_s ), tr( "Exterior Ring Only" ), QgsLineSymbolLayer::ExteriorRingOnly );
1910 mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( u"mIconInteriorRings.svg"_s ), tr( "Interior Rings Only" ), QgsLineSymbolLayer::InteriorRingsOnly );
1911 connect( mRingFilterComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
1912 if ( mLayer )
1913 {
1914 mLayer->setRingFilter( static_cast<QgsLineSymbolLayer::RenderRingFilter>( mRingFilterComboBox->currentData().toInt() ) );
1915 emit changed();
1916 }
1917 } );
1918
1919 spinOffset->setClearValue( 0.0 );
1920 mSpinOffsetAlongLine->setClearValue( 0.0 );
1921 mHashRotationSpinBox->setClearValue( 0 );
1922 mSpinAverageAngleLength->setClearValue( 4.0 );
1923
1924 connect( spinInterval, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsTemplatedLineSymbolLayerWidget::setInterval );
1925 connect( mSpinOffsetAlongLine, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsTemplatedLineSymbolLayerWidget::setOffsetAlongLine );
1926 connect( mSpinHashLength, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsTemplatedLineSymbolLayerWidget::setHashLength );
1927 connect( mHashRotationSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsTemplatedLineSymbolLayerWidget::setHashAngle );
1928 connect( chkRotateMarker, &QAbstractButton::clicked, this, &QgsTemplatedLineSymbolLayerWidget::setRotate );
1929 connect( spinOffset, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsTemplatedLineSymbolLayerWidget::setOffset );
1930 connect( mSpinAverageAngleLength, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsTemplatedLineSymbolLayerWidget::setAverageAngle );
1931 connect( mEditBlankSegmentsBtn, &QToolButton::toggled, this, &QgsMarkerLineSymbolLayerWidget::toggleMapToolEditBlankSegments );
1932
1933 connect( mCheckInterval, &QCheckBox::toggled, this, &QgsTemplatedLineSymbolLayerWidget::setPlacement );
1934 connect( mCheckVertex, &QCheckBox::toggled, this, &QgsTemplatedLineSymbolLayerWidget::setPlacement );
1935 connect( mCheckVertexLast, &QCheckBox::toggled, this, &QgsTemplatedLineSymbolLayerWidget::setPlacement );
1936 connect( mCheckVertexFirst, &QCheckBox::toggled, this, &QgsTemplatedLineSymbolLayerWidget::setPlacement );
1937 connect( mCheckCentralPoint, &QCheckBox::toggled, this, &QgsTemplatedLineSymbolLayerWidget::setPlacement );
1938 connect( mCheckCurvePoint, &QCheckBox::toggled, this, &QgsTemplatedLineSymbolLayerWidget::setPlacement );
1939 connect( mCheckSegmentCentralPoint, &QCheckBox::toggled, this, &QgsTemplatedLineSymbolLayerWidget::setPlacement );
1940
1941 connect( mCheckPlaceOnEveryPart, &QCheckBox::toggled, this, [this] {
1942 if ( mLayer )
1943 {
1944 mLayer->setPlaceOnEveryPart( mCheckPlaceOnEveryPart->isChecked() );
1945 emit changed();
1946 }
1947 } );
1948
1949
1950 switch ( mSymbolType )
1951 {
1953 {
1954 connect( mHashLengthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsTemplatedLineSymbolLayerWidget::hashLengthUnitWidgetChanged );
1956 mPlacementLabel->setText( tr( "Hash placement" ) );
1957 chkRotateMarker->setText( tr( "Rotate hash to follow line direction" ) );
1958 mHashLengthLabel->setVisible( true );
1959 mSpinHashLength->setVisible( true );
1960 mHashLengthUnitWidget->setVisible( true );
1961 mHashLengthDDBtn->setVisible( true );
1962 mHashRotationLabel->setVisible( true );
1963 mHashRotationSpinBox->setVisible( true );
1964 mHashRotationDDBtn->setVisible( true );
1965 break;
1966 }
1967
1969 mPlacementLabel->setText( tr( "Marker placement" ) );
1970 chkRotateMarker->setText( tr( "Rotate marker to follow line direction" ) );
1971 mHashLengthLabel->setVisible( false );
1972 mSpinHashLength->setVisible( false );
1973 mHashLengthUnitWidget->setVisible( false );
1974 mHashLengthDDBtn->setVisible( false );
1975 mHashRotationLabel->setVisible( false );
1976 mHashRotationSpinBox->setVisible( false );
1977 mHashRotationDDBtn->setVisible( false );
1978 }
1979}
1980
1982{
1983 switch ( mSymbolType )
1984 {
1986 if ( layer->layerType() != "HashLine"_L1 )
1987 return;
1988 break;
1989
1991 if ( layer->layerType() != "MarkerLine"_L1 )
1992 return;
1993 }
1994
1995 // layer type is correct, we can do the cast
1996 mLayer = static_cast<QgsTemplatedLineSymbolLayerBase *>( layer );
1997
1998 // set values
1999 spinInterval->blockSignals( true );
2000 spinInterval->setValue( mLayer->interval() );
2001 spinInterval->blockSignals( false );
2002 mSpinOffsetAlongLine->blockSignals( true );
2003 mSpinOffsetAlongLine->setValue( mLayer->offsetAlongLine() );
2004 mSpinOffsetAlongLine->blockSignals( false );
2005
2006 chkRotateMarker->blockSignals( true );
2007 chkRotateMarker->setChecked( mLayer->rotateSymbols() );
2008 chkRotateMarker->blockSignals( false );
2009 spinOffset->blockSignals( true );
2010 spinOffset->setValue( mLayer->offset() );
2011 spinOffset->blockSignals( false );
2012
2013 whileBlocking( mCheckInterval )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::Interval );
2014 whileBlocking( mCheckVertex )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::InnerVertices || mLayer->placements() & Qgis::MarkerLinePlacement::Vertex );
2015 whileBlocking( mCheckVertexFirst )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::FirstVertex || mLayer->placements() & Qgis::MarkerLinePlacement::Vertex );
2016 whileBlocking( mCheckVertexLast )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::LastVertex || mLayer->placements() & Qgis::MarkerLinePlacement::Vertex );
2017 whileBlocking( mCheckCentralPoint )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::CentralPoint );
2018 whileBlocking( mCheckCurvePoint )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::CurvePoint );
2019 whileBlocking( mCheckSegmentCentralPoint )->setChecked( mLayer->placements() & Qgis::MarkerLinePlacement::SegmentCenter );
2020 whileBlocking( mCheckPlaceOnEveryPart )->setChecked( mLayer->placeOnEveryPart() );
2021
2022 // set units
2023 mIntervalUnitWidget->blockSignals( true );
2024 mIntervalUnitWidget->setUnit( mLayer->intervalUnit() );
2025 mIntervalUnitWidget->setMapUnitScale( mLayer->intervalMapUnitScale() );
2026 mIntervalUnitWidget->blockSignals( false );
2027 mOffsetUnitWidget->blockSignals( true );
2028 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
2029 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
2030 mOffsetUnitWidget->blockSignals( false );
2031 mOffsetAlongLineUnitWidget->blockSignals( true );
2032 mOffsetAlongLineUnitWidget->setUnit( mLayer->offsetAlongLineUnit() );
2033 mOffsetAlongLineUnitWidget->setMapUnitScale( mLayer->offsetAlongLineMapUnitScale() );
2034 mOffsetAlongLineUnitWidget->blockSignals( false );
2035 whileBlocking( mAverageAngleUnit )->setUnit( mLayer->averageAngleUnit() );
2036 whileBlocking( mAverageAngleUnit )->setMapUnitScale( mLayer->averageAngleMapUnitScale() );
2037 whileBlocking( mSpinAverageAngleLength )->setValue( mLayer->averageAngleLength() );
2038 whileBlocking( mBlankSegmentsUnitWidget )->setUnit( mLayer->blankSegmentsUnit() );
2039
2040 switch ( mSymbolType )
2041 {
2043 {
2044 QgsHashedLineSymbolLayer *hashLayer = static_cast<QgsHashedLineSymbolLayer *>( mLayer );
2045 whileBlocking( mSpinHashLength )->setValue( hashLayer->hashLength() );
2046 whileBlocking( mHashRotationSpinBox )->setValue( hashLayer->hashAngle() );
2047 whileBlocking( mHashLengthUnitWidget )->setUnit( hashLayer->hashLengthUnit() );
2048 whileBlocking( mHashLengthUnitWidget )->setMapUnitScale( hashLayer->hashLengthMapUnitScale() );
2051 break;
2052 }
2053
2055 break;
2056 }
2057
2058 whileBlocking( mRingFilterComboBox )->setCurrentIndex( mRingFilterComboBox->findData( mLayer->ringFilter() ) );
2059
2060 setPlacement(); // update gui
2061
2068
2069 connect( mBlankSegmentsDDButton, &QgsPropertyOverrideButton::changed, this, &QgsMarkerLineSymbolLayerWidget::updateBlankSegmentsWidget );
2070 connect( mBlankSegmentsDDButton, &QgsPropertyOverrideButton::createAuxiliaryField, this, &QgsMarkerLineSymbolLayerWidget::updateBlankSegmentsWidget );
2071
2072 updateBlankSegmentsWidget();
2073}
2074
2079
2081{
2083
2084 switch ( context.symbolType() )
2085 {
2088 //these settings only have an effect when the symbol layers is part of a fill symbol
2089 mRingFilterComboBox->hide();
2090 mRingsLabel->hide();
2091 break;
2092
2095 break;
2096 }
2097}
2098
2100{
2101 mLayer->setInterval( val );
2102 emit changed();
2103}
2104
2106{
2107 mLayer->setOffsetAlongLine( val );
2108 emit changed();
2109}
2110
2111void QgsTemplatedLineSymbolLayerWidget::setHashLength( double val )
2112{
2113 switch ( mSymbolType )
2114 {
2116 {
2117 QgsHashedLineSymbolLayer *hashLayer = static_cast<QgsHashedLineSymbolLayer *>( mLayer );
2118 hashLayer->setHashLength( val );
2119 emit changed();
2120 break;
2121 }
2122
2124 Q_ASSERT( false );
2125 }
2126}
2127
2128void QgsTemplatedLineSymbolLayerWidget::setHashAngle( double val )
2129{
2130 if ( !mLayer )
2131 return;
2132
2133 switch ( mSymbolType )
2134 {
2136 {
2137 QgsHashedLineSymbolLayer *hashLayer = static_cast<QgsHashedLineSymbolLayer *>( mLayer );
2138 hashLayer->setHashAngle( val );
2139 emit changed();
2140 break;
2141 }
2142
2144 Q_ASSERT( false );
2145 }
2146}
2147
2148void QgsTemplatedLineSymbolLayerWidget::setRotate()
2149{
2150 mSpinAverageAngleLength->setEnabled( chkRotateMarker->isChecked() && ( mCheckInterval->isChecked() || mCheckCentralPoint->isChecked() ) );
2151 mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
2152
2153 mLayer->setRotateSymbols( chkRotateMarker->isChecked() );
2154 emit changed();
2155}
2156
2157void QgsTemplatedLineSymbolLayerWidget::setOffset()
2158{
2159 mLayer->setOffset( spinOffset->value() );
2160 emit changed();
2161}
2162
2163void QgsTemplatedLineSymbolLayerWidget::setPlacement()
2164{
2165 const bool interval = mCheckInterval->isChecked();
2166 spinInterval->setEnabled( interval );
2167 mSpinOffsetAlongLine->setEnabled( mCheckInterval->isChecked() || mCheckVertexLast->isChecked() || mCheckVertexFirst->isChecked() );
2168 mOffsetAlongLineUnitWidget->setEnabled( mSpinOffsetAlongLine->isEnabled() );
2169 mSpinAverageAngleLength->setEnabled( chkRotateMarker->isChecked() && ( mCheckInterval->isChecked() || mCheckCentralPoint->isChecked() ) );
2170 mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
2171 mCheckPlaceOnEveryPart->setEnabled( mCheckVertexLast->isChecked() || mCheckVertexFirst->isChecked() );
2172
2173 Qgis::MarkerLinePlacements placements;
2174 if ( mCheckInterval->isChecked() )
2176 if ( mCheckVertex->isChecked() )
2178 if ( mCheckVertexLast->isChecked() )
2180 if ( mCheckVertexFirst->isChecked() )
2182 if ( mCheckCurvePoint->isChecked() )
2184 if ( mCheckSegmentCentralPoint->isChecked() )
2186 if ( mCheckCentralPoint->isChecked() )
2188 mLayer->setPlacements( placements );
2189
2190 emit changed();
2191}
2192
2193void QgsTemplatedLineSymbolLayerWidget::mIntervalUnitWidget_changed()
2194{
2195 if ( mLayer )
2196 {
2197 mLayer->setIntervalUnit( mIntervalUnitWidget->unit() );
2198 mLayer->setIntervalMapUnitScale( mIntervalUnitWidget->getMapUnitScale() );
2199 emit changed();
2200 }
2201}
2202
2203void QgsTemplatedLineSymbolLayerWidget::mOffsetUnitWidget_changed()
2204{
2205 if ( mLayer )
2206 {
2207 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
2208 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
2209 emit changed();
2210 }
2211}
2212
2213void QgsTemplatedLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed()
2214{
2215 if ( mLayer )
2216 {
2217 mLayer->setOffsetAlongLineUnit( mOffsetAlongLineUnitWidget->unit() );
2218 mLayer->setOffsetAlongLineMapUnitScale( mOffsetAlongLineUnitWidget->getMapUnitScale() );
2219 }
2220 emit changed();
2221}
2222
2223void QgsTemplatedLineSymbolLayerWidget::hashLengthUnitWidgetChanged()
2224{
2225 if ( !mLayer )
2226 return;
2227
2228 switch ( mSymbolType )
2229 {
2231 {
2232 QgsHashedLineSymbolLayer *hashLayer = static_cast<QgsHashedLineSymbolLayer *>( mLayer );
2233 hashLayer->setHashLengthUnit( mHashLengthUnitWidget->unit() );
2234 hashLayer->setHashLengthMapUnitScale( mHashLengthUnitWidget->getMapUnitScale() );
2235 emit changed();
2236 break;
2237 }
2238
2240 Q_ASSERT( false );
2241 }
2242}
2243
2244void QgsTemplatedLineSymbolLayerWidget::averageAngleUnitChanged()
2245{
2246 if ( mLayer )
2247 {
2248 mLayer->setAverageAngleUnit( mAverageAngleUnit->unit() );
2249 mLayer->setAverageAngleMapUnitScale( mAverageAngleUnit->getMapUnitScale() );
2250 }
2251 emit changed();
2252}
2253
2254void QgsTemplatedLineSymbolLayerWidget::blankSegmentsUnitChanged()
2255{
2256 if ( mLayer )
2257 {
2258 mLayer->setBlankSegmentsUnit( mBlankSegmentsUnitWidget->unit() );
2259 }
2260 emit changed();
2261}
2262
2263void QgsTemplatedLineSymbolLayerWidget::setAverageAngle( double val )
2264{
2265 if ( mLayer )
2266 {
2267 mLayer->setAverageAngleLength( val );
2268 emit changed();
2269 }
2270}
2271
2272void QgsTemplatedLineSymbolLayerWidget::toggleMapToolEditBlankSegments( bool toggled )
2273{
2274 if ( mMapToolEditBlankSegments )
2275 {
2276 context().mapCanvas()->unsetMapTool( mMapToolEditBlankSegments );
2277 mMapToolEditBlankSegments.reset();
2278 }
2279
2280 if ( toggled )
2281 {
2282 switch ( mSymbolType )
2283 {
2285 mMapToolEditBlankSegments.reset( new QgsMapToolEditBlankSegments<QgsHashedLineSymbolLayer>( context().mapCanvas(), vectorLayer(), mLayer, blankSegmentsFieldIndex() ) );
2286 break;
2287
2289 mMapToolEditBlankSegments.reset( new QgsMapToolEditBlankSegments<QgsMarkerLineSymbolLayer>( context().mapCanvas(), vectorLayer(), mLayer, blankSegmentsFieldIndex() ) );
2290 break;
2291 }
2292
2293 context().mapCanvas()->setMapTool( mMapToolEditBlankSegments );
2294 }
2295}
2296
2297void QgsTemplatedLineSymbolLayerWidget::updateBlankSegmentsWidget()
2298{
2299 mEditBlankSegmentsBtn->setEnabled( blankSegmentsFieldIndex() > -1 );
2300 QString tooltip;
2301 switch ( mSymbolType )
2302 {
2304 tooltip = tr( "Tool to create blank segments where hashed lines won't be displayed" );
2305 break;
2306
2308 tooltip = tr( "Tool to create blank segments where marker lines won't be displayed" );
2309 break;
2310 }
2311
2312 if ( !mEditBlankSegmentsBtn->isEnabled() )
2313 {
2314 tooltip += u"<br/><br/>"_s + tr( "This tool is disabled because no valid field property has been set" );
2315 }
2316
2317 mEditBlankSegmentsBtn->setToolTip( tooltip );
2318}
2319
2320int QgsTemplatedLineSymbolLayerWidget::blankSegmentsFieldIndex() const
2321{
2322 const QgsProperty blankSegmentsProperty = mLayer->dataDefinedProperties().property( QgsSymbolLayer::Property::BlankSegments );
2323 return blankSegmentsProperty && blankSegmentsProperty.isActive()
2324 && blankSegmentsProperty.propertyType() == Qgis::PropertyType::Field
2325 ? vectorLayer()->fields().indexFromName( blankSegmentsProperty.field() )
2326 : -1;
2327}
2328
2330
2335
2337
2342
2344
2345
2347 : QgsSymbolLayerWidget( parent, vl )
2348{
2349 mLayer = nullptr;
2350
2351 setupUi( this );
2352
2353 mHorizontalAnchorComboBox->addItem( tr( "Left" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Left ) );
2354 mHorizontalAnchorComboBox->addItem( tr( "Horizontal Center" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Center ) );
2355 mHorizontalAnchorComboBox->addItem( tr( "Right" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Right ) );
2356
2357 mVerticalAnchorComboBox->addItem( tr( "Top" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Top ) );
2358 mVerticalAnchorComboBox->addItem( tr( "Vertical Center" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Center ) );
2359 mVerticalAnchorComboBox->addItem( tr( "Bottom" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Bottom ) );
2360
2361 mSvgSelectorWidget->setAllowParameters( true );
2362 mSvgSelectorWidget->sourceLineEdit()->setPropertyOverrideToolButtonVisible( true );
2363 mSvgSelectorWidget->sourceLineEdit()->setLastPathSettingsKey( u"/UI/lastSVGMarkerDir"_s );
2364 mSvgSelectorWidget->initParametersModel( this, vl );
2365
2366 connect( mSvgSelectorWidget->sourceLineEdit(), &QgsSvgSourceLineEdit::sourceChanged, this, &QgsSvgMarkerSymbolLayerWidget::svgSourceChanged );
2367 connect( mChangeColorButton, &QgsColorButton::colorChanged, this, &QgsSvgMarkerSymbolLayerWidget::mChangeColorButton_colorChanged );
2368 connect( mChangeStrokeColorButton, &QgsColorButton::colorChanged, this, &QgsSvgMarkerSymbolLayerWidget::mChangeStrokeColorButton_colorChanged );
2369 connect( mStrokeWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
2370 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
2371 connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
2372 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
2373 connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSvgMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
2374 connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSvgMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
2378 mChangeColorButton->setAllowOpacity( true );
2379 mChangeColorButton->setColorDialogTitle( tr( "Select Fill color" ) );
2380 mChangeColorButton->setContext( u"symbology"_s );
2381 mChangeStrokeColorButton->setAllowOpacity( true );
2382 mChangeStrokeColorButton->setColorDialogTitle( tr( "Select Stroke Color" ) );
2383 mChangeStrokeColorButton->setContext( u"symbology"_s );
2384
2385 mFillColorDDBtn->registerLinkedWidget( mChangeColorButton );
2386 mStrokeColorDDBtn->registerLinkedWidget( mChangeStrokeColorButton );
2387
2388 spinOffsetX->setClearValue( 0.0 );
2389 spinOffsetY->setClearValue( 0.0 );
2390 spinAngle->setClearValue( 0.0 );
2391
2392 connect( spinWidth, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setWidth );
2393 connect( spinHeight, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setHeight );
2394 connect( mLockAspectRatio, static_cast<void ( QgsRatioLockButton::* )( bool )>( &QgsRatioLockButton::lockChanged ), this, &QgsSvgMarkerSymbolLayerWidget::lockAspectRatioChanged );
2395 connect( spinAngle, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setAngle );
2396 connect( spinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setOffset );
2397 connect( spinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setOffset );
2398 connect( this, &QgsSymbolLayerWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::updateAssistantSymbol );
2399
2402
2403 //make a temporary symbol for the size assistant preview
2404 mAssistantPreviewSymbol = std::make_shared<QgsMarkerSymbol>();
2405
2406 if ( vectorLayer() )
2407 {
2408 mWidthDDBtn->setSymbol( mAssistantPreviewSymbol );
2409 mHeightDDBtn->setSymbol( mAssistantPreviewSymbol );
2410 }
2411}
2412
2414
2415#include <QTime>
2416#include <QAbstractListModel>
2417#include <QPixmapCache>
2418#include <QStyle>
2419#include <memory>
2420
2421
2423{
2424 if ( !layer )
2425 {
2426 return;
2427 }
2428
2429 //activate gui for svg parameters only if supported by the svg file
2430 bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2431 QColor defaultFill, defaultStroke;
2432 double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2433 bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
2434 QgsApplication::svgCache()->containsParams( layer->path(), hasFillParam, hasDefaultFillColor, defaultFill, hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity, hasStrokeParam, hasDefaultStrokeColor, defaultStroke, hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth, hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
2435 mChangeColorButton->setEnabled( hasFillParam );
2436 mChangeColorButton->setAllowOpacity( hasFillOpacityParam );
2437 mChangeStrokeColorButton->setEnabled( hasStrokeParam );
2438 mChangeStrokeColorButton->setAllowOpacity( hasStrokeOpacityParam );
2439 mStrokeWidthSpinBox->setEnabled( hasStrokeWidthParam );
2440
2441 if ( hasFillParam )
2442 {
2443 QColor fill = layer->fillColor();
2444 const double existingOpacity = hasFillOpacityParam ? fill.alphaF() : 1.0;
2445 if ( hasDefaultFillColor && !skipDefaultColors )
2446 {
2447 fill = defaultFill;
2448 }
2449 fill.setAlphaF( hasDefaultFillOpacity ? defaultFillOpacity : existingOpacity );
2450 mChangeColorButton->setColor( fill );
2451 }
2452 if ( hasStrokeParam )
2453 {
2454 QColor stroke = layer->strokeColor();
2455 const double existingOpacity = hasStrokeOpacityParam ? stroke.alphaF() : 1.0;
2456 if ( hasDefaultStrokeColor && !skipDefaultColors )
2457 {
2458 stroke = defaultStroke;
2459 }
2460 stroke.setAlphaF( hasDefaultStrokeOpacity ? defaultStrokeOpacity : existingOpacity );
2461 mChangeStrokeColorButton->setColor( stroke );
2462 }
2463
2464 whileBlocking( mSvgSelectorWidget->sourceLineEdit() )->setSource( layer->path() );
2465
2466 mStrokeWidthSpinBox->blockSignals( true );
2467 mStrokeWidthSpinBox->setValue( hasDefaultStrokeWidth ? defaultStrokeWidth : layer->strokeWidth() );
2468 mStrokeWidthSpinBox->blockSignals( false );
2469
2470 const bool preservedAspectRatio = layer->preservedAspectRatio();
2471 spinHeight->blockSignals( true );
2472 if ( preservedAspectRatio )
2473 {
2474 spinHeight->setValue( layer->size() * layer->defaultAspectRatio() );
2475 }
2476 else
2477 {
2478 spinHeight->setValue( layer->size() * layer->fixedAspectRatio() );
2479 }
2480 spinHeight->setEnabled( layer->defaultAspectRatio() > 0.0 );
2481 spinHeight->blockSignals( false );
2482 whileBlocking( mLockAspectRatio )->setLocked( preservedAspectRatio );
2483}
2484
2485void QgsSvgMarkerSymbolLayerWidget::updateAssistantSymbol()
2486{
2487 for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1; i >= 0; --i )
2488 {
2489 mAssistantPreviewSymbol->deleteSymbolLayer( i );
2490 }
2491 mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
2492 const QgsProperty ddSize = mLayer->dataDefinedProperties().property( QgsSymbolLayer::Property::Size );
2493 if ( ddSize )
2494 mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
2495}
2496
2497
2499{
2500 if ( !layer )
2501 {
2502 return;
2503 }
2504
2505 if ( layer->layerType() != "SvgMarker"_L1 )
2506 return;
2507
2508 // layer type is correct, we can do the cast
2509 mLayer = static_cast<QgsSvgMarkerSymbolLayer *>( layer );
2510
2511 // set values
2512 mSvgSelectorWidget->setSvgPath( mLayer->path() );
2513 mSvgSelectorWidget->setSvgParameters( mLayer->parameters() );
2514
2515 spinWidth->blockSignals( true );
2516 spinWidth->setValue( mLayer->size() );
2517 spinWidth->blockSignals( false );
2518 spinAngle->blockSignals( true );
2519 spinAngle->setValue( mLayer->angle() );
2520 spinAngle->blockSignals( false );
2521
2522 // without blocking signals the value gets changed because of slot setOffset()
2523 spinOffsetX->blockSignals( true );
2524 spinOffsetX->setValue( mLayer->offset().x() );
2525 spinOffsetX->blockSignals( false );
2526 spinOffsetY->blockSignals( true );
2527 spinOffsetY->setValue( mLayer->offset().y() );
2528 spinOffsetY->blockSignals( false );
2529
2530 mSizeUnitWidget->blockSignals( true );
2531 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
2532 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
2533 mSizeUnitWidget->blockSignals( false );
2534 mStrokeWidthUnitWidget->blockSignals( true );
2535 mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
2536 mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
2537 mStrokeWidthUnitWidget->blockSignals( false );
2538 mOffsetUnitWidget->blockSignals( true );
2539 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
2540 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
2541 mOffsetUnitWidget->blockSignals( false );
2542
2543 //anchor points
2544 mHorizontalAnchorComboBox->blockSignals( true );
2545 mVerticalAnchorComboBox->blockSignals( true );
2546 mHorizontalAnchorComboBox->setCurrentIndex( mHorizontalAnchorComboBox->findData( QVariant::fromValue( mLayer->horizontalAnchorPoint() ) ) );
2547 mVerticalAnchorComboBox->setCurrentIndex( mVerticalAnchorComboBox->findData( QVariant::fromValue( mLayer->verticalAnchorPoint() ) ) );
2548 mHorizontalAnchorComboBox->blockSignals( false );
2549 mVerticalAnchorComboBox->blockSignals( false );
2550
2551 setGuiForSvg( mLayer, true );
2552
2562
2563 registerDataDefinedButton( mSvgSelectorWidget->sourceLineEdit()->propertyOverrideToolButton(), QgsSymbolLayer::Property::Name );
2564
2565 updateAssistantSymbol();
2566}
2567
2572
2574{
2576 mSvgSelectorWidget->sourceLineEdit()->setMessageBar( context.messageBar() );
2577}
2578
2580{
2581 mLayer->setPath( name );
2582 whileBlocking( mSvgSelectorWidget->sourceLineEdit() )->setSource( name );
2583
2585 emit changed();
2586}
2587
2588void QgsSvgMarkerSymbolLayerWidget::setSvgParameters( const QMap<QString, QgsProperty> &parameters )
2589{
2590 mLayer->setParameters( parameters );
2591 whileBlocking( mSvgSelectorWidget )->setSvgParameters( parameters );
2592
2594 emit changed();
2595}
2596
2597void QgsSvgMarkerSymbolLayerWidget::setWidth()
2598{
2599 const double defaultAspectRatio = mLayer->defaultAspectRatio();
2600 double fixedAspectRatio = 0.0;
2601 spinHeight->blockSignals( true );
2602 if ( defaultAspectRatio <= 0.0 )
2603 {
2604 spinHeight->setValue( spinWidth->value() );
2605 }
2606 else if ( mLockAspectRatio->locked() )
2607 {
2608 spinHeight->setValue( spinWidth->value() * defaultAspectRatio );
2609 }
2610 else
2611 {
2612 fixedAspectRatio = spinHeight->value() / spinWidth->value();
2613 }
2614 spinHeight->blockSignals( false );
2615 mLayer->setSize( spinWidth->value() );
2616 mLayer->setFixedAspectRatio( fixedAspectRatio );
2617 emit changed();
2618}
2619
2620void QgsSvgMarkerSymbolLayerWidget::setHeight()
2621{
2622 const double defaultAspectRatio = mLayer->defaultAspectRatio();
2623 double fixedAspectRatio = 0.0;
2624 spinWidth->blockSignals( true );
2625 if ( defaultAspectRatio <= 0.0 )
2626 {
2627 spinWidth->setValue( spinHeight->value() );
2628 }
2629 else if ( mLockAspectRatio->locked() )
2630 {
2631 spinWidth->setValue( spinHeight->value() / defaultAspectRatio );
2632 }
2633 else
2634 {
2635 fixedAspectRatio = spinHeight->value() / spinWidth->value();
2636 }
2637 spinWidth->blockSignals( false );
2638 mLayer->setSize( spinWidth->value() );
2639 mLayer->setFixedAspectRatio( fixedAspectRatio );
2640 emit changed();
2641}
2642
2643void QgsSvgMarkerSymbolLayerWidget::lockAspectRatioChanged( const bool locked )
2644{
2645 //spinHeight->setEnabled( !locked );
2646 const double defaultAspectRatio = mLayer->defaultAspectRatio();
2647 if ( defaultAspectRatio <= 0.0 )
2648 {
2649 whileBlocking( mLockAspectRatio )->setLocked( true );
2650 }
2651 else if ( locked )
2652 {
2653 mLayer->setFixedAspectRatio( 0.0 );
2654 setWidth();
2655 }
2656 else
2657 {
2658 mLayer->setFixedAspectRatio( spinHeight->value() / spinWidth->value() );
2659 }
2660 //emit changed();
2661}
2662
2663void QgsSvgMarkerSymbolLayerWidget::setAngle()
2664{
2665 mLayer->setAngle( spinAngle->value() );
2666 emit changed();
2667}
2668
2669void QgsSvgMarkerSymbolLayerWidget::setOffset()
2670{
2671 mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
2672 emit changed();
2673}
2674
2675void QgsSvgMarkerSymbolLayerWidget::svgSourceChanged( const QString &text )
2676{
2677 mLayer->setPath( text );
2679 emit changed();
2680}
2681
2682void QgsSvgMarkerSymbolLayerWidget::mChangeColorButton_colorChanged( const QColor &color )
2683{
2684 if ( !mLayer )
2685 {
2686 return;
2687 }
2688
2689 mLayer->setFillColor( color );
2690 emit changed();
2691}
2692
2693void QgsSvgMarkerSymbolLayerWidget::mChangeStrokeColorButton_colorChanged( const QColor &color )
2694{
2695 if ( !mLayer )
2696 {
2697 return;
2698 }
2699
2700 mLayer->setStrokeColor( color );
2701 emit changed();
2702}
2703
2704void QgsSvgMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
2705{
2706 if ( mLayer )
2707 {
2708 mLayer->setStrokeWidth( d );
2709 emit changed();
2710 }
2711}
2712
2713void QgsSvgMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
2714{
2715 if ( mLayer )
2716 {
2717 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
2718 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
2719 emit changed();
2720 }
2721}
2722
2723void QgsSvgMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
2724{
2725 if ( mLayer )
2726 {
2727 mLayer->setStrokeWidthUnit( mStrokeWidthUnitWidget->unit() );
2728 mLayer->setStrokeWidthMapUnitScale( mStrokeWidthUnitWidget->getMapUnitScale() );
2729 emit changed();
2730 }
2731}
2732
2733void QgsSvgMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
2734{
2735 if ( mLayer )
2736 {
2737 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
2738 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
2739 emit changed();
2740 }
2741}
2742
2743void QgsSvgMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int )
2744{
2745 if ( mLayer )
2746 {
2747 mLayer->setHorizontalAnchorPoint( mHorizontalAnchorComboBox->currentData().value< Qgis::HorizontalAnchorPoint >() );
2748 emit changed();
2749 }
2750}
2751
2752void QgsSvgMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int )
2753{
2754 if ( mLayer )
2755 {
2756 mLayer->setVerticalAnchorPoint( mVerticalAnchorComboBox->currentData().value< Qgis::VerticalAnchorPoint >() );
2757 emit changed();
2758 }
2759}
2760
2762
2764 : QgsSymbolLayerWidget( parent, vl )
2765{
2766 mLayer = nullptr;
2767 setupUi( this );
2768
2769 mSvgSelectorWidget->setAllowParameters( true );
2770 mSvgSelectorWidget->sourceLineEdit()->setPropertyOverrideToolButtonVisible( true );
2771
2772 connect( mTextureWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mTextureWidthSpinBox_valueChanged );
2773 connect( mSvgSelectorWidget->sourceLineEdit(), &QgsSvgSourceLineEdit::sourceChanged, this, &QgsSVGFillSymbolLayerWidget::svgSourceChanged );
2774 connect( mRotationSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mRotationSpinBox_valueChanged );
2775 connect( mChangeColorButton, &QgsColorButton::colorChanged, this, &QgsSVGFillSymbolLayerWidget::mChangeColorButton_colorChanged );
2776 connect( mChangeStrokeColorButton, &QgsColorButton::colorChanged, this, &QgsSVGFillSymbolLayerWidget::mChangeStrokeColorButton_colorChanged );
2777 connect( mStrokeWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
2778 connect( mTextureWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSVGFillSymbolLayerWidget::mTextureWidthUnitWidget_changed );
2779 connect( mSvgStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSVGFillSymbolLayerWidget::mSvgStrokeWidthUnitWidget_changed );
2782
2783 mRotationSpinBox->setClearValue( 0.0 );
2784
2785 mChangeColorButton->setColorDialogTitle( tr( "Select Fill Color" ) );
2786 mChangeColorButton->setContext( u"symbology"_s );
2787 mChangeStrokeColorButton->setColorDialogTitle( tr( "Select Stroke Color" ) );
2788 mChangeStrokeColorButton->setContext( u"symbology"_s );
2789
2790 mFilColorDDBtn->registerLinkedWidget( mChangeColorButton );
2791 mStrokeColorDDBtn->registerLinkedWidget( mChangeStrokeColorButton );
2792
2793 connect( mSvgSelectorWidget, &QgsSvgSelectorWidget::svgSelected, this, &QgsSVGFillSymbolLayerWidget::setFile );
2794 connect( mSvgSelectorWidget, &QgsSvgSelectorWidget::svgParametersChanged, this, &QgsSVGFillSymbolLayerWidget::setSvgParameters );
2795}
2796
2798{
2799 if ( !layer )
2800 {
2801 return;
2802 }
2803
2804 if ( layer->layerType() != "SVGFill"_L1 )
2805 {
2806 return;
2807 }
2808
2809 mLayer = dynamic_cast<QgsSVGFillSymbolLayer *>( layer );
2810 if ( mLayer )
2811 {
2812 const double width = mLayer->patternWidth();
2813 mTextureWidthSpinBox->blockSignals( true );
2814 mTextureWidthSpinBox->setValue( width );
2815 mTextureWidthSpinBox->blockSignals( false );
2816 whileBlocking( mSvgSelectorWidget->sourceLineEdit() )->setSource( mLayer->svgFilePath() );
2817 mRotationSpinBox->blockSignals( true );
2818 mRotationSpinBox->setValue( mLayer->angle() );
2819 mRotationSpinBox->blockSignals( false );
2820 mTextureWidthUnitWidget->blockSignals( true );
2821 mTextureWidthUnitWidget->setUnit( mLayer->patternWidthUnit() );
2822 mTextureWidthUnitWidget->setMapUnitScale( mLayer->patternWidthMapUnitScale() );
2823 mTextureWidthUnitWidget->blockSignals( false );
2824 mSvgStrokeWidthUnitWidget->blockSignals( true );
2825 mSvgStrokeWidthUnitWidget->setUnit( mLayer->svgStrokeWidthUnit() );
2826 mSvgStrokeWidthUnitWidget->setMapUnitScale( mLayer->svgStrokeWidthMapUnitScale() );
2827 mSvgStrokeWidthUnitWidget->blockSignals( false );
2828 mChangeColorButton->blockSignals( true );
2829 mChangeColorButton->setColor( mLayer->svgFillColor() );
2830 mChangeColorButton->blockSignals( false );
2831 mChangeStrokeColorButton->blockSignals( true );
2832 mChangeStrokeColorButton->setColor( mLayer->svgStrokeColor() );
2833 mChangeStrokeColorButton->blockSignals( false );
2834 mStrokeWidthSpinBox->blockSignals( true );
2835 mStrokeWidthSpinBox->setValue( mLayer->svgStrokeWidth() );
2836 mStrokeWidthSpinBox->blockSignals( false );
2837 }
2838 updateParamGui( false );
2839
2845
2846 registerDataDefinedButton( mSvgSelectorWidget->sourceLineEdit()->propertyOverrideToolButton(), QgsSymbolLayer::Property::File );
2847}
2848
2853
2855{
2857 mSvgSelectorWidget->sourceLineEdit()->setMessageBar( context.messageBar() );
2858}
2859
2860void QgsSVGFillSymbolLayerWidget::mTextureWidthSpinBox_valueChanged( double d )
2861{
2862 if ( mLayer )
2863 {
2864 mLayer->setPatternWidth( d );
2865 emit changed();
2866 }
2867}
2868
2869void QgsSVGFillSymbolLayerWidget::svgSourceChanged( const QString &text )
2870{
2871 if ( !mLayer )
2872 {
2873 return;
2874 }
2875
2876 mLayer->setSvgFilePath( text );
2878 emit changed();
2879}
2880
2881void QgsSVGFillSymbolLayerWidget::setFile( const QString &name )
2882{
2883 mLayer->setSvgFilePath( name );
2884 whileBlocking( mSvgSelectorWidget->sourceLineEdit() )->setSource( name );
2885
2887 emit changed();
2888}
2889
2890void QgsSVGFillSymbolLayerWidget::setSvgParameters( const QMap<QString, QgsProperty> &parameters )
2891{
2892 mLayer->setParameters( parameters );
2893 whileBlocking( mSvgSelectorWidget )->setSvgParameters( parameters );
2894
2896 emit changed();
2897}
2898
2899
2900void QgsSVGFillSymbolLayerWidget::mRotationSpinBox_valueChanged( double d )
2901{
2902 if ( mLayer )
2903 {
2904 mLayer->setAngle( d );
2905 emit changed();
2906 }
2907}
2908
2910{
2911 //activate gui for svg parameters only if supported by the svg file
2912 bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2913 QColor defaultFill, defaultStroke;
2914 double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2915 bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
2916 QgsApplication::svgCache()->containsParams( mSvgSelectorWidget->sourceLineEdit()->source(), hasFillParam, hasDefaultFillColor, defaultFill, hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity, hasStrokeParam, hasDefaultStrokeColor, defaultStroke, hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth, hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
2917 if ( resetValues )
2918 {
2919 QColor fill = mChangeColorButton->color();
2920 const double newOpacity = hasFillOpacityParam ? fill.alphaF() : 1.0;
2921 if ( hasDefaultFillColor )
2922 {
2923 fill = defaultFill;
2924 }
2925 fill.setAlphaF( hasDefaultFillOpacity ? defaultFillOpacity : newOpacity );
2926 mChangeColorButton->setColor( fill );
2927 }
2928 mChangeColorButton->setEnabled( hasFillParam );
2929 mChangeColorButton->setAllowOpacity( hasFillOpacityParam );
2930 if ( resetValues )
2931 {
2932 QColor stroke = mChangeStrokeColorButton->color();
2933 const double newOpacity = hasStrokeOpacityParam ? stroke.alphaF() : 1.0;
2934 if ( hasDefaultStrokeColor )
2935 {
2936 stroke = defaultStroke;
2937 }
2938 stroke.setAlphaF( hasDefaultStrokeOpacity ? defaultStrokeOpacity : newOpacity );
2939 mChangeStrokeColorButton->setColor( stroke );
2940 }
2941 mChangeStrokeColorButton->setEnabled( hasStrokeParam );
2942 mChangeStrokeColorButton->setAllowOpacity( hasStrokeOpacityParam );
2943 if ( hasDefaultStrokeWidth && resetValues )
2944 {
2945 mStrokeWidthSpinBox->setValue( defaultStrokeWidth );
2946 }
2947 mStrokeWidthSpinBox->setEnabled( hasStrokeWidthParam );
2948}
2949
2950void QgsSVGFillSymbolLayerWidget::mChangeColorButton_colorChanged( const QColor &color )
2951{
2952 if ( !mLayer )
2953 {
2954 return;
2955 }
2956
2957 mLayer->setSvgFillColor( color );
2958 emit changed();
2959}
2960
2961void QgsSVGFillSymbolLayerWidget::mChangeStrokeColorButton_colorChanged( const QColor &color )
2962{
2963 if ( !mLayer )
2964 {
2965 return;
2966 }
2967
2968 mLayer->setSvgStrokeColor( color );
2969 emit changed();
2970}
2971
2972void QgsSVGFillSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
2973{
2974 if ( mLayer )
2975 {
2976 mLayer->setSvgStrokeWidth( d );
2977 emit changed();
2978 }
2979}
2980
2981void QgsSVGFillSymbolLayerWidget::mTextureWidthUnitWidget_changed()
2982{
2983 if ( mLayer )
2984 {
2985 mLayer->setPatternWidthUnit( mTextureWidthUnitWidget->unit() );
2986 mLayer->setPatternWidthMapUnitScale( mTextureWidthUnitWidget->getMapUnitScale() );
2987 emit changed();
2988 }
2989}
2990
2991void QgsSVGFillSymbolLayerWidget::mSvgStrokeWidthUnitWidget_changed()
2992{
2993 if ( mLayer )
2994 {
2995 mLayer->setSvgStrokeWidthUnit( mSvgStrokeWidthUnitWidget->unit() );
2996 mLayer->setSvgStrokeWidthMapUnitScale( mSvgStrokeWidthUnitWidget->getMapUnitScale() );
2997 emit changed();
2998 }
2999}
3000
3002
3004 : QgsSymbolLayerWidget( parent, vl )
3005{
3006 setupUi( this );
3007 connect( mAngleSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLinePatternFillSymbolLayerWidget::mAngleSpinBox_valueChanged );
3008 connect( mDistanceSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLinePatternFillSymbolLayerWidget::mDistanceSpinBox_valueChanged );
3009 connect( mOffsetSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLinePatternFillSymbolLayerWidget::mOffsetSpinBox_valueChanged );
3010 connect( mDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsLinePatternFillSymbolLayerWidget::mDistanceUnitWidget_changed );
3011 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsLinePatternFillSymbolLayerWidget::mOffsetUnitWidget_changed );
3014 mOffsetSpinBox->setClearValue( 0 );
3015 mAngleSpinBox->setClearValue( 0 );
3016
3017 mCoordinateReferenceComboBox->addItem( tr( "Align Pattern to Feature" ), static_cast<int>( Qgis::SymbolCoordinateReference::Feature ) );
3018 mCoordinateReferenceComboBox->addItem( tr( "Align Pattern to Map Extent" ), static_cast<int>( Qgis::SymbolCoordinateReference::Viewport ) );
3019 connect( mCoordinateReferenceComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this] {
3020 if ( mLayer )
3021 {
3022 mLayer->setCoordinateReference( static_cast<Qgis::SymbolCoordinateReference>( mCoordinateReferenceComboBox->currentData().toInt() ) );
3023 emit changed();
3024 }
3025 } );
3026
3027 mClipModeComboBox->addItem( tr( "Clip During Render Only" ), static_cast<int>( Qgis::LineClipMode::ClipPainterOnly ) );
3028 mClipModeComboBox->addItem( tr( "Clip Lines Before Render" ), static_cast<int>( Qgis::LineClipMode::ClipToIntersection ) );
3029 mClipModeComboBox->addItem( tr( "No Clipping" ), static_cast<int>( Qgis::LineClipMode::NoClipping ) );
3030 connect( mClipModeComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this] {
3031 if ( mLayer )
3032 {
3033 mLayer->setClipMode( static_cast<Qgis::LineClipMode>( mClipModeComboBox->currentData().toInt() ) );
3034 emit changed();
3035 }
3036 } );
3037}
3038
3040{
3041 if ( layer->layerType() != "LinePatternFill"_L1 )
3042 {
3043 return;
3044 }
3045
3046 QgsLinePatternFillSymbolLayer *patternLayer = static_cast<QgsLinePatternFillSymbolLayer *>( layer );
3047 if ( patternLayer )
3048 {
3049 mLayer = patternLayer;
3050 whileBlocking( mAngleSpinBox )->setValue( mLayer->lineAngle() );
3051 whileBlocking( mDistanceSpinBox )->setValue( mLayer->distance() );
3052 whileBlocking( mOffsetSpinBox )->setValue( mLayer->offset() );
3053
3054 //units
3055 mDistanceUnitWidget->blockSignals( true );
3056 mDistanceUnitWidget->setUnit( mLayer->distanceUnit() );
3057 mDistanceUnitWidget->setMapUnitScale( mLayer->distanceMapUnitScale() );
3058 mDistanceUnitWidget->blockSignals( false );
3059 mOffsetUnitWidget->blockSignals( true );
3060 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
3061 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
3062 mOffsetUnitWidget->blockSignals( false );
3063
3064 whileBlocking( mCoordinateReferenceComboBox )->setCurrentIndex( mCoordinateReferenceComboBox->findData( static_cast<int>( mLayer->coordinateReference() ) ) );
3065
3066 whileBlocking( mClipModeComboBox )->setCurrentIndex( mClipModeComboBox->findData( static_cast<int>( mLayer->clipMode() ) ) );
3067 }
3068
3073}
3074
3079
3080void QgsLinePatternFillSymbolLayerWidget::mAngleSpinBox_valueChanged( double d )
3081{
3082 if ( mLayer )
3083 {
3084 mLayer->setLineAngle( d );
3085 emit changed();
3086 }
3087}
3088
3089void QgsLinePatternFillSymbolLayerWidget::mDistanceSpinBox_valueChanged( double d )
3090{
3091 if ( mLayer )
3092 {
3093 mLayer->setDistance( d );
3094 emit changed();
3095 }
3096}
3097
3098void QgsLinePatternFillSymbolLayerWidget::mOffsetSpinBox_valueChanged( double d )
3099{
3100 if ( mLayer )
3101 {
3102 mLayer->setOffset( d );
3103 emit changed();
3104 }
3105}
3106
3107void QgsLinePatternFillSymbolLayerWidget::mDistanceUnitWidget_changed()
3108{
3109 if ( mLayer )
3110 {
3111 mLayer->setDistanceUnit( mDistanceUnitWidget->unit() );
3112 mLayer->setDistanceMapUnitScale( mDistanceUnitWidget->getMapUnitScale() );
3113 emit changed();
3114 }
3115}
3116
3117void QgsLinePatternFillSymbolLayerWidget::mOffsetUnitWidget_changed()
3118{
3119 if ( mLayer )
3120 {
3121 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
3122 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
3123 emit changed();
3124 }
3125}
3126
3128
3130 : QgsSymbolLayerWidget( parent, vl )
3131{
3132 setupUi( this );
3133 connect( mHorizontalDistanceSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceSpinBox_valueChanged );
3134 connect( mVerticalDistanceSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceSpinBox_valueChanged );
3135 connect( mHorizontalDisplacementSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementSpinBox_valueChanged );
3136 connect( mVerticalDisplacementSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementSpinBox_valueChanged );
3137 connect( mHorizontalOffsetSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetSpinBox_valueChanged );
3138 connect( mVerticalOffsetSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetSpinBox_valueChanged );
3139 connect( mHorizontalDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceUnitWidget_changed );
3140 connect( mVerticalDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceUnitWidget_changed );
3141 connect( mHorizontalDisplacementUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementUnitWidget_changed );
3142 connect( mVerticalDisplacementUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementUnitWidget_changed );
3143 connect( mHorizontalOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetUnitWidget_changed );
3144 connect( mVerticalOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetUnitWidget_changed );
3151
3152 mClipModeComboBox->addItem( tr( "Clip to Shape" ), static_cast<int>( Qgis::MarkerClipMode::Shape ) );
3153 mClipModeComboBox->addItem( tr( "Marker Centroid Within Shape" ), static_cast<int>( Qgis::MarkerClipMode::CentroidWithin ) );
3154 mClipModeComboBox->addItem( tr( "Marker Completely Within Shape" ), static_cast<int>( Qgis::MarkerClipMode::CompletelyWithin ) );
3155 mClipModeComboBox->addItem( tr( "No Clipping" ), static_cast<int>( Qgis::MarkerClipMode::NoClipping ) );
3156 connect( mClipModeComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this] {
3157 if ( mLayer )
3158 {
3159 mLayer->setClipMode( static_cast<Qgis::MarkerClipMode>( mClipModeComboBox->currentData().toInt() ) );
3160 emit changed();
3161 }
3162 } );
3163
3164 mCoordinateReferenceComboBox->addItem( tr( "Align Pattern to Feature" ), static_cast<int>( Qgis::SymbolCoordinateReference::Feature ) );
3165 mCoordinateReferenceComboBox->addItem( tr( "Align Pattern to Map Extent" ), static_cast<int>( Qgis::SymbolCoordinateReference::Viewport ) );
3166 connect( mCoordinateReferenceComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this] {
3167 if ( mLayer )
3168 {
3169 mLayer->setCoordinateReference( static_cast<Qgis::SymbolCoordinateReference>( mCoordinateReferenceComboBox->currentData().toInt() ) );
3170 emit changed();
3171 }
3172 } );
3173
3174 mSeedSpinBox->setShowClearButton( true );
3175 mSeedSpinBox->setClearValue( 0 );
3176 mRandomXSpinBox->setClearValue( 0 );
3177 mRandomYSpinBox->setClearValue( 0 );
3178
3181 connect( mRandomXSpinBox, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double d ) {
3182 if ( mLayer )
3183 {
3184 mLayer->setMaximumRandomDeviationX( d );
3185 emit changed();
3186 }
3187 } );
3188 connect( mRandomYSpinBox, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double d ) {
3189 if ( mLayer )
3190 {
3191 mLayer->setMaximumRandomDeviationY( d );
3192 emit changed();
3193 }
3194 } );
3195 connect( mRandomXOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
3196 if ( mLayer )
3197 {
3198 mLayer->setRandomDeviationXUnit( mRandomXOffsetUnitWidget->unit() );
3199 mLayer->setRandomDeviationXMapUnitScale( mRandomXOffsetUnitWidget->getMapUnitScale() );
3200 emit changed();
3201 }
3202 } );
3203 connect( mRandomYOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
3204 if ( mLayer )
3205 {
3206 mLayer->setRandomDeviationYUnit( mRandomYOffsetUnitWidget->unit() );
3207 mLayer->setRandomDeviationYMapUnitScale( mRandomYOffsetUnitWidget->getMapUnitScale() );
3208 emit changed();
3209 }
3210 } );
3211 connect( mSeedSpinBox, qOverload<int>( &QSpinBox::valueChanged ), this, [this]( int v ) {
3212 if ( mLayer )
3213 {
3214 mLayer->setSeed( v );
3215 emit changed();
3216 }
3217 } );
3218
3219 mAngleSpinBox->setShowClearButton( true );
3220 mAngleSpinBox->setClearValue( 0 );
3221 connect( mAngleSpinBox, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double d ) {
3222 if ( mLayer )
3223 {
3224 mLayer->setAngle( d );
3225 emit changed();
3226 }
3227 } );
3228}
3229
3231{
3232 if ( !layer || layer->layerType() != "PointPatternFill"_L1 )
3233 {
3234 return;
3235 }
3236
3237 mLayer = static_cast<QgsPointPatternFillSymbolLayer *>( layer );
3238 whileBlocking( mHorizontalDistanceSpinBox )->setValue( mLayer->distanceX() );
3239 whileBlocking( mVerticalDistanceSpinBox )->setValue( mLayer->distanceY() );
3240 whileBlocking( mHorizontalDisplacementSpinBox )->setValue( mLayer->displacementX() );
3241 whileBlocking( mVerticalDisplacementSpinBox )->setValue( mLayer->displacementY() );
3242 whileBlocking( mHorizontalOffsetSpinBox )->setValue( mLayer->offsetX() );
3243 whileBlocking( mVerticalOffsetSpinBox )->setValue( mLayer->offsetY() );
3244 whileBlocking( mAngleSpinBox )->setValue( mLayer->angle() );
3245
3246 mHorizontalDistanceUnitWidget->blockSignals( true );
3247 mHorizontalDistanceUnitWidget->setUnit( mLayer->distanceXUnit() );
3248 mHorizontalDistanceUnitWidget->setMapUnitScale( mLayer->distanceXMapUnitScale() );
3249 mHorizontalDistanceUnitWidget->blockSignals( false );
3250 mVerticalDistanceUnitWidget->blockSignals( true );
3251 mVerticalDistanceUnitWidget->setUnit( mLayer->distanceYUnit() );
3252 mVerticalDistanceUnitWidget->setMapUnitScale( mLayer->distanceYMapUnitScale() );
3253 mVerticalDistanceUnitWidget->blockSignals( false );
3254 mHorizontalDisplacementUnitWidget->blockSignals( true );
3255 mHorizontalDisplacementUnitWidget->setUnit( mLayer->displacementXUnit() );
3256 mHorizontalDisplacementUnitWidget->setMapUnitScale( mLayer->displacementXMapUnitScale() );
3257 mHorizontalDisplacementUnitWidget->blockSignals( false );
3258 mVerticalDisplacementUnitWidget->blockSignals( true );
3259 mVerticalDisplacementUnitWidget->setUnit( mLayer->displacementYUnit() );
3260 mVerticalDisplacementUnitWidget->setMapUnitScale( mLayer->displacementYMapUnitScale() );
3261 mVerticalDisplacementUnitWidget->blockSignals( false );
3262 mHorizontalOffsetUnitWidget->blockSignals( true );
3263 mHorizontalOffsetUnitWidget->setUnit( mLayer->offsetXUnit() );
3264 mHorizontalOffsetUnitWidget->setMapUnitScale( mLayer->offsetXMapUnitScale() );
3265 mHorizontalOffsetUnitWidget->blockSignals( false );
3266 mVerticalOffsetUnitWidget->blockSignals( true );
3267 mVerticalOffsetUnitWidget->setUnit( mLayer->offsetYUnit() );
3268 mVerticalOffsetUnitWidget->setMapUnitScale( mLayer->offsetYMapUnitScale() );
3269 mVerticalOffsetUnitWidget->blockSignals( false );
3270
3271 whileBlocking( mClipModeComboBox )->setCurrentIndex( mClipModeComboBox->findData( static_cast<int>( mLayer->clipMode() ) ) );
3272 whileBlocking( mCoordinateReferenceComboBox )->setCurrentIndex( mCoordinateReferenceComboBox->findData( static_cast<int>( mLayer->coordinateReference() ) ) );
3273
3274 whileBlocking( mRandomXSpinBox )->setValue( mLayer->maximumRandomDeviationX() );
3275 whileBlocking( mRandomYSpinBox )->setValue( mLayer->maximumRandomDeviationY() );
3276 whileBlocking( mRandomXOffsetUnitWidget )->setUnit( mLayer->randomDeviationXUnit() );
3277 whileBlocking( mRandomXOffsetUnitWidget )->setMapUnitScale( mLayer->randomDeviationXMapUnitScale() );
3278 whileBlocking( mRandomYOffsetUnitWidget )->setUnit( mLayer->randomDeviationYUnit() );
3279 whileBlocking( mRandomYOffsetUnitWidget )->setMapUnitScale( mLayer->randomDeviationYMapUnitScale() );
3280 whileBlocking( mSeedSpinBox )->setValue( mLayer->seed() );
3281
3294}
3295
3300
3301void QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceSpinBox_valueChanged( double d )
3302{
3303 if ( mLayer )
3304 {
3305 mLayer->setDistanceX( d );
3306 emit changed();
3307 }
3308}
3309
3310void QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceSpinBox_valueChanged( double d )
3311{
3312 if ( mLayer )
3313 {
3314 mLayer->setDistanceY( d );
3315 emit changed();
3316 }
3317}
3318
3319void QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementSpinBox_valueChanged( double d )
3320{
3321 if ( mLayer )
3322 {
3323 mLayer->setDisplacementX( d );
3324 emit changed();
3325 }
3326}
3327
3328void QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementSpinBox_valueChanged( double d )
3329{
3330 if ( mLayer )
3331 {
3332 mLayer->setDisplacementY( d );
3333 emit changed();
3334 }
3335}
3336
3337void QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetSpinBox_valueChanged( double d )
3338{
3339 if ( mLayer )
3340 {
3341 mLayer->setOffsetX( d );
3342 emit changed();
3343 }
3344}
3345
3346void QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetSpinBox_valueChanged( double d )
3347{
3348 if ( mLayer )
3349 {
3350 mLayer->setOffsetY( d );
3351 emit changed();
3352 }
3353}
3354
3355void QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceUnitWidget_changed()
3356{
3357 if ( mLayer )
3358 {
3359 mLayer->setDistanceXUnit( mHorizontalDistanceUnitWidget->unit() );
3360 mLayer->setDistanceXMapUnitScale( mHorizontalDistanceUnitWidget->getMapUnitScale() );
3361 emit changed();
3362 }
3363}
3364
3365void QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceUnitWidget_changed()
3366{
3367 if ( mLayer )
3368 {
3369 mLayer->setDistanceYUnit( mVerticalDistanceUnitWidget->unit() );
3370 mLayer->setDistanceYMapUnitScale( mVerticalDistanceUnitWidget->getMapUnitScale() );
3371 emit changed();
3372 }
3373}
3374
3375void QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementUnitWidget_changed()
3376{
3377 if ( mLayer )
3378 {
3379 mLayer->setDisplacementXUnit( mHorizontalDisplacementUnitWidget->unit() );
3380 mLayer->setDisplacementXMapUnitScale( mHorizontalDisplacementUnitWidget->getMapUnitScale() );
3381 emit changed();
3382 }
3383}
3384
3385void QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementUnitWidget_changed()
3386{
3387 if ( mLayer )
3388 {
3389 mLayer->setDisplacementYUnit( mVerticalDisplacementUnitWidget->unit() );
3390 mLayer->setDisplacementYMapUnitScale( mVerticalDisplacementUnitWidget->getMapUnitScale() );
3391 emit changed();
3392 }
3393}
3394
3395void QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetUnitWidget_changed()
3396{
3397 if ( mLayer )
3398 {
3399 mLayer->setOffsetXUnit( mHorizontalOffsetUnitWidget->unit() );
3400 mLayer->setOffsetXMapUnitScale( mHorizontalOffsetUnitWidget->getMapUnitScale() );
3401 emit changed();
3402 }
3403}
3404
3405void QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetUnitWidget_changed()
3406{
3407 if ( mLayer )
3408 {
3409 mLayer->setOffsetYUnit( mVerticalOffsetUnitWidget->unit() );
3410 mLayer->setOffsetYMapUnitScale( mVerticalOffsetUnitWidget->getMapUnitScale() );
3411 emit changed();
3412 }
3413}
3414
3416
3418 : QgsSymbolLayerWidget( parent, vl )
3419{
3420 mLayer = nullptr;
3421
3422 setupUi( this );
3423
3424 mHorizontalAnchorComboBox->addItem( tr( "Left" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Left ) );
3425 mHorizontalAnchorComboBox->addItem( tr( "Horizontal Center" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Center ) );
3426 mHorizontalAnchorComboBox->addItem( tr( "Right" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Right ) );
3427
3428 mVerticalAnchorComboBox->addItem( tr( "Top" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Top ) );
3429 mVerticalAnchorComboBox->addItem( tr( "Vertical Center" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Center ) );
3430 mVerticalAnchorComboBox->addItem( tr( "Bottom on Baseline" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Baseline ) );
3431 mVerticalAnchorComboBox->addItem( tr( "Bottom" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Bottom ) );
3432
3433 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
3434 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
3435 connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
3436 connect( mStrokeWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
3437 connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
3438 connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
3442
3444 scrollArea->setWidget( widgetChar );
3445 scrollArea->setVerticalOnly( true );
3446
3447 btnColor->setAllowOpacity( true );
3448 btnColor->setColorDialogTitle( tr( "Select Symbol Fill Color" ) );
3449 btnColor->setContext( u"symbology"_s );
3450 btnStrokeColor->setAllowOpacity( true );
3451 btnStrokeColor->setColorDialogTitle( tr( "Select Symbol Stroke Color" ) );
3452 btnStrokeColor->setContext( u"symbology"_s );
3453
3454 mColorDDBtn->registerLinkedWidget( btnColor );
3455 mStrokeColorDDBtn->registerLinkedWidget( btnStrokeColor );
3456
3457 spinOffsetX->setClearValue( 0.0 );
3458 spinOffsetY->setClearValue( 0.0 );
3459 spinAngle->setClearValue( 0.0 );
3460
3461 //make a temporary symbol for the size assistant preview
3462 mAssistantPreviewSymbol = std::make_shared<QgsMarkerSymbol>();
3463
3464 if ( vectorLayer() )
3465 mSizeDDBtn->setSymbol( mAssistantPreviewSymbol );
3466
3467 connect( cboFont, &QFontComboBox::currentFontChanged, this, &QgsFontMarkerSymbolLayerWidget::setFontFamily );
3468 connect( mFontStyleComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::mFontStyleComboBox_currentIndexChanged );
3469 connect( spinSize, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setSize );
3470 connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::penJoinStyleChanged );
3473 connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::penJoinStyleChanged );
3474 connect( spinAngle, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setAngle );
3475 connect( spinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setOffset );
3476 connect( spinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setOffset );
3478 connect( mCharLineEdit, &QLineEdit::textChanged, this, &QgsFontMarkerSymbolLayerWidget::setCharacterFromText );
3479
3480 connect( this, &QgsSymbolLayerWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::updateAssistantSymbol );
3481}
3482
3484
3486{
3487 if ( layer->layerType() != "FontMarker"_L1 )
3488 return;
3489
3490 // layer type is correct, we can do the cast
3491 mLayer = static_cast<QgsFontMarkerSymbolLayer *>( layer );
3492
3493 QgsFontUtils::setFontFamily( mRefFont, mLayer->fontFamily() );
3494 mRefFont.setStyleName( QgsFontUtils::translateNamedStyle( mLayer->fontStyle() ) );
3495
3496 mFontStyleComboBox->blockSignals( true );
3497 populateFontStyleComboBox();
3498 mFontStyleComboBox->blockSignals( false );
3499
3500 // set values
3501 whileBlocking( cboFont )->setCurrentFont( mRefFont );
3502 whileBlocking( spinSize )->setValue( mLayer->size() );
3503 whileBlocking( btnColor )->setColor( mLayer->color() );
3504 whileBlocking( btnStrokeColor )->setColor( mLayer->strokeColor() );
3505 whileBlocking( mStrokeWidthSpinBox )->setValue( mLayer->strokeWidth() );
3506 whileBlocking( spinAngle )->setValue( mLayer->angle() );
3507
3508 widgetChar->blockSignals( true );
3509 widgetChar->setFont( mRefFont );
3510 if ( mLayer->character().length() == 1 )
3511 {
3512 widgetChar->setCharacter( mLayer->character().at( 0 ) );
3513 }
3514 widgetChar->blockSignals( false );
3515 whileBlocking( mCharLineEdit )->setText( mLayer->character() );
3516 mCharPreview->setFont( mRefFont );
3517
3518 //block
3519 whileBlocking( spinOffsetX )->setValue( mLayer->offset().x() );
3520 whileBlocking( spinOffsetY )->setValue( mLayer->offset().y() );
3521
3522 mSizeUnitWidget->blockSignals( true );
3523 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
3524 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
3525 mSizeUnitWidget->blockSignals( false );
3526
3527 mStrokeWidthUnitWidget->blockSignals( true );
3528 mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
3529 mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
3530 mStrokeWidthUnitWidget->blockSignals( false );
3531
3532 mOffsetUnitWidget->blockSignals( true );
3533 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
3534 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
3535 mOffsetUnitWidget->blockSignals( false );
3536
3537 whileBlocking( cboJoinStyle )->setPenJoinStyle( mLayer->penJoinStyle() );
3538
3539 //anchor points
3540 whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mHorizontalAnchorComboBox->findData( QVariant::fromValue( mLayer->horizontalAnchorPoint() ) ) );
3541 whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mVerticalAnchorComboBox->findData( QVariant::fromValue( mLayer->verticalAnchorPoint() ) ) );
3542
3555
3556 updateAssistantSymbol();
3557}
3558
3563
3565{
3566 if ( mLayer )
3567 {
3568 mLayer->setFontFamily( font.family() );
3569 QgsFontUtils::setFontFamily( mRefFont, font.family() );
3570 widgetChar->setFont( mRefFont );
3571 mCharPreview->setFont( mRefFont );
3572 populateFontStyleComboBox();
3573 emit changed();
3574 }
3575}
3576
3577void QgsFontMarkerSymbolLayerWidget::setFontStyle( const QString &style )
3578{
3579 if ( mLayer )
3580 {
3581 QgsFontUtils::updateFontViaStyle( mRefFont, style );
3583 widgetChar->setFont( mRefFont );
3584 mCharPreview->setFont( mRefFont );
3585 emit changed();
3586 }
3587}
3588
3590{
3591 mLayer->setColor( color );
3592 emit changed();
3593}
3594
3596{
3597 mLayer->setStrokeColor( color );
3598 emit changed();
3599}
3600
3602{
3603 mLayer->setSize( size );
3604 //widgetChar->updateSize(size);
3605 emit changed();
3606}
3607
3609{
3610 mLayer->setAngle( angle );
3611 emit changed();
3612}
3613
3615{
3616 mCharPreview->setText( text );
3617
3618 if ( text.isEmpty() )
3619 return;
3620
3621 // take the last character of a string for a better experience when users cycle through several characters on their keyboard
3622 QString character = text;
3623 if ( text.contains( QRegularExpression( u"^0x[0-9a-fA-F]{1,4}$"_s ) ) )
3624 {
3625 bool ok = false;
3626 const unsigned int value = text.toUInt( &ok, 0 );
3627 if ( ok )
3628 {
3629 character = QChar( value );
3630 mCharPreview->setText( character );
3631 }
3632 }
3633
3634 if ( character != mLayer->character() )
3635 {
3636 mLayer->setCharacter( character );
3637 if ( mLayer->character().length() == 1 )
3638 {
3639 whileBlocking( widgetChar )->setCharacter( mLayer->character().at( 0 ) );
3640 }
3641 else
3642 {
3643 widgetChar->clearCharacter();
3644 }
3645 emit changed();
3646 }
3647}
3648
3650{
3651 if ( mLayer->character().length() > 1 || QGuiApplication::keyboardModifiers() & Qt::ControlModifier )
3652 {
3653 mCharLineEdit->insert( chr );
3654 return;
3655 }
3656
3657 mLayer->setCharacter( chr );
3658 whileBlocking( mCharLineEdit )->setText( chr );
3659 mCharPreview->setText( chr );
3660 emit changed();
3661}
3662
3663void QgsFontMarkerSymbolLayerWidget::setOffset()
3664{
3665 mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
3666 emit changed();
3667}
3668
3669void QgsFontMarkerSymbolLayerWidget::penJoinStyleChanged()
3670{
3671 mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
3672 emit changed();
3673}
3674
3675void QgsFontMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
3676{
3677 if ( mLayer )
3678 {
3679 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
3680 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
3681 emit changed();
3682 }
3683}
3684
3685void QgsFontMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
3686{
3687 if ( mLayer )
3688 {
3689 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
3690 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
3691 emit changed();
3692 }
3693}
3694
3695void QgsFontMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
3696{
3697 if ( mLayer )
3698 {
3699 mLayer->setStrokeWidthUnit( mSizeUnitWidget->unit() );
3700 mLayer->setStrokeWidthMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
3701 emit changed();
3702 }
3703}
3704
3705void QgsFontMarkerSymbolLayerWidget::populateFontStyleComboBox()
3706{
3707 mFontStyleComboBox->clear();
3708 const QStringList styles = mFontDB.styles( mRefFont.family() );
3709 const auto constStyles = styles;
3710 for ( const QString &style : constStyles )
3711 {
3712 mFontStyleComboBox->addItem( style );
3713 }
3714
3715 QString targetStyle = mFontDB.styleString( mRefFont );
3716 if ( !styles.contains( targetStyle ) )
3717 {
3718 const QFont f = QgsFontUtils::createFont( mRefFont.family() );
3719 targetStyle = QFontInfo( f ).styleName();
3720 mRefFont.setStyleName( targetStyle );
3721 }
3722 int curIndx = 0;
3723 const int stylIndx = mFontStyleComboBox->findText( targetStyle );
3724 if ( stylIndx > -1 )
3725 {
3726 curIndx = stylIndx;
3727 }
3728
3729 mFontStyleComboBox->setCurrentIndex( curIndx );
3730}
3731
3732void QgsFontMarkerSymbolLayerWidget::mFontStyleComboBox_currentIndexChanged( int index )
3733{
3734 Q_UNUSED( index );
3735 setFontStyle( mFontStyleComboBox->currentText() );
3736}
3737
3738void QgsFontMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int )
3739{
3740 if ( mLayer )
3741 {
3742 mLayer->setHorizontalAnchorPoint( mHorizontalAnchorComboBox->currentData().value< Qgis::HorizontalAnchorPoint >() );
3743 emit changed();
3744 }
3745}
3746
3747void QgsFontMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int )
3748{
3749 if ( mLayer )
3750 {
3751 mLayer->setVerticalAnchorPoint( mVerticalAnchorComboBox->currentData().value< Qgis::VerticalAnchorPoint >() );
3752 emit changed();
3753 }
3754}
3755
3756void QgsFontMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
3757{
3758 if ( mLayer )
3759 {
3760 mLayer->setStrokeWidth( d );
3761 emit changed();
3762 }
3763}
3764
3765void QgsFontMarkerSymbolLayerWidget::updateAssistantSymbol()
3766{
3767 for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1; i >= 0; --i )
3768 {
3769 mAssistantPreviewSymbol->deleteSymbolLayer( i );
3770 }
3771 mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
3772 const QgsProperty ddSize = mLayer->dataDefinedProperties().property( QgsSymbolLayer::Property::Size );
3773 if ( ddSize )
3774 mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
3775}
3776
3778
3779
3781 : QgsSymbolLayerWidget( parent, vl )
3782{
3783 mLayer = nullptr;
3784
3785 setupUi( this );
3786 connect( mDrawInsideCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mDrawInsideCheckBox_stateChanged );
3787 connect( mDrawAllPartsCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mDrawAllPartsCheckBox_stateChanged );
3788 connect( mClipPointsCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mClipPointsCheckBox_stateChanged );
3789 connect( mClipOnCurrentPartOnlyCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mClipOnCurrentPartOnlyCheckBox_stateChanged );
3790}
3791
3793{
3794 if ( layer->layerType() != "CentroidFill"_L1 )
3795 return;
3796
3797 // layer type is correct, we can do the cast
3798 mLayer = static_cast<QgsCentroidFillSymbolLayer *>( layer );
3799
3800 // set values
3801 whileBlocking( mDrawInsideCheckBox )->setChecked( mLayer->pointOnSurface() );
3802 whileBlocking( mDrawAllPartsCheckBox )->setChecked( mLayer->pointOnAllParts() );
3803 whileBlocking( mClipPointsCheckBox )->setChecked( mLayer->clipPoints() );
3804 whileBlocking( mClipOnCurrentPartOnlyCheckBox )->setChecked( mLayer->clipOnCurrentPartOnly() );
3805}
3806
3811
3812void QgsCentroidFillSymbolLayerWidget::mDrawInsideCheckBox_stateChanged( int state )
3813{
3814 mLayer->setPointOnSurface( state == Qt::Checked );
3815 emit changed();
3816}
3817
3818void QgsCentroidFillSymbolLayerWidget::mDrawAllPartsCheckBox_stateChanged( int state )
3819{
3820 mLayer->setPointOnAllParts( state == Qt::Checked );
3821 emit changed();
3822}
3823
3824void QgsCentroidFillSymbolLayerWidget::mClipPointsCheckBox_stateChanged( int state )
3825{
3826 mLayer->setClipPoints( state == Qt::Checked );
3827 emit changed();
3828}
3829
3830void QgsCentroidFillSymbolLayerWidget::mClipOnCurrentPartOnlyCheckBox_stateChanged( int state )
3831{
3832 mLayer->setClipOnCurrentPartOnly( state == Qt::Checked );
3833 emit changed();
3834}
3835
3837
3839 : QgsSymbolLayerWidget( parent, vl )
3840{
3841 mLayer = nullptr;
3842
3843 setupUi( this );
3844
3845 mHorizontalAnchorComboBox->addItem( tr( "Left" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Left ) );
3846 mHorizontalAnchorComboBox->addItem( tr( "Horizontal Center" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Center ) );
3847 mHorizontalAnchorComboBox->addItem( tr( "Right" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Right ) );
3848
3849 mVerticalAnchorComboBox->addItem( tr( "Top" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Top ) );
3850 mVerticalAnchorComboBox->addItem( tr( "Vertical Center" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Center ) );
3851 mVerticalAnchorComboBox->addItem( tr( "Bottom" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Bottom ) );
3852
3853 mImageSourceLineEdit->setLastPathSettingsKey( u"/UI/lastRasterMarkerImageDir"_s );
3854
3855 connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsRasterMarkerSymbolLayerWidget::imageSourceChanged );
3856 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
3857 connect( mRotationSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setAngle );
3858 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
3859 connect( mWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setWidth );
3860 connect( mHeightSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setHeight );
3861 connect( mLockAspectRatio, static_cast<void ( QgsRatioLockButton::* )( bool )>( &QgsRatioLockButton::lockChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setLockAspectRatio );
3862
3865
3866 mSpinOffsetX->setClearValue( 0.0 );
3867 mSpinOffsetY->setClearValue( 0.0 );
3868 mRotationSpinBox->setClearValue( 0.0 );
3869
3870 connect( mSpinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setOffset );
3871 connect( mSpinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setOffset );
3872 connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsRasterMarkerSymbolLayerWidget::setOpacity );
3873
3874 connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
3875 connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
3876}
3877
3879{
3880 if ( !layer )
3881 {
3882 return;
3883 }
3884
3885 if ( layer->layerType() != "RasterMarker"_L1 )
3886 return;
3887
3888 // layer type is correct, we can do the cast
3889 mLayer = static_cast<QgsRasterMarkerSymbolLayer *>( layer );
3890
3891 // set values
3892 whileBlocking( mImageSourceLineEdit )->setSource( mLayer->path() );
3893
3894 whileBlocking( mWidthSpinBox )->setValue( mLayer->size() );
3895 const bool preservedAspectRatio = mLayer->preservedAspectRatio();
3896 mHeightSpinBox->blockSignals( true );
3897 if ( preservedAspectRatio )
3898 {
3899 mHeightSpinBox->setValue( mLayer->size() );
3900 }
3901 else
3902 {
3903 mHeightSpinBox->setValue( mLayer->size() * mLayer->fixedAspectRatio() );
3904 }
3905 mHeightSpinBox->setEnabled( mLayer->defaultAspectRatio() > 0.0 );
3906 mHeightSpinBox->blockSignals( false );
3907 whileBlocking( mLockAspectRatio )->setLocked( preservedAspectRatio );
3908
3909 whileBlocking( mRotationSpinBox )->setValue( mLayer->angle() );
3910 whileBlocking( mOpacityWidget )->setOpacity( mLayer->opacity() );
3911
3912 whileBlocking( mSpinOffsetX )->setValue( mLayer->offset().x() );
3913 whileBlocking( mSpinOffsetY )->setValue( mLayer->offset().y() );
3914
3915 mSizeUnitWidget->blockSignals( true );
3916 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
3917 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
3918 mSizeUnitWidget->blockSignals( false );
3919 mOffsetUnitWidget->blockSignals( true );
3920 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
3921 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
3922 mOffsetUnitWidget->blockSignals( false );
3923
3924 //anchor points
3925 whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mHorizontalAnchorComboBox->findData( QVariant::fromValue( mLayer->horizontalAnchorPoint() ) ) );
3926 whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mVerticalAnchorComboBox->findData( QVariant::fromValue( mLayer->verticalAnchorPoint() ) ) );
3927
3936
3937 updatePreviewImage();
3938}
3939
3944
3946{
3948 mImageSourceLineEdit->setMessageBar( context.messageBar() );
3949}
3950
3951void QgsRasterMarkerSymbolLayerWidget::imageSourceChanged( const QString &text )
3952{
3953 mLayer->setPath( text );
3954 updatePreviewImage();
3955 emit changed();
3956}
3957
3958void QgsRasterMarkerSymbolLayerWidget::updatePreviewImage()
3959{
3960 bool fitsInCache = false;
3961 const QImage image = QgsApplication::imageCache()->pathAsImage( mLayer->path(), QSize( 150, 150 ), true, 1.0, fitsInCache );
3962 if ( image.isNull() )
3963 {
3964 mLabelImagePreview->setPixmap( QPixmap() );
3965 return;
3966 }
3967
3968 QImage previewImage( 150, 150, QImage::Format_ARGB32 );
3969 previewImage.fill( Qt::transparent );
3970 const QRect imageRect( ( 150 - image.width() ) / 2.0, ( 150 - image.height() ) / 2.0, image.width(), image.height() );
3971 QPainter p;
3972 p.begin( &previewImage );
3973 //draw a checkerboard background
3974 uchar pixDataRGB[] = { 150, 150, 150, 150, 100, 100, 100, 150, 100, 100, 100, 150, 150, 150, 150, 150 };
3975 const QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
3976 const QPixmap pix = QPixmap::fromImage( img.scaled( 8, 8 ) );
3977 QBrush checkerBrush;
3978 checkerBrush.setTexture( pix );
3979 p.fillRect( imageRect, checkerBrush );
3980
3981 if ( mLayer->opacity() < 1.0 )
3982 {
3983 p.setOpacity( mLayer->opacity() );
3984 }
3985
3986 p.drawImage( imageRect.left(), imageRect.top(), image );
3987 p.end();
3988 mLabelImagePreview->setPixmap( QPixmap::fromImage( previewImage ) );
3989}
3990
3991void QgsRasterMarkerSymbolLayerWidget::setWidth()
3992{
3993 const double defaultAspectRatio = mLayer->defaultAspectRatio();
3994 double fixedAspectRatio = 0.0;
3995 mHeightSpinBox->blockSignals( true );
3996 if ( defaultAspectRatio <= 0.0 )
3997 {
3998 mHeightSpinBox->setValue( mWidthSpinBox->value() );
3999 }
4000 else if ( mLockAspectRatio->locked() )
4001 {
4002 mHeightSpinBox->setValue( mWidthSpinBox->value() * defaultAspectRatio );
4003 }
4004 else
4005 {
4006 fixedAspectRatio = mHeightSpinBox->value() / mWidthSpinBox->value();
4007 }
4008 mHeightSpinBox->blockSignals( false );
4009 mLayer->setSize( mWidthSpinBox->value() );
4010 mLayer->setFixedAspectRatio( fixedAspectRatio );
4011 emit changed();
4012}
4013
4014void QgsRasterMarkerSymbolLayerWidget::setHeight()
4015{
4016 const double defaultAspectRatio = mLayer->defaultAspectRatio();
4017 double fixedAspectRatio = 0.0;
4018 mWidthSpinBox->blockSignals( true );
4019 if ( defaultAspectRatio <= 0.0 )
4020 {
4021 mWidthSpinBox->setValue( mHeightSpinBox->value() );
4022 }
4023 else if ( mLockAspectRatio->locked() )
4024 {
4025 mWidthSpinBox->setValue( mHeightSpinBox->value() / defaultAspectRatio );
4026 }
4027 else
4028 {
4029 fixedAspectRatio = mHeightSpinBox->value() / mWidthSpinBox->value();
4030 }
4031 mWidthSpinBox->blockSignals( false );
4032 mLayer->setSize( mWidthSpinBox->value() );
4033 mLayer->setFixedAspectRatio( fixedAspectRatio );
4034 emit changed();
4035}
4036
4037void QgsRasterMarkerSymbolLayerWidget::setLockAspectRatio( const bool locked )
4038{
4039 const double defaultAspectRatio = mLayer->defaultAspectRatio();
4040 if ( defaultAspectRatio <= 0.0 )
4041 {
4042 whileBlocking( mLockAspectRatio )->setLocked( true );
4043 }
4044 else if ( locked )
4045 {
4046 mLayer->setFixedAspectRatio( 0.0 );
4047 setWidth();
4048 }
4049 else
4050 {
4051 mLayer->setFixedAspectRatio( mHeightSpinBox->value() / mWidthSpinBox->value() );
4052 }
4053}
4054
4055void QgsRasterMarkerSymbolLayerWidget::setAngle()
4056{
4057 mLayer->setAngle( mRotationSpinBox->value() );
4058 emit changed();
4059}
4060
4061void QgsRasterMarkerSymbolLayerWidget::setOpacity( double value )
4062{
4063 mLayer->setOpacity( value );
4064 emit changed();
4065 updatePreviewImage();
4066}
4067
4068void QgsRasterMarkerSymbolLayerWidget::setOffset()
4069{
4070 mLayer->setOffset( QPointF( mSpinOffsetX->value(), mSpinOffsetY->value() ) );
4071 emit changed();
4072}
4073
4074void QgsRasterMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
4075{
4076 if ( mLayer )
4077 {
4078 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
4079 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
4080 emit changed();
4081 }
4082}
4083
4084void QgsRasterMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
4085{
4086 if ( mLayer )
4087 {
4088 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
4089 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
4090 emit changed();
4091 }
4092}
4093
4094void QgsRasterMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int )
4095{
4096 if ( mLayer )
4097 {
4098 mLayer->setHorizontalAnchorPoint( mHorizontalAnchorComboBox->currentData().value< Qgis::HorizontalAnchorPoint >() );
4099 emit changed();
4100 }
4101}
4102
4103void QgsRasterMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int )
4104{
4105 if ( mLayer )
4106 {
4107 mLayer->setVerticalAnchorPoint( mVerticalAnchorComboBox->currentData().value< Qgis::VerticalAnchorPoint >() );
4108 emit changed();
4109 }
4110}
4111
4112
4114
4116 : QgsSymbolLayerWidget( parent, vl )
4117{
4118 mLayer = nullptr;
4119
4120 setupUi( this );
4121
4122 mHorizontalAnchorComboBox->addItem( tr( "Left" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Left ) );
4123 mHorizontalAnchorComboBox->addItem( tr( "Horizontal Center" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Center ) );
4124 mHorizontalAnchorComboBox->addItem( tr( "Right" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Right ) );
4125
4126 mVerticalAnchorComboBox->addItem( tr( "Top" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Top ) );
4127 mVerticalAnchorComboBox->addItem( tr( "Vertical Center" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Center ) );
4128 mVerticalAnchorComboBox->addItem( tr( "Bottom" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Bottom ) );
4129
4130 mImageSourceLineEdit->setLastPathSettingsKey( u"/UI/lastAnimatedMarkerImageDir"_s );
4131
4132 connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsAnimatedMarkerSymbolLayerWidget::imageSourceChanged );
4133 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsAnimatedMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
4134 connect( mRotationSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::setAngle );
4135 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsAnimatedMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
4136 connect( mWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::setWidth );
4137 connect( mHeightSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::setHeight );
4138 connect( mLockAspectRatio, static_cast<void ( QgsRatioLockButton::* )( bool )>( &QgsRatioLockButton::lockChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::setLockAspectRatio );
4139
4140 mFrameRateSpin->setClearValue( 10 );
4141 mFrameRateSpin->setShowClearButton( true );
4142 connect( mFrameRateSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double value ) {
4143 mLayer->setFrameRate( value );
4144 emit changed();
4145 } );
4146
4149
4150 mSpinOffsetX->setClearValue( 0.0 );
4151 mSpinOffsetY->setClearValue( 0.0 );
4152 mRotationSpinBox->setClearValue( 0.0 );
4153
4154 connect( mSpinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::setOffset );
4155 connect( mSpinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::setOffset );
4156 connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsAnimatedMarkerSymbolLayerWidget::setOpacity );
4157
4158 connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
4159 connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
4160}
4161
4163{
4164 if ( !layer )
4165 {
4166 return;
4167 }
4168
4169 if ( layer->layerType() != "AnimatedMarker"_L1 )
4170 return;
4171
4172 // layer type is correct, we can do the cast
4173 mLayer = static_cast<QgsAnimatedMarkerSymbolLayer *>( layer );
4174
4175 // set values
4176 whileBlocking( mImageSourceLineEdit )->setSource( mLayer->path() );
4177
4178 const double firstFrameTime = QgsApplication::imageCache()->nextFrameDelay( mLayer->path() );
4179 if ( firstFrameTime > 0 )
4180 {
4181 mFrameRateSpin->setClearValue( 1000 / firstFrameTime );
4182 }
4183 else
4184 {
4185 mFrameRateSpin->setClearValue( 10 );
4186 }
4187
4188 whileBlocking( mWidthSpinBox )->setValue( mLayer->size() );
4189 const bool preservedAspectRatio = mLayer->preservedAspectRatio();
4190 mHeightSpinBox->blockSignals( true );
4191 if ( preservedAspectRatio )
4192 {
4193 mHeightSpinBox->setValue( mLayer->size() );
4194 }
4195 else
4196 {
4197 mHeightSpinBox->setValue( mLayer->size() * mLayer->fixedAspectRatio() );
4198 }
4199 mHeightSpinBox->setEnabled( mLayer->defaultAspectRatio() > 0.0 );
4200 mHeightSpinBox->blockSignals( false );
4201 whileBlocking( mLockAspectRatio )->setLocked( preservedAspectRatio );
4202
4203 whileBlocking( mRotationSpinBox )->setValue( mLayer->angle() );
4204 whileBlocking( mOpacityWidget )->setOpacity( mLayer->opacity() );
4205
4206 whileBlocking( mSpinOffsetX )->setValue( mLayer->offset().x() );
4207 whileBlocking( mSpinOffsetY )->setValue( mLayer->offset().y() );
4208
4209 whileBlocking( mFrameRateSpin )->setValue( mLayer->frameRate() );
4210
4211 mSizeUnitWidget->blockSignals( true );
4212 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
4213 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
4214 mSizeUnitWidget->blockSignals( false );
4215 mOffsetUnitWidget->blockSignals( true );
4216 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
4217 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
4218 mOffsetUnitWidget->blockSignals( false );
4219
4220 //anchor points
4221 whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mHorizontalAnchorComboBox->findData( QVariant::fromValue( mLayer->horizontalAnchorPoint() ) ) );
4222 whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mVerticalAnchorComboBox->findData( QVariant::fromValue( mLayer->verticalAnchorPoint() ) ) );
4223
4232
4233 updatePreviewImage();
4234}
4235
4240
4242{
4244 mImageSourceLineEdit->setMessageBar( context.messageBar() );
4245}
4246
4247void QgsAnimatedMarkerSymbolLayerWidget::imageSourceChanged( const QString &text )
4248{
4249 mLayer->setPath( text );
4250
4251 const double firstFrameTime = QgsApplication::imageCache()->nextFrameDelay( text );
4252 if ( firstFrameTime > 0 )
4253 {
4254 mFrameRateSpin->setClearValue( 1000 / firstFrameTime );
4255 }
4256 else
4257 {
4258 mFrameRateSpin->setClearValue( 10 );
4259 }
4260 updatePreviewImage();
4261 emit changed();
4262}
4263
4264void QgsAnimatedMarkerSymbolLayerWidget::updatePreviewImage()
4265{
4266 if ( mPreviewMovie )
4267 {
4268 mLabelImagePreview->setMovie( nullptr );
4269 mPreviewMovie->deleteLater();
4270 mPreviewMovie = nullptr;
4271 }
4272
4273 mPreviewMovie = new QMovie( mLayer->path(), QByteArray(), this );
4274 mPreviewMovie->setScaledSize( QSize( 150, 150 ) );
4275 mLabelImagePreview->setMovie( mPreviewMovie );
4276 mPreviewMovie->start();
4277}
4278
4279void QgsAnimatedMarkerSymbolLayerWidget::setWidth()
4280{
4281 const double defaultAspectRatio = mLayer->defaultAspectRatio();
4282 double fixedAspectRatio = 0.0;
4283 mHeightSpinBox->blockSignals( true );
4284 if ( defaultAspectRatio <= 0.0 )
4285 {
4286 mHeightSpinBox->setValue( mWidthSpinBox->value() );
4287 }
4288 else if ( mLockAspectRatio->locked() )
4289 {
4290 mHeightSpinBox->setValue( mWidthSpinBox->value() * defaultAspectRatio );
4291 }
4292 else
4293 {
4294 fixedAspectRatio = mHeightSpinBox->value() / mWidthSpinBox->value();
4295 }
4296 mHeightSpinBox->blockSignals( false );
4297 mLayer->setSize( mWidthSpinBox->value() );
4298 mLayer->setFixedAspectRatio( fixedAspectRatio );
4299 emit changed();
4300}
4301
4302void QgsAnimatedMarkerSymbolLayerWidget::setHeight()
4303{
4304 const double defaultAspectRatio = mLayer->defaultAspectRatio();
4305 double fixedAspectRatio = 0.0;
4306 mWidthSpinBox->blockSignals( true );
4307 if ( defaultAspectRatio <= 0.0 )
4308 {
4309 mWidthSpinBox->setValue( mHeightSpinBox->value() );
4310 }
4311 else if ( mLockAspectRatio->locked() )
4312 {
4313 mWidthSpinBox->setValue( mHeightSpinBox->value() / defaultAspectRatio );
4314 }
4315 else
4316 {
4317 fixedAspectRatio = mHeightSpinBox->value() / mWidthSpinBox->value();
4318 }
4319 mWidthSpinBox->blockSignals( false );
4320 mLayer->setSize( mWidthSpinBox->value() );
4321 mLayer->setFixedAspectRatio( fixedAspectRatio );
4322 emit changed();
4323}
4324
4325void QgsAnimatedMarkerSymbolLayerWidget::setLockAspectRatio( const bool locked )
4326{
4327 const double defaultAspectRatio = mLayer->defaultAspectRatio();
4328 if ( defaultAspectRatio <= 0.0 )
4329 {
4330 whileBlocking( mLockAspectRatio )->setLocked( true );
4331 }
4332 else if ( locked )
4333 {
4334 mLayer->setFixedAspectRatio( 0.0 );
4335 setWidth();
4336 }
4337 else
4338 {
4339 mLayer->setFixedAspectRatio( mHeightSpinBox->value() / mWidthSpinBox->value() );
4340 }
4341}
4342
4343void QgsAnimatedMarkerSymbolLayerWidget::setAngle()
4344{
4345 mLayer->setAngle( mRotationSpinBox->value() );
4346 emit changed();
4347}
4348
4349void QgsAnimatedMarkerSymbolLayerWidget::setOpacity( double value )
4350{
4351 mLayer->setOpacity( value );
4352 emit changed();
4353 updatePreviewImage();
4354}
4355
4356void QgsAnimatedMarkerSymbolLayerWidget::setOffset()
4357{
4358 mLayer->setOffset( QPointF( mSpinOffsetX->value(), mSpinOffsetY->value() ) );
4359 emit changed();
4360}
4361
4362void QgsAnimatedMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
4363{
4364 if ( mLayer )
4365 {
4366 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
4367 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
4368 emit changed();
4369 }
4370}
4371
4372void QgsAnimatedMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
4373{
4374 if ( mLayer )
4375 {
4376 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
4377 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
4378 emit changed();
4379 }
4380}
4381
4382void QgsAnimatedMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int )
4383{
4384 if ( mLayer )
4385 {
4386 mLayer->setHorizontalAnchorPoint( mHorizontalAnchorComboBox->currentData().value< Qgis::HorizontalAnchorPoint >() );
4387 emit changed();
4388 }
4389}
4390
4391void QgsAnimatedMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int )
4392{
4393 if ( mLayer )
4394 {
4395 mLayer->setVerticalAnchorPoint( mVerticalAnchorComboBox->currentData().value< Qgis::VerticalAnchorPoint >() );
4396 emit changed();
4397 }
4398}
4399
4401
4403 : QgsSymbolLayerWidget( parent, vl )
4404{
4405 mLayer = nullptr;
4406 setupUi( this );
4407
4408 mImageSourceLineEdit->setLastPathSettingsKey( u"/UI/lastRasterMarkerImageDir"_s );
4409 connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsRasterFillSymbolLayerWidget::imageSourceChanged );
4410
4411 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterFillSymbolLayerWidget::mOffsetUnitWidget_changed );
4412 connect( mRotationSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::mRotationSpinBox_valueChanged );
4413
4414 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
4415 if ( !mLayer )
4416 {
4417 return;
4418 }
4419 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
4420 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
4421 emit changed();
4422 } );
4423 connect( mWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, [this]( double d ) {
4424 if ( !mLayer )
4425 {
4426 return;
4427 }
4428 mLayer->setWidth( d );
4429 emit changed();
4430 } );
4431
4432 connect( mHeightSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, [this]( double d ) {
4433 if ( !mLayer )
4434 {
4435 return;
4436 }
4437 mLayer->setHeight( d );
4438 emit changed();
4439 } );
4440
4443
4444 mSpinOffsetX->setClearValue( 0.0 );
4445 mSpinOffsetY->setClearValue( 0.0 );
4446 mRotationSpinBox->setClearValue( 0.0 );
4447
4448 connect( cboCoordinateMode, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterFillSymbolLayerWidget::setCoordinateMode );
4449 connect( mSpinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::offsetChanged );
4450 connect( mSpinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::offsetChanged );
4451 connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsRasterFillSymbolLayerWidget::opacityChanged );
4452}
4453
4454
4456{
4457 if ( !layer )
4458 {
4459 return;
4460 }
4461
4462 if ( layer->layerType() != "RasterFill"_L1 )
4463 {
4464 return;
4465 }
4466
4467 mLayer = dynamic_cast<QgsRasterFillSymbolLayer *>( layer );
4468 if ( !mLayer )
4469 {
4470 return;
4471 }
4472
4473 whileBlocking( mImageSourceLineEdit )->setSource( mLayer->imageFilePath() );
4474
4475 cboCoordinateMode->blockSignals( true );
4476 switch ( mLayer->coordinateMode() )
4477 {
4479 cboCoordinateMode->setCurrentIndex( 1 );
4480 break;
4482 default:
4483 cboCoordinateMode->setCurrentIndex( 0 );
4484 break;
4485 }
4486 cboCoordinateMode->blockSignals( false );
4487 whileBlocking( mOpacityWidget )->setOpacity( mLayer->opacity() );
4488 whileBlocking( mRotationSpinBox )->setValue( mLayer->angle() );
4489
4490 whileBlocking( mSpinOffsetX )->setValue( mLayer->offset().x() );
4491 whileBlocking( mSpinOffsetY )->setValue( mLayer->offset().y() );
4492 mOffsetUnitWidget->blockSignals( true );
4493 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
4494 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
4495 mOffsetUnitWidget->blockSignals( false );
4496
4497 whileBlocking( mWidthSpinBox )->setValue( mLayer->width() );
4498 mSizeUnitWidget->blockSignals( true );
4499 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
4500 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
4501 mSizeUnitWidget->blockSignals( false );
4502
4503 whileBlocking( mHeightSpinBox )->setValue( mLayer->height() );
4504
4505 updatePreviewImage();
4506
4513}
4514
4519
4520void QgsRasterFillSymbolLayerWidget::imageSourceChanged( const QString &text )
4521{
4522 mLayer->setImageFilePath( text );
4523 updatePreviewImage();
4524 emit changed();
4525}
4526
4527void QgsRasterFillSymbolLayerWidget::setCoordinateMode( int index )
4528{
4529 switch ( index )
4530 {
4531 case 0:
4532 //feature coordinate mode
4534 break;
4535 case 1:
4536 //viewport coordinate mode
4538 break;
4539 }
4540
4541 emit changed();
4542}
4543
4544void QgsRasterFillSymbolLayerWidget::opacityChanged( double value )
4545{
4546 if ( !mLayer )
4547 {
4548 return;
4549 }
4550
4551 mLayer->setOpacity( value );
4552 emit changed();
4553 updatePreviewImage();
4554}
4555
4556void QgsRasterFillSymbolLayerWidget::offsetChanged()
4557{
4558 mLayer->setOffset( QPointF( mSpinOffsetX->value(), mSpinOffsetY->value() ) );
4559 emit changed();
4560}
4561
4562void QgsRasterFillSymbolLayerWidget::mOffsetUnitWidget_changed()
4563{
4564 if ( !mLayer )
4565 {
4566 return;
4567 }
4568 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
4569 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
4570 emit changed();
4571}
4572
4573void QgsRasterFillSymbolLayerWidget::mRotationSpinBox_valueChanged( double d )
4574{
4575 if ( mLayer )
4576 {
4577 mLayer->setAngle( d );
4578 emit changed();
4579 }
4580}
4581
4582void QgsRasterFillSymbolLayerWidget::updatePreviewImage()
4583{
4584 bool fitsInCache = false;
4585 const QImage image = QgsApplication::imageCache()->pathAsImage( mLayer->imageFilePath(), QSize( 150, 150 ), true, 1.0, fitsInCache );
4586 if ( image.isNull() )
4587 {
4588 mLabelImagePreview->setPixmap( QPixmap() );
4589 return;
4590 }
4591
4592 QImage previewImage( 150, 150, QImage::Format_ARGB32 );
4593 previewImage.fill( Qt::transparent );
4594 const QRect imageRect( ( 150 - image.width() ) / 2.0, ( 150 - image.height() ) / 2.0, image.width(), image.height() );
4595 QPainter p;
4596 p.begin( &previewImage );
4597 //draw a checkerboard background
4598 uchar pixDataRGB[] = { 150, 150, 150, 150, 100, 100, 100, 150, 100, 100, 100, 150, 150, 150, 150, 150 };
4599 const QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
4600 const QPixmap pix = QPixmap::fromImage( img.scaled( 8, 8 ) );
4601 QBrush checkerBrush;
4602 checkerBrush.setTexture( pix );
4603 p.fillRect( imageRect, checkerBrush );
4604
4605 if ( mLayer->opacity() < 1.0 )
4606 {
4607 p.setOpacity( mLayer->opacity() );
4608 }
4609
4610 p.drawImage( imageRect.left(), imageRect.top(), image );
4611 p.end();
4612 mLabelImagePreview->setPixmap( QPixmap::fromImage( previewImage ) );
4613}
4614
4615//
4616// QgsRasterLineSymbolLayerWidget
4617//
4618
4619
4621 : QgsSymbolLayerWidget( parent, vl )
4622{
4623 mLayer = nullptr;
4624 setupUi( this );
4625
4626 mImageSourceLineEdit->setLastPathSettingsKey( u"/UI/lastRasterMarkerImageDir"_s );
4627
4630
4631 connect( mPenWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
4632 if ( mLayer )
4633 {
4634 mLayer->setWidthUnit( mPenWidthUnitWidget->unit() );
4635 mLayer->setWidthMapUnitScale( mPenWidthUnitWidget->getMapUnitScale() );
4636 emit changed();
4637 }
4638 } );
4639
4640 connect( spinWidth, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this] {
4641 if ( mLayer )
4642 {
4643 mLayer->setWidth( spinWidth->value() );
4644 emit changed();
4645 }
4646 } );
4647
4648 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
4649 if ( mLayer )
4650 {
4651 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
4652 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
4653 emit changed();
4654 }
4655 } );
4656
4657
4658 spinOffset->setClearValue( 0.0 );
4659 connect( spinOffset, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double val ) {
4660 if ( mLayer )
4661 {
4662 mLayer->setOffset( val );
4663 emit changed();
4664 }
4665 } );
4666
4667 connect( cboCapStyle, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this] {
4668 if ( mLayer )
4669 {
4670 mLayer->setPenCapStyle( cboCapStyle->penCapStyle() );
4671 emit changed();
4672 }
4673 } );
4674 connect( cboJoinStyle, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this] {
4675 if ( mLayer )
4676 {
4677 mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
4678 emit changed();
4679 }
4680 } );
4681
4682 connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsRasterLineSymbolLayerWidget::imageSourceChanged );
4683 connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, [this]( double opacity ) {
4684 if ( mLayer )
4685 {
4686 mLayer->setOpacity( opacity );
4687 updatePreviewImage();
4688 emit changed();
4689 }
4690 } );
4691}
4692
4694{
4695 if ( !layer )
4696 {
4697 return;
4698 }
4699
4700 if ( layer->layerType() != "RasterLine"_L1 )
4701 {
4702 return;
4703 }
4704
4705 mLayer = dynamic_cast<QgsRasterLineSymbolLayer *>( layer );
4706 if ( !mLayer )
4707 {
4708 return;
4709 }
4710
4711 whileBlocking( mImageSourceLineEdit )->setSource( mLayer->path() );
4712 whileBlocking( mOpacityWidget )->setOpacity( mLayer->opacity() );
4713
4714 whileBlocking( spinWidth )->setValue( mLayer->width() );
4715 whileBlocking( mPenWidthUnitWidget )->setUnit( mLayer->widthUnit() );
4716 whileBlocking( mPenWidthUnitWidget )->setMapUnitScale( mLayer->widthMapUnitScale() );
4717 whileBlocking( cboJoinStyle )->setPenJoinStyle( mLayer->penJoinStyle() );
4718 whileBlocking( cboCapStyle )->setPenCapStyle( mLayer->penCapStyle() );
4719
4720 whileBlocking( mOffsetUnitWidget )->setUnit( mLayer->offsetUnit() );
4721 whileBlocking( mOffsetUnitWidget )->setMapUnitScale( mLayer->offsetMapUnitScale() );
4722 whileBlocking( spinOffset )->setValue( mLayer->offset() );
4723
4724 updatePreviewImage();
4725
4732}
4733
4738
4739void QgsRasterLineSymbolLayerWidget::imageSourceChanged( const QString &text )
4740{
4741 mLayer->setPath( text );
4742 updatePreviewImage();
4743 emit changed();
4744}
4745
4746void QgsRasterLineSymbolLayerWidget::updatePreviewImage()
4747{
4748 bool fitsInCache = false;
4749 const QImage image = QgsApplication::imageCache()->pathAsImage( mLayer->path(), QSize( 150, 150 ), true, 1.0, fitsInCache );
4750 if ( image.isNull() )
4751 {
4752 mLabelImagePreview->setPixmap( QPixmap() );
4753 return;
4754 }
4755
4756 QImage previewImage( 150, 150, QImage::Format_ARGB32 );
4757 previewImage.fill( Qt::transparent );
4758 const QRect imageRect( ( 150 - image.width() ) / 2.0, ( 150 - image.height() ) / 2.0, image.width(), image.height() );
4759 QPainter p;
4760 p.begin( &previewImage );
4761 //draw a checkerboard background
4762 uchar pixDataRGB[] = { 150, 150, 150, 150, 100, 100, 100, 150, 100, 100, 100, 150, 150, 150, 150, 150 };
4763 const QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
4764 const QPixmap pix = QPixmap::fromImage( img.scaled( 8, 8 ) );
4765 QBrush checkerBrush;
4766 checkerBrush.setTexture( pix );
4767 p.fillRect( imageRect, checkerBrush );
4768
4769 if ( mLayer->opacity() < 1.0 )
4770 {
4771 p.setOpacity( mLayer->opacity() );
4772 }
4773
4774 p.drawImage( imageRect.left(), imageRect.top(), image );
4775 p.end();
4776 mLabelImagePreview->setPixmap( QPixmap::fromImage( previewImage ) );
4777}
4778
4779
4780//
4781// QgsGeometryGeneratorSymbolLayerWidget
4782//
4783
4785 : QgsSymbolLayerWidget( parent, vl )
4786
4787{
4788 setupUi( this );
4789 modificationExpressionSelector->setMultiLine( true );
4790 modificationExpressionSelector->setLayer( const_cast<QgsVectorLayer *>( vl ) );
4791 modificationExpressionSelector->registerExpressionContextGenerator( this );
4792 cbxGeometryType->addItem( QgsIconUtils::iconPolygon(), tr( "Polygon / MultiPolygon" ), static_cast<int>( Qgis::SymbolType::Fill ) );
4793 cbxGeometryType->addItem( QgsIconUtils::iconLine(), tr( "LineString / MultiLineString" ), static_cast<int>( Qgis::SymbolType::Line ) );
4794 cbxGeometryType->addItem( QgsIconUtils::iconPoint(), tr( "Point / MultiPoint" ), static_cast<int>( Qgis::SymbolType::Marker ) );
4795
4797 mUnitWidget->setShowMapScaleButton( false );
4798
4799 connect( modificationExpressionSelector, &QgsExpressionLineEdit::expressionChanged, this, &QgsGeometryGeneratorSymbolLayerWidget::updateExpression );
4800 connect( cbxGeometryType, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGeometryGeneratorSymbolLayerWidget::updateSymbolType );
4801 connect( mUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
4802 if ( !mBlockSignals )
4803 {
4804 mLayer->setUnits( mUnitWidget->unit() );
4805 emit symbolChanged();
4806 }
4807 } );
4808}
4809
4811{
4812 mBlockSignals++;
4813 mLayer = static_cast<QgsGeometryGeneratorSymbolLayer *>( l );
4814 modificationExpressionSelector->setExpression( mLayer->geometryExpression() );
4815 cbxGeometryType->setCurrentIndex( cbxGeometryType->findData( static_cast<int>( mLayer->symbolType() ) ) );
4816 mUnitWidget->setUnit( mLayer->units() );
4817 mBlockSignals--;
4818}
4819
4824
4825void QgsGeometryGeneratorSymbolLayerWidget::updateExpression( const QString &string )
4826{
4827 mLayer->setGeometryExpression( string );
4828
4829 emit changed();
4830}
4831
4832void QgsGeometryGeneratorSymbolLayerWidget::updateSymbolType()
4833{
4834 // we try to keep the subsymbol, if we can!
4835 std::unique_ptr<QgsSymbol> subSymbol( mLayer->subSymbol()->clone() );
4836
4837 mLayer->setSymbolType( static_cast<Qgis::SymbolType>( cbxGeometryType->currentData().toInt() ) );
4838
4839 switch ( mLayer->symbolType() )
4840 {
4843 break;
4845 {
4846 if ( subSymbol->type() == Qgis::SymbolType::Fill )
4847 {
4848 // going from fill -> line type, so we can copy any LINE symbol layers across
4849 QgsSymbolLayerList layers;
4850 for ( int i = 0; i < subSymbol->symbolLayerCount(); ++i )
4851 {
4852 if ( dynamic_cast<const QgsLineSymbolLayer *>( subSymbol->symbolLayer( i ) ) )
4853 layers << subSymbol->symbolLayer( i )->clone();
4854 }
4855
4856 if ( !layers.empty() )
4857 mLayer->setSubSymbol( new QgsLineSymbol( layers ) );
4858 }
4859 break;
4860 }
4862 if ( subSymbol->type() == Qgis::SymbolType::Line )
4863 {
4864 // going from line -> fill type, so copy ALL line symbol layers across
4865 QgsSymbolLayerList layers;
4866 for ( int i = 0; i < subSymbol->symbolLayerCount(); ++i )
4867 layers << subSymbol->symbolLayer( i )->clone();
4868 mLayer->setSubSymbol( new QgsFillSymbol( layers ) );
4869 }
4870 break;
4871 }
4872
4873 emit symbolChanged();
4874}
4875
4876//
4877// QgsRandomMarkerFillSymbolLayerWidget
4878//
4879
4880
4882 : QgsSymbolLayerWidget( parent, vl )
4883{
4884 setupUi( this );
4885
4886 mCountMethodComboBox->addItem( tr( "Absolute Count" ), static_cast<int>( Qgis::PointCountMethod::Absolute ) );
4887 mCountMethodComboBox->addItem( tr( "Density-based Count" ), static_cast<int>( Qgis::PointCountMethod::DensityBased ) );
4888
4889 mPointCountSpinBox->setShowClearButton( true );
4890 mPointCountSpinBox->setClearValue( 100 );
4891 mSeedSpinBox->setShowClearButton( true );
4892 mSeedSpinBox->setClearValue( 0 );
4893
4894 connect( mCountMethodComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRandomMarkerFillSymbolLayerWidget::countMethodChanged );
4895 connect( mPointCountSpinBox, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ), this, &QgsRandomMarkerFillSymbolLayerWidget::countChanged );
4896 connect( mDensityAreaSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRandomMarkerFillSymbolLayerWidget::densityAreaChanged );
4897 connect( mSeedSpinBox, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ), this, &QgsRandomMarkerFillSymbolLayerWidget::seedChanged );
4898 connect( mClipPointsCheckBox, &QCheckBox::toggled, this, [this]( bool checked ) {
4899 if ( mLayer )
4900 {
4901 mLayer->setClipPoints( checked );
4902 emit changed();
4903 }
4904 } );
4905
4907
4908 connect( mDensityAreaUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRandomMarkerFillSymbolLayerWidget::densityAreaUnitChanged );
4909}
4910
4912{
4913 if ( !layer || layer->layerType() != "RandomMarkerFill"_L1 )
4914 {
4915 return;
4916 }
4917
4918 mLayer = static_cast<QgsRandomMarkerFillSymbolLayer *>( layer );
4919 whileBlocking( mPointCountSpinBox )->setValue( mLayer->pointCount() );
4920 whileBlocking( mSeedSpinBox )->setValue( mLayer->seed() );
4921 whileBlocking( mClipPointsCheckBox )->setChecked( mLayer->clipPoints() );
4922
4923 bool showDensityBasedCountWidgets = false;
4924 switch ( mLayer->countMethod() )
4925 {
4927 showDensityBasedCountWidgets = true;
4928 break;
4930 break;
4931 }
4932 mDensityAreaLabel->setVisible( showDensityBasedCountWidgets );
4933 mDensityAreaSpinBox->setVisible( showDensityBasedCountWidgets );
4934 mDensityAreaUnitWidget->setVisible( showDensityBasedCountWidgets );
4935 mDensityAreaDdbtn->setVisible( showDensityBasedCountWidgets );
4936
4937 whileBlocking( mCountMethodComboBox )->setCurrentIndex( mCountMethodComboBox->findData( static_cast<int>( mLayer->countMethod() ) ) );
4938 whileBlocking( mDensityAreaSpinBox )->setValue( mLayer->densityArea() );
4939 mDensityAreaUnitWidget->blockSignals( true );
4940 mDensityAreaUnitWidget->setUnit( mLayer->densityAreaUnit() );
4941 mDensityAreaUnitWidget->setMapUnitScale( mLayer->densityAreaUnitScale() );
4942 mDensityAreaUnitWidget->blockSignals( false );
4943
4948}
4949
4954
4955void QgsRandomMarkerFillSymbolLayerWidget::countMethodChanged( int )
4956{
4957 bool showDensityBasedCountWidgets = false;
4958 switch ( static_cast<Qgis::PointCountMethod>( mCountMethodComboBox->currentData().toInt() ) )
4959 {
4961 showDensityBasedCountWidgets = true;
4962 break;
4964 break;
4965 }
4966 mDensityAreaLabel->setVisible( showDensityBasedCountWidgets );
4967 mDensityAreaSpinBox->setVisible( showDensityBasedCountWidgets );
4968 mDensityAreaUnitWidget->setVisible( showDensityBasedCountWidgets );
4969 mDensityAreaDdbtn->setVisible( showDensityBasedCountWidgets );
4970
4971 if ( mLayer )
4972 {
4973 mLayer->setCountMethod( static_cast<Qgis::PointCountMethod>( mCountMethodComboBox->currentData().toInt() ) );
4974 emit changed();
4975 }
4976}
4977
4978void QgsRandomMarkerFillSymbolLayerWidget::countChanged( int d )
4979{
4980 if ( mLayer )
4981 {
4982 mLayer->setPointCount( d );
4983 emit changed();
4984 }
4985}
4986
4987void QgsRandomMarkerFillSymbolLayerWidget::densityAreaChanged( double d )
4988{
4989 if ( mLayer )
4990 {
4991 mLayer->setDensityArea( d );
4992 emit changed();
4993 }
4994}
4995
4996void QgsRandomMarkerFillSymbolLayerWidget::densityAreaUnitChanged()
4997{
4998 if ( mLayer )
4999 {
5000 mLayer->setDensityAreaUnit( mDensityAreaUnitWidget->unit() );
5001 mLayer->setDensityAreaUnitScale( mDensityAreaUnitWidget->getMapUnitScale() );
5002 emit changed();
5003 }
5004}
5005
5006void QgsRandomMarkerFillSymbolLayerWidget::seedChanged( int d )
5007{
5008 if ( mLayer )
5009 {
5010 mLayer->setSeed( d );
5011 emit changed();
5012 }
5013}
5014
5015//
5016// QgsGradientLineSymbolLayerWidget
5017//
5018
5020 : QgsSymbolLayerWidget( parent, vl )
5021{
5022 mLayer = nullptr;
5023 setupUi( this );
5024
5025 btnColorRamp->setShowGradientOnly( true );
5026
5027 btnChangeColor->setAllowOpacity( true );
5028 btnChangeColor->setColorDialogTitle( tr( "Select Gradient Color" ) );
5029 btnChangeColor->setContext( u"symbology"_s );
5030 btnChangeColor->setShowNoColor( true );
5031 btnChangeColor->setNoColorString( tr( "Transparent" ) );
5032 btnChangeColor2->setAllowOpacity( true );
5033 btnChangeColor2->setColorDialogTitle( tr( "Select Gradient Color" ) );
5034 btnChangeColor2->setContext( u"symbology"_s );
5035 btnChangeColor2->setShowNoColor( true );
5036 btnChangeColor2->setNoColorString( tr( "Transparent" ) );
5037
5038 mStartColorDDBtn->registerLinkedWidget( btnChangeColor );
5039 mEndColorDDBtn->registerLinkedWidget( btnChangeColor2 );
5040
5041 connect( btnChangeColor, &QgsColorButton::colorChanged, this, [this]( const QColor &color ) {
5042 if ( mLayer )
5043 {
5044 mLayer->setColor( color );
5045 emit changed();
5046 }
5047 } );
5048 connect( btnChangeColor2, &QgsColorButton::colorChanged, this, [this]( const QColor &color ) {
5049 if ( mLayer )
5050 {
5051 mLayer->setColor2( color );
5052 emit changed();
5053 }
5054 } );
5055 connect( btnColorRamp, &QgsColorRampButton::colorRampChanged, this, [this] {
5056 if ( btnColorRamp->isNull() )
5057 return;
5058
5059 if ( mLayer )
5060 {
5061 mLayer->setColorRamp( btnColorRamp->colorRamp()->clone() );
5062 emit changed();
5063 }
5064 } );
5065
5066 connect( radioTwoColor, &QAbstractButton::toggled, this, [this] {
5067 if ( mLayer )
5068 {
5069 if ( radioTwoColor->isChecked() )
5070 {
5071 mLayer->setGradientColorType( Qgis::GradientColorSource::SimpleTwoColor );
5072 btnChangeColor->setEnabled( true );
5073 btnChangeColor2->setEnabled( true );
5074 btnColorRamp->setEnabled( false );
5075 }
5076 else
5077 {
5078 mLayer->setGradientColorType( Qgis::GradientColorSource::ColorRamp );
5079 btnColorRamp->setEnabled( true );
5080 btnChangeColor->setEnabled( false );
5081 btnChangeColor2->setEnabled( false );
5082 }
5083 emit changed();
5084 }
5085 } );
5086
5089
5090 connect( mPenWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
5091 if ( mLayer )
5092 {
5093 mLayer->setWidthUnit( mPenWidthUnitWidget->unit() );
5094 mLayer->setWidthMapUnitScale( mPenWidthUnitWidget->getMapUnitScale() );
5095 emit changed();
5096 }
5097 } );
5098
5099 connect( spinWidth, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, [this] {
5100 if ( mLayer )
5101 {
5102 mLayer->setWidth( spinWidth->value() );
5103 emit changed();
5104 }
5105 } );
5106
5107 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
5108 if ( mLayer )
5109 {
5110 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
5111 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
5112 emit changed();
5113 }
5114 } );
5115
5116 spinOffset->setClearValue( 0.0 );
5117 connect( spinOffset, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double val ) {
5118 if ( mLayer )
5119 {
5120 mLayer->setOffset( val );
5121 emit changed();
5122 }
5123 } );
5124
5125 connect( cboCapStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [this] {
5126 if ( mLayer )
5127 {
5128 mLayer->setPenCapStyle( cboCapStyle->penCapStyle() );
5129 emit changed();
5130 }
5131 } );
5132 connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [this] {
5133 if ( mLayer )
5134 {
5135 mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
5136 emit changed();
5137 }
5138 } );
5139}
5140
5142{
5143 if ( !layer )
5144 {
5145 return;
5146 }
5147
5148 if ( layer->layerType() != "Lineburst"_L1 )
5149 {
5150 return;
5151 }
5152
5153 mLayer = dynamic_cast<QgsLineburstSymbolLayer *>( layer );
5154 if ( !mLayer )
5155 {
5156 return;
5157 }
5158
5159 btnChangeColor->blockSignals( true );
5160 btnChangeColor->setColor( mLayer->color() );
5161 btnChangeColor->blockSignals( false );
5162 btnChangeColor2->blockSignals( true );
5163 btnChangeColor2->setColor( mLayer->color2() );
5164 btnChangeColor2->blockSignals( false );
5165
5166 if ( mLayer->gradientColorType() == Qgis::GradientColorSource::SimpleTwoColor )
5167 {
5168 radioTwoColor->setChecked( true );
5169 btnColorRamp->setEnabled( false );
5170 }
5171 else
5172 {
5173 radioColorRamp->setChecked( true );
5174 btnChangeColor->setEnabled( false );
5175 btnChangeColor2->setEnabled( false );
5176 }
5177
5178 // set source color ramp
5179 if ( mLayer->colorRamp() )
5180 {
5181 btnColorRamp->blockSignals( true );
5182 btnColorRamp->setColorRamp( mLayer->colorRamp() );
5183 btnColorRamp->blockSignals( false );
5184 }
5185
5186 whileBlocking( spinWidth )->setValue( mLayer->width() );
5187 whileBlocking( mPenWidthUnitWidget )->setUnit( mLayer->widthUnit() );
5188 whileBlocking( mPenWidthUnitWidget )->setMapUnitScale( mLayer->widthMapUnitScale() );
5189
5190 whileBlocking( mOffsetUnitWidget )->setUnit( mLayer->offsetUnit() );
5191 whileBlocking( mOffsetUnitWidget )->setMapUnitScale( mLayer->offsetMapUnitScale() );
5192 whileBlocking( spinOffset )->setValue( mLayer->offset() );
5193
5194 whileBlocking( cboJoinStyle )->setPenJoinStyle( mLayer->penJoinStyle() );
5195 whileBlocking( cboCapStyle )->setPenCapStyle( mLayer->penCapStyle() );
5196
5203}
5204
5209
5210//
5211// QgsFilledLineSymbolLayerWidget
5212//
5213
5215 : QgsSymbolLayerWidget( parent, vl )
5216{
5217 mLayer = nullptr;
5218 setupUi( this );
5219
5222
5223 connect( mPenWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
5224 if ( mLayer )
5225 {
5226 mLayer->setWidthUnit( mPenWidthUnitWidget->unit() );
5227 mLayer->setWidthMapUnitScale( mPenWidthUnitWidget->getMapUnitScale() );
5228 emit changed();
5229 }
5230 } );
5231
5232 connect( spinWidth, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, [this] {
5233 if ( mLayer )
5234 {
5235 mLayer->setWidth( spinWidth->value() );
5236 emit changed();
5237 }
5238 } );
5239
5240 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
5241 if ( mLayer )
5242 {
5243 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
5244 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
5245 emit changed();
5246 }
5247 } );
5248
5249 spinOffset->setClearValue( 0.0 );
5250 connect( spinOffset, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double val ) {
5251 if ( mLayer )
5252 {
5253 mLayer->setOffset( val );
5254 emit changed();
5255 }
5256 } );
5257
5258 connect( cboCapStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [this] {
5259 if ( mLayer )
5260 {
5261 mLayer->setPenCapStyle( cboCapStyle->penCapStyle() );
5262 emit changed();
5263 }
5264 } );
5265 connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [this] {
5266 if ( mLayer )
5267 {
5268 mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
5269 emit changed();
5270 }
5271 } );
5272}
5273
5275
5277{
5278 if ( !layer )
5279 {
5280 return;
5281 }
5282
5283 if ( layer->layerType() != "FilledLine"_L1 )
5284 {
5285 return;
5286 }
5287
5288 mLayer = dynamic_cast<QgsFilledLineSymbolLayer *>( layer );
5289 if ( !mLayer )
5290 {
5291 return;
5292 }
5293
5294 whileBlocking( spinWidth )->setValue( mLayer->width() );
5295 whileBlocking( mPenWidthUnitWidget )->setUnit( mLayer->widthUnit() );
5296 whileBlocking( mPenWidthUnitWidget )->setMapUnitScale( mLayer->widthMapUnitScale() );
5297
5298 whileBlocking( mOffsetUnitWidget )->setUnit( mLayer->offsetUnit() );
5299 whileBlocking( mOffsetUnitWidget )->setMapUnitScale( mLayer->offsetMapUnitScale() );
5300 whileBlocking( spinOffset )->setValue( mLayer->offset() );
5301
5302 whileBlocking( cboJoinStyle )->setPenJoinStyle( mLayer->penJoinStyle() );
5303 whileBlocking( cboCapStyle )->setPenCapStyle( mLayer->penCapStyle() );
5304
5309}
5310
5315
5316//
5317// QgsLinearReferencingSymbolLayerWidget
5318//
5319
5321 : QgsSymbolLayerWidget( parent, vl )
5322{
5323 mLayer = nullptr;
5324
5325 setupUi( this );
5326
5327 mComboPlacement->addItem( tr( "Interval (Cartesian 2D Distances)" ), QVariant::fromValue( Qgis::LinearReferencingPlacement::IntervalCartesian2D ) );
5328 mComboPlacement->addItem( tr( "Interval (Z Values)" ), QVariant::fromValue( Qgis::LinearReferencingPlacement::IntervalZ ) );
5329 mComboPlacement->addItem( tr( "Interval (M Values)" ), QVariant::fromValue( Qgis::LinearReferencingPlacement::IntervalM ) );
5330 mComboPlacement->addItem( tr( "On Every Vertex" ), QVariant::fromValue( Qgis::LinearReferencingPlacement::Vertex ) );
5331
5332 mComboQuantity->addItem( tr( "Cartesian 2D Distance" ), QVariant::fromValue( Qgis::LinearReferencingLabelSource::CartesianDistance2D ) );
5333 mComboQuantity->addItem( tr( "Z Values" ), QVariant::fromValue( Qgis::LinearReferencingLabelSource::Z ) );
5334 mComboQuantity->addItem( tr( "M Values" ), QVariant::fromValue( Qgis::LinearReferencingLabelSource::M ) );
5335
5336 mSpinSkipMultiples->setClearValue( 0, tr( "Not set" ) );
5337 mSpinLabelOffsetX->setClearValue( 0 );
5338 mSpinLabelOffsetY->setClearValue( 0 );
5339 mSpinAverageAngleLength->setClearValue( 4.0 );
5342
5343 connect( mComboQuantity, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this] {
5344 if ( mLayer && !mBlockChangesSignal )
5345 {
5346 mLayer->setLabelSource( mComboQuantity->currentData().value<Qgis::LinearReferencingLabelSource>() );
5347 emit changed();
5348 }
5349 } );
5350 connect( mTextFormatButton, &QgsFontButton::changed, this, [this] {
5351 if ( mLayer && !mBlockChangesSignal )
5352 {
5353 mLayer->setTextFormat( mTextFormatButton->textFormat() );
5354 emit changed();
5355 }
5356 } );
5357 connect( spinInterval, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, [this] {
5358 if ( mLayer && !mBlockChangesSignal )
5359 {
5360 mLayer->setInterval( spinInterval->value() );
5361 emit changed();
5362 }
5363 } );
5364 connect( mSpinSkipMultiples, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, [this] {
5365 if ( mLayer && !mBlockChangesSignal )
5366 {
5367 mLayer->setSkipMultiplesOf( mSpinSkipMultiples->value() );
5368 emit changed();
5369 }
5370 } );
5371 connect( mCheckRotate, &QCheckBox::toggled, this, [this]( bool checked ) {
5372 if ( mLayer && !mBlockChangesSignal )
5373 {
5374 mLayer->setRotateLabels( checked );
5375 emit changed();
5376 }
5377 mSpinAverageAngleLength->setEnabled( checked );
5378 mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
5379 } );
5380 connect( mCheckShowMarker, &QCheckBox::toggled, this, [this]( bool checked ) {
5381 if ( mLayer && !mBlockChangesSignal )
5382 {
5383 mLayer->setShowMarker( checked );
5384 emit symbolChanged();
5385 }
5386 } );
5387
5388 connect( mSpinLabelOffsetX, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, [this] {
5389 if ( mLayer && !mBlockChangesSignal )
5390 {
5391 mLayer->setLabelOffset( QPointF( mSpinLabelOffsetX->value(), mSpinLabelOffsetY->value() ) );
5392 emit changed();
5393 }
5394 } );
5395 connect( mSpinLabelOffsetY, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, [this] {
5396 if ( mLayer && !mBlockChangesSignal )
5397 {
5398 mLayer->setLabelOffset( QPointF( mSpinLabelOffsetX->value(), mSpinLabelOffsetY->value() ) );
5399 emit changed();
5400 }
5401 } );
5402 connect( mLabelOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
5403 if ( mLayer && !mBlockChangesSignal )
5404 {
5405 mLayer->setLabelOffsetUnit( mLabelOffsetUnitWidget->unit() );
5406 mLayer->setLabelOffsetMapUnitScale( mLabelOffsetUnitWidget->getMapUnitScale() );
5407 emit changed();
5408 }
5409 } );
5410
5411 connect( mComboPlacement, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this] {
5412 if ( mLayer && !mBlockChangesSignal )
5413 {
5414 const Qgis::LinearReferencingPlacement placement = mComboPlacement->currentData().value<Qgis::LinearReferencingPlacement>();
5415 mLayer->setPlacement( placement );
5416 switch ( placement )
5417 {
5421 mIntervalWidget->show();
5422 break;
5424 mIntervalWidget->hide();
5425 break;
5426 }
5427 emit changed();
5428 }
5429 } );
5430
5431 connect( mSpinAverageAngleLength, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, [this] {
5432 if ( mLayer && !mBlockChangesSignal )
5433 {
5434 mLayer->setAverageAngleLength( mSpinAverageAngleLength->value() );
5435 emit changed();
5436 }
5437 } );
5438 connect( mAverageAngleUnit, &QgsUnitSelectionWidget::changed, this, [this] {
5439 if ( mLayer && !mBlockChangesSignal )
5440 {
5441 mLayer->setAverageAngleUnit( mAverageAngleUnit->unit() );
5442 mLayer->setAverageAngleMapUnitScale( mAverageAngleUnit->getMapUnitScale() );
5443 emit changed();
5444 }
5445 } );
5446
5447 connect( mNumberFormatPushButton, &QPushButton::clicked, this, &QgsLinearReferencingSymbolLayerWidget::changeNumberFormat );
5448
5449 mTextFormatButton->registerExpressionContextGenerator( this );
5450}
5451
5453
5454
5456{
5457 if ( !layer || layer->layerType() != "LinearReferencing"_L1 )
5458 return;
5459
5460 // layer type is correct, we can do the cast
5461 mLayer = qgis::down_cast<QgsLinearReferencingSymbolLayer *>( layer );
5462
5463 mBlockChangesSignal = true;
5464
5465 mComboPlacement->setCurrentIndex( mComboPlacement->findData( QVariant::fromValue( mLayer->placement() ) ) );
5466 switch ( mLayer->placement() )
5467 {
5471 mIntervalWidget->show();
5472 break;
5474 mIntervalWidget->hide();
5475 break;
5476 }
5477
5478 mComboQuantity->setCurrentIndex( mComboQuantity->findData( QVariant::fromValue( mLayer->labelSource() ) ) );
5479
5480 mTextFormatButton->setTextFormat( mLayer->textFormat() );
5481 spinInterval->setValue( mLayer->interval() );
5482 mSpinSkipMultiples->setValue( mLayer->skipMultiplesOf() );
5483 mCheckRotate->setChecked( mLayer->rotateLabels() );
5484 mCheckShowMarker->setChecked( mLayer->showMarker() );
5485 mSpinLabelOffsetX->setValue( mLayer->labelOffset().x() );
5486 mSpinLabelOffsetY->setValue( mLayer->labelOffset().y() );
5487 mLabelOffsetUnitWidget->setUnit( mLayer->labelOffsetUnit() );
5488 mLabelOffsetUnitWidget->setMapUnitScale( mLayer->labelOffsetMapUnitScale() );
5489
5490 mAverageAngleUnit->setUnit( mLayer->averageAngleUnit() );
5491 mAverageAngleUnit->setMapUnitScale( mLayer->averageAngleMapUnitScale() );
5492 mSpinAverageAngleLength->setValue( mLayer->averageAngleLength() );
5493
5494 mSpinAverageAngleLength->setEnabled( mCheckRotate->isChecked() );
5495 mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
5496
5501
5502 mBlockChangesSignal = false;
5503}
5504
5509
5511{
5513 mTextFormatButton->setMapCanvas( context.mapCanvas() );
5514 mTextFormatButton->setMessageBar( context.messageBar() );
5515}
5516
5517void QgsLinearReferencingSymbolLayerWidget::changeNumberFormat()
5518{
5520 if ( panel && panel->dockMode() )
5521 {
5523 widget->setPanelTitle( tr( "Number Format" ) );
5524 widget->setFormat( mLayer->numericFormat() );
5525 widget->registerExpressionContextGenerator( this );
5526 connect( widget, &QgsNumericFormatSelectorWidget::changed, this, [this, widget] {
5527 if ( !mBlockChangesSignal )
5528 {
5529 mLayer->setNumericFormat( widget->format() );
5530 emit changed();
5531 }
5532 } );
5533 panel->openPanel( widget );
5534 }
5535 else
5536 {
5537 QgsNumericFormatSelectorDialog dialog( this );
5538 dialog.setFormat( mLayer->numericFormat() );
5539 dialog.registerExpressionContextGenerator( this );
5540 if ( dialog.exec() )
5541 {
5542 mLayer->setNumericFormat( dialog.format() );
5543 emit changed();
5544 }
5545 }
5546}
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:3221
@ InnerVertices
Inner vertices (i.e. all vertices except the first and last vertex).
Definition qgis.h:3223
@ LastVertex
Place symbols on the last vertex in the line.
Definition qgis.h:3218
@ CentralPoint
Place symbols at the mid point of the line.
Definition qgis.h:3220
@ SegmentCenter
Place symbols at the center of every line segment.
Definition qgis.h:3222
@ Vertex
Place symbols on every vertex in the line.
Definition qgis.h:3217
@ Interval
Place symbols at regular intervals.
Definition qgis.h:3216
@ FirstVertex
Place symbols on the first vertex in the line.
Definition qgis.h:3219
MarkerClipMode
Marker clipping modes.
Definition qgis.h:3335
@ CompletelyWithin
Render complete markers wherever the completely fall within the polygon shape.
Definition qgis.h:3339
@ NoClipping
No clipping, render complete markers.
Definition qgis.h:3336
@ Shape
Clip to polygon shape.
Definition qgis.h:3337
@ CentroidWithin
Render complete markers wherever their centroid falls within the polygon shape.
Definition qgis.h:3338
LineClipMode
Line clipping modes.
Definition qgis.h:3349
@ NoClipping
Lines are not clipped, will extend to shape's bounding box.
Definition qgis.h:3352
@ ClipPainterOnly
Applying clipping on the painter only (i.e. line endpoints will coincide with polygon bounding box,...
Definition qgis.h:3350
@ ClipToIntersection
Clip lines to intersection with polygon shape (slower) (i.e. line endpoints will coincide with polygo...
Definition qgis.h:3351
@ ColorRamp
Gradient color ramp.
Definition qgis.h:3266
@ SimpleTwoColor
Simple two color gradient.
Definition qgis.h:3265
@ Repeat
Repeat gradient.
Definition qgis.h:3311
@ Reflect
Reflect gradient.
Definition qgis.h:3310
@ Pad
Pad out gradient using colors at endpoint of gradient.
Definition qgis.h:3309
PointCountMethod
Methods which define the number of points randomly filling a polygon.
Definition qgis.h:3323
@ Absolute
The point count is used as an absolute count of markers.
Definition qgis.h:3324
@ DensityBased
The point count is part of a marker density count.
Definition qgis.h:3325
@ Field
Field based property.
Definition qgis.h:706
MarkerShape
Marker shapes.
Definition qgis.h:3166
VerticalAnchorPoint
Marker symbol vertical anchor points.
Definition qgis.h:835
@ Bottom
Align to bottom of symbol.
Definition qgis.h:838
@ Center
Align to vertical center of symbol.
Definition qgis.h:837
@ Baseline
Align to baseline of symbol, e.g. font baseline for font marker symbol layers. Treated as Bottom if n...
Definition qgis.h:839
@ Top
Align to top of symbol.
Definition qgis.h:836
LinearReferencingPlacement
Defines how/where the labels should be placed in a linear referencing symbol layer.
Definition qgis.h:3235
@ IntervalZ
Place labels at regular intervals, linearly interpolated using Z values.
Definition qgis.h:3237
@ Vertex
Place labels on every vertex in the line.
Definition qgis.h:3239
@ IntervalM
Place labels at regular intervals, linearly interpolated using M values.
Definition qgis.h:3238
@ IntervalCartesian2D
Place labels at regular intervals, using Cartesian distance calculations on a 2D plane.
Definition qgis.h:3236
LinearReferencingLabelSource
Defines what quantity to use for the labels shown in a linear referencing symbol layer.
Definition qgis.h:3249
@ CartesianDistance2D
Distance along line, calculated using Cartesian calculations on a 2D plane.
Definition qgis.h:3250
@ Percentage
Percentage of another measurement (e.g., canvas size, feature size).
Definition qgis.h:5309
@ Millimeters
Millimeters.
Definition qgis.h:5306
@ Points
Points (e.g., for font sizes).
Definition qgis.h:5310
@ MapUnits
Map units.
Definition qgis.h:5307
@ Pixels
Pixels.
Definition qgis.h:5308
@ Inches
Inches.
Definition qgis.h:5311
@ MetersInMapUnits
Meters value as Map units.
Definition qgis.h:5313
@ Linear
Linear gradient.
Definition qgis.h:3279
@ Conical
Conical (polar) gradient.
Definition qgis.h:3281
@ Radial
Radial (circular) gradient.
Definition qgis.h:3280
SymbolType
Symbol types.
Definition qgis.h:631
@ Marker
Marker symbol.
Definition qgis.h:632
@ Line
Line symbol.
Definition qgis.h:633
@ Fill
Fill symbol.
Definition qgis.h:634
@ Hybrid
Hybrid symbol.
Definition qgis.h:635
SymbolCoordinateReference
Symbol coordinate reference modes.
Definition qgis.h:3293
@ Feature
Relative to feature/shape being rendered.
Definition qgis.h:3294
@ Viewport
Relative to the whole viewport/output device.
Definition qgis.h:3295
QFlags< MarkerLinePlacement > MarkerLinePlacements
Definition qgis.h:3226
HorizontalAnchorPoint
Marker symbol horizontal anchor points.
Definition qgis.h:821
@ Center
Align to horizontal center of symbol.
Definition qgis.h:823
@ Right
Align to right side of symbol.
Definition qgis.h:824
@ Left
Align to left side of symbol.
Definition qgis.h:822
static const double UI_SCALE_FACTOR
UI scaling factor.
Definition qgis.h:6549
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.
Q_INVOKABLE int indexFromName(const QString &fieldName) const
Gets the field index from the field name.
~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.
void unsetMapTool(QgsMapTool *mapTool)
Unset the current map tool or last non zoom tool.
void setMapTool(QgsMapTool *mapTool, bool clean=false)
Sets the map tool currently being used on the canvas.
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.
Qgis::PropertyType propertyType() const
Returns the property type.
QString field() const
Returns the current field name the property references.
bool isActive() const
Returns whether the property is currently active.
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.
QgsVectorLayer * vectorLayer() const
Returns the vector layer associated with the widget.
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...
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.
@ BlankSegments
String list of distance to define blank segments along line for templated line symbol layers.
@ 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,...
QgsMapCanvas * mapCanvas() const
Returns the map canvas associated with the widget.
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:6854
QList< QgsSymbolLayer * > QgsSymbolLayerList
Definition qgssymbol.h:30
class GUI_EXPORT QgsMapToolEditBlankSegments
Single variable definition for use within a QgsExpressionContextScope.