QGIS API Documentation 3.99.0-Master (d270888f95f)
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 {
2284 // NOLINTBEGIN(bugprone-branch-clone)
2286 mMapToolEditBlankSegments.reset( new QgsMapToolEditBlankSegments<QgsHashedLineSymbolLayer>( context().mapCanvas(), vectorLayer(), mLayer, blankSegmentsFieldIndex() ) );
2287 break;
2288
2290 mMapToolEditBlankSegments.reset( new QgsMapToolEditBlankSegments<QgsMarkerLineSymbolLayer>( context().mapCanvas(), vectorLayer(), mLayer, blankSegmentsFieldIndex() ) );
2291 break;
2292 // NOLINTEND(bugprone-branch-clone)
2293 }
2294
2295 context().mapCanvas()->setMapTool( mMapToolEditBlankSegments );
2296 }
2297}
2298
2299void QgsTemplatedLineSymbolLayerWidget::updateBlankSegmentsWidget()
2300{
2301 mEditBlankSegmentsBtn->setEnabled( blankSegmentsFieldIndex() > -1 );
2302 QString tooltip;
2303 switch ( mSymbolType )
2304 {
2306 tooltip = tr( "Tool to create blank segments where hashed lines won't be displayed" );
2307 break;
2308
2310 tooltip = tr( "Tool to create blank segments where marker lines won't be displayed" );
2311 break;
2312 }
2313
2314 if ( !mEditBlankSegmentsBtn->isEnabled() )
2315 {
2316 tooltip += u"<br/><br/>"_s + tr( "This tool is disabled because no valid field property has been set" );
2317 }
2318
2319 mEditBlankSegmentsBtn->setToolTip( tooltip );
2320}
2321
2322int QgsTemplatedLineSymbolLayerWidget::blankSegmentsFieldIndex() const
2323{
2324 const QgsProperty blankSegmentsProperty = mLayer->dataDefinedProperties().property( QgsSymbolLayer::Property::BlankSegments );
2325 return blankSegmentsProperty && blankSegmentsProperty.isActive()
2326 && blankSegmentsProperty.propertyType() == Qgis::PropertyType::Field
2327 ? vectorLayer()->fields().indexFromName( blankSegmentsProperty.field() )
2328 : -1;
2329}
2330
2332
2337
2339
2344
2346
2347
2349 : QgsSymbolLayerWidget( parent, vl )
2350{
2351 mLayer = nullptr;
2352
2353 setupUi( this );
2354
2355 mHorizontalAnchorComboBox->addItem( tr( "Left" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Left ) );
2356 mHorizontalAnchorComboBox->addItem( tr( "Horizontal Center" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Center ) );
2357 mHorizontalAnchorComboBox->addItem( tr( "Right" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Right ) );
2358
2359 mVerticalAnchorComboBox->addItem( tr( "Top" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Top ) );
2360 mVerticalAnchorComboBox->addItem( tr( "Vertical Center" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Center ) );
2361 mVerticalAnchorComboBox->addItem( tr( "Bottom" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Bottom ) );
2362
2363 mSvgSelectorWidget->setAllowParameters( true );
2364 mSvgSelectorWidget->sourceLineEdit()->setPropertyOverrideToolButtonVisible( true );
2365 mSvgSelectorWidget->sourceLineEdit()->setLastPathSettingsKey( u"/UI/lastSVGMarkerDir"_s );
2366 mSvgSelectorWidget->initParametersModel( this, vl );
2367
2368 connect( mSvgSelectorWidget->sourceLineEdit(), &QgsSvgSourceLineEdit::sourceChanged, this, &QgsSvgMarkerSymbolLayerWidget::svgSourceChanged );
2369 connect( mChangeColorButton, &QgsColorButton::colorChanged, this, &QgsSvgMarkerSymbolLayerWidget::mChangeColorButton_colorChanged );
2370 connect( mChangeStrokeColorButton, &QgsColorButton::colorChanged, this, &QgsSvgMarkerSymbolLayerWidget::mChangeStrokeColorButton_colorChanged );
2371 connect( mStrokeWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
2372 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
2373 connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
2374 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
2375 connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSvgMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
2376 connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSvgMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
2380 mChangeColorButton->setAllowOpacity( true );
2381 mChangeColorButton->setColorDialogTitle( tr( "Select Fill color" ) );
2382 mChangeColorButton->setContext( u"symbology"_s );
2383 mChangeStrokeColorButton->setAllowOpacity( true );
2384 mChangeStrokeColorButton->setColorDialogTitle( tr( "Select Stroke Color" ) );
2385 mChangeStrokeColorButton->setContext( u"symbology"_s );
2386
2387 mFillColorDDBtn->registerLinkedWidget( mChangeColorButton );
2388 mStrokeColorDDBtn->registerLinkedWidget( mChangeStrokeColorButton );
2389
2390 spinOffsetX->setClearValue( 0.0 );
2391 spinOffsetY->setClearValue( 0.0 );
2392 spinAngle->setClearValue( 0.0 );
2393
2394 connect( spinWidth, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setWidth );
2395 connect( spinHeight, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setHeight );
2396 connect( mLockAspectRatio, static_cast<void ( QgsRatioLockButton::* )( bool )>( &QgsRatioLockButton::lockChanged ), this, &QgsSvgMarkerSymbolLayerWidget::lockAspectRatioChanged );
2397 connect( spinAngle, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setAngle );
2398 connect( spinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setOffset );
2399 connect( spinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSvgMarkerSymbolLayerWidget::setOffset );
2400 connect( this, &QgsSymbolLayerWidget::changed, this, &QgsSvgMarkerSymbolLayerWidget::updateAssistantSymbol );
2401
2404
2405 //make a temporary symbol for the size assistant preview
2406 mAssistantPreviewSymbol = std::make_shared<QgsMarkerSymbol>();
2407
2408 if ( vectorLayer() )
2409 {
2410 mWidthDDBtn->setSymbol( mAssistantPreviewSymbol );
2411 mHeightDDBtn->setSymbol( mAssistantPreviewSymbol );
2412 }
2413}
2414
2416
2417#include <QTime>
2418#include <QAbstractListModel>
2419#include <QPixmapCache>
2420#include <QStyle>
2421#include <memory>
2422
2423
2425{
2426 if ( !layer )
2427 {
2428 return;
2429 }
2430
2431 //activate gui for svg parameters only if supported by the svg file
2432 bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2433 QColor defaultFill, defaultStroke;
2434 double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2435 bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
2436 QgsApplication::svgCache()->containsParams( layer->path(), hasFillParam, hasDefaultFillColor, defaultFill, hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity, hasStrokeParam, hasDefaultStrokeColor, defaultStroke, hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth, hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
2437 mChangeColorButton->setEnabled( hasFillParam );
2438 mChangeColorButton->setAllowOpacity( hasFillOpacityParam );
2439 mChangeStrokeColorButton->setEnabled( hasStrokeParam );
2440 mChangeStrokeColorButton->setAllowOpacity( hasStrokeOpacityParam );
2441 mStrokeWidthSpinBox->setEnabled( hasStrokeWidthParam );
2442
2443 if ( hasFillParam )
2444 {
2445 QColor fill = layer->fillColor();
2446 const double existingOpacity = hasFillOpacityParam ? fill.alphaF() : 1.0;
2447 if ( hasDefaultFillColor && !skipDefaultColors )
2448 {
2449 fill = defaultFill;
2450 }
2451 fill.setAlphaF( hasDefaultFillOpacity ? defaultFillOpacity : existingOpacity );
2452 mChangeColorButton->setColor( fill );
2453 }
2454 if ( hasStrokeParam )
2455 {
2456 QColor stroke = layer->strokeColor();
2457 const double existingOpacity = hasStrokeOpacityParam ? stroke.alphaF() : 1.0;
2458 if ( hasDefaultStrokeColor && !skipDefaultColors )
2459 {
2460 stroke = defaultStroke;
2461 }
2462 stroke.setAlphaF( hasDefaultStrokeOpacity ? defaultStrokeOpacity : existingOpacity );
2463 mChangeStrokeColorButton->setColor( stroke );
2464 }
2465
2466 whileBlocking( mSvgSelectorWidget->sourceLineEdit() )->setSource( layer->path() );
2467
2468 mStrokeWidthSpinBox->blockSignals( true );
2469 mStrokeWidthSpinBox->setValue( hasDefaultStrokeWidth ? defaultStrokeWidth : layer->strokeWidth() );
2470 mStrokeWidthSpinBox->blockSignals( false );
2471
2472 const bool preservedAspectRatio = layer->preservedAspectRatio();
2473 spinHeight->blockSignals( true );
2474 if ( preservedAspectRatio )
2475 {
2476 spinHeight->setValue( layer->size() * layer->defaultAspectRatio() );
2477 }
2478 else
2479 {
2480 spinHeight->setValue( layer->size() * layer->fixedAspectRatio() );
2481 }
2482 spinHeight->setEnabled( layer->defaultAspectRatio() > 0.0 );
2483 spinHeight->blockSignals( false );
2484 whileBlocking( mLockAspectRatio )->setLocked( preservedAspectRatio );
2485}
2486
2487void QgsSvgMarkerSymbolLayerWidget::updateAssistantSymbol()
2488{
2489 for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1; i >= 0; --i )
2490 {
2491 mAssistantPreviewSymbol->deleteSymbolLayer( i );
2492 }
2493 mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
2494 const QgsProperty ddSize = mLayer->dataDefinedProperties().property( QgsSymbolLayer::Property::Size );
2495 if ( ddSize )
2496 mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
2497}
2498
2499
2501{
2502 if ( !layer )
2503 {
2504 return;
2505 }
2506
2507 if ( layer->layerType() != "SvgMarker"_L1 )
2508 return;
2509
2510 // layer type is correct, we can do the cast
2511 mLayer = static_cast<QgsSvgMarkerSymbolLayer *>( layer );
2512
2513 // set values
2514 mSvgSelectorWidget->setSvgPath( mLayer->path() );
2515 mSvgSelectorWidget->setSvgParameters( mLayer->parameters() );
2516
2517 spinWidth->blockSignals( true );
2518 spinWidth->setValue( mLayer->size() );
2519 spinWidth->blockSignals( false );
2520 spinAngle->blockSignals( true );
2521 spinAngle->setValue( mLayer->angle() );
2522 spinAngle->blockSignals( false );
2523
2524 // without blocking signals the value gets changed because of slot setOffset()
2525 spinOffsetX->blockSignals( true );
2526 spinOffsetX->setValue( mLayer->offset().x() );
2527 spinOffsetX->blockSignals( false );
2528 spinOffsetY->blockSignals( true );
2529 spinOffsetY->setValue( mLayer->offset().y() );
2530 spinOffsetY->blockSignals( false );
2531
2532 mSizeUnitWidget->blockSignals( true );
2533 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
2534 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
2535 mSizeUnitWidget->blockSignals( false );
2536 mStrokeWidthUnitWidget->blockSignals( true );
2537 mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
2538 mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
2539 mStrokeWidthUnitWidget->blockSignals( false );
2540 mOffsetUnitWidget->blockSignals( true );
2541 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
2542 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
2543 mOffsetUnitWidget->blockSignals( false );
2544
2545 //anchor points
2546 mHorizontalAnchorComboBox->blockSignals( true );
2547 mVerticalAnchorComboBox->blockSignals( true );
2548 mHorizontalAnchorComboBox->setCurrentIndex( mHorizontalAnchorComboBox->findData( QVariant::fromValue( mLayer->horizontalAnchorPoint() ) ) );
2549 mVerticalAnchorComboBox->setCurrentIndex( mVerticalAnchorComboBox->findData( QVariant::fromValue( mLayer->verticalAnchorPoint() ) ) );
2550 mHorizontalAnchorComboBox->blockSignals( false );
2551 mVerticalAnchorComboBox->blockSignals( false );
2552
2553 setGuiForSvg( mLayer, true );
2554
2564
2565 registerDataDefinedButton( mSvgSelectorWidget->sourceLineEdit()->propertyOverrideToolButton(), QgsSymbolLayer::Property::Name );
2566
2567 updateAssistantSymbol();
2568}
2569
2574
2576{
2578 mSvgSelectorWidget->sourceLineEdit()->setMessageBar( context.messageBar() );
2579}
2580
2582{
2583 mLayer->setPath( name );
2584 whileBlocking( mSvgSelectorWidget->sourceLineEdit() )->setSource( name );
2585
2587 emit changed();
2588}
2589
2590void QgsSvgMarkerSymbolLayerWidget::setSvgParameters( const QMap<QString, QgsProperty> &parameters )
2591{
2592 mLayer->setParameters( parameters );
2593 whileBlocking( mSvgSelectorWidget )->setSvgParameters( parameters );
2594
2596 emit changed();
2597}
2598
2599void QgsSvgMarkerSymbolLayerWidget::setWidth()
2600{
2601 const double defaultAspectRatio = mLayer->defaultAspectRatio();
2602 double fixedAspectRatio = 0.0;
2603 spinHeight->blockSignals( true );
2604 if ( defaultAspectRatio <= 0.0 )
2605 {
2606 spinHeight->setValue( spinWidth->value() );
2607 }
2608 else if ( mLockAspectRatio->locked() )
2609 {
2610 spinHeight->setValue( spinWidth->value() * defaultAspectRatio );
2611 }
2612 else
2613 {
2614 fixedAspectRatio = spinHeight->value() / spinWidth->value();
2615 }
2616 spinHeight->blockSignals( false );
2617 mLayer->setSize( spinWidth->value() );
2618 mLayer->setFixedAspectRatio( fixedAspectRatio );
2619 emit changed();
2620}
2621
2622void QgsSvgMarkerSymbolLayerWidget::setHeight()
2623{
2624 const double defaultAspectRatio = mLayer->defaultAspectRatio();
2625 double fixedAspectRatio = 0.0;
2626 spinWidth->blockSignals( true );
2627 if ( defaultAspectRatio <= 0.0 )
2628 {
2629 spinWidth->setValue( spinHeight->value() );
2630 }
2631 else if ( mLockAspectRatio->locked() )
2632 {
2633 spinWidth->setValue( spinHeight->value() / defaultAspectRatio );
2634 }
2635 else
2636 {
2637 fixedAspectRatio = spinHeight->value() / spinWidth->value();
2638 }
2639 spinWidth->blockSignals( false );
2640 mLayer->setSize( spinWidth->value() );
2641 mLayer->setFixedAspectRatio( fixedAspectRatio );
2642 emit changed();
2643}
2644
2645void QgsSvgMarkerSymbolLayerWidget::lockAspectRatioChanged( const bool locked )
2646{
2647 //spinHeight->setEnabled( !locked );
2648 const double defaultAspectRatio = mLayer->defaultAspectRatio();
2649 if ( defaultAspectRatio <= 0.0 )
2650 {
2651 whileBlocking( mLockAspectRatio )->setLocked( true );
2652 }
2653 else if ( locked )
2654 {
2655 mLayer->setFixedAspectRatio( 0.0 );
2656 setWidth();
2657 }
2658 else
2659 {
2660 mLayer->setFixedAspectRatio( spinHeight->value() / spinWidth->value() );
2661 }
2662 //emit changed();
2663}
2664
2665void QgsSvgMarkerSymbolLayerWidget::setAngle()
2666{
2667 mLayer->setAngle( spinAngle->value() );
2668 emit changed();
2669}
2670
2671void QgsSvgMarkerSymbolLayerWidget::setOffset()
2672{
2673 mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
2674 emit changed();
2675}
2676
2677void QgsSvgMarkerSymbolLayerWidget::svgSourceChanged( const QString &text )
2678{
2679 mLayer->setPath( text );
2681 emit changed();
2682}
2683
2684void QgsSvgMarkerSymbolLayerWidget::mChangeColorButton_colorChanged( const QColor &color )
2685{
2686 if ( !mLayer )
2687 {
2688 return;
2689 }
2690
2691 mLayer->setFillColor( color );
2692 emit changed();
2693}
2694
2695void QgsSvgMarkerSymbolLayerWidget::mChangeStrokeColorButton_colorChanged( const QColor &color )
2696{
2697 if ( !mLayer )
2698 {
2699 return;
2700 }
2701
2702 mLayer->setStrokeColor( color );
2703 emit changed();
2704}
2705
2706void QgsSvgMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
2707{
2708 if ( mLayer )
2709 {
2710 mLayer->setStrokeWidth( d );
2711 emit changed();
2712 }
2713}
2714
2715void QgsSvgMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
2716{
2717 if ( mLayer )
2718 {
2719 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
2720 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
2721 emit changed();
2722 }
2723}
2724
2725void QgsSvgMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
2726{
2727 if ( mLayer )
2728 {
2729 mLayer->setStrokeWidthUnit( mStrokeWidthUnitWidget->unit() );
2730 mLayer->setStrokeWidthMapUnitScale( mStrokeWidthUnitWidget->getMapUnitScale() );
2731 emit changed();
2732 }
2733}
2734
2735void QgsSvgMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
2736{
2737 if ( mLayer )
2738 {
2739 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
2740 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
2741 emit changed();
2742 }
2743}
2744
2745void QgsSvgMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int )
2746{
2747 if ( mLayer )
2748 {
2749 mLayer->setHorizontalAnchorPoint( mHorizontalAnchorComboBox->currentData().value< Qgis::HorizontalAnchorPoint >() );
2750 emit changed();
2751 }
2752}
2753
2754void QgsSvgMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int )
2755{
2756 if ( mLayer )
2757 {
2758 mLayer->setVerticalAnchorPoint( mVerticalAnchorComboBox->currentData().value< Qgis::VerticalAnchorPoint >() );
2759 emit changed();
2760 }
2761}
2762
2764
2766 : QgsSymbolLayerWidget( parent, vl )
2767{
2768 mLayer = nullptr;
2769 setupUi( this );
2770
2771 mSvgSelectorWidget->setAllowParameters( true );
2772 mSvgSelectorWidget->sourceLineEdit()->setPropertyOverrideToolButtonVisible( true );
2773
2774 connect( mTextureWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mTextureWidthSpinBox_valueChanged );
2775 connect( mSvgSelectorWidget->sourceLineEdit(), &QgsSvgSourceLineEdit::sourceChanged, this, &QgsSVGFillSymbolLayerWidget::svgSourceChanged );
2776 connect( mRotationSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mRotationSpinBox_valueChanged );
2777 connect( mChangeColorButton, &QgsColorButton::colorChanged, this, &QgsSVGFillSymbolLayerWidget::mChangeColorButton_colorChanged );
2778 connect( mChangeStrokeColorButton, &QgsColorButton::colorChanged, this, &QgsSVGFillSymbolLayerWidget::mChangeStrokeColorButton_colorChanged );
2779 connect( mStrokeWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
2780 connect( mTextureWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSVGFillSymbolLayerWidget::mTextureWidthUnitWidget_changed );
2781 connect( mSvgStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSVGFillSymbolLayerWidget::mSvgStrokeWidthUnitWidget_changed );
2784
2785 mRotationSpinBox->setClearValue( 0.0 );
2786
2787 mChangeColorButton->setColorDialogTitle( tr( "Select Fill Color" ) );
2788 mChangeColorButton->setContext( u"symbology"_s );
2789 mChangeStrokeColorButton->setColorDialogTitle( tr( "Select Stroke Color" ) );
2790 mChangeStrokeColorButton->setContext( u"symbology"_s );
2791
2792 mFilColorDDBtn->registerLinkedWidget( mChangeColorButton );
2793 mStrokeColorDDBtn->registerLinkedWidget( mChangeStrokeColorButton );
2794
2795 connect( mSvgSelectorWidget, &QgsSvgSelectorWidget::svgSelected, this, &QgsSVGFillSymbolLayerWidget::setFile );
2796 connect( mSvgSelectorWidget, &QgsSvgSelectorWidget::svgParametersChanged, this, &QgsSVGFillSymbolLayerWidget::setSvgParameters );
2797}
2798
2800{
2801 if ( !layer )
2802 {
2803 return;
2804 }
2805
2806 if ( layer->layerType() != "SVGFill"_L1 )
2807 {
2808 return;
2809 }
2810
2811 mLayer = dynamic_cast<QgsSVGFillSymbolLayer *>( layer );
2812 if ( mLayer )
2813 {
2814 const double width = mLayer->patternWidth();
2815 mTextureWidthSpinBox->blockSignals( true );
2816 mTextureWidthSpinBox->setValue( width );
2817 mTextureWidthSpinBox->blockSignals( false );
2818 whileBlocking( mSvgSelectorWidget->sourceLineEdit() )->setSource( mLayer->svgFilePath() );
2819 mRotationSpinBox->blockSignals( true );
2820 mRotationSpinBox->setValue( mLayer->angle() );
2821 mRotationSpinBox->blockSignals( false );
2822 mTextureWidthUnitWidget->blockSignals( true );
2823 mTextureWidthUnitWidget->setUnit( mLayer->patternWidthUnit() );
2824 mTextureWidthUnitWidget->setMapUnitScale( mLayer->patternWidthMapUnitScale() );
2825 mTextureWidthUnitWidget->blockSignals( false );
2826 mSvgStrokeWidthUnitWidget->blockSignals( true );
2827 mSvgStrokeWidthUnitWidget->setUnit( mLayer->svgStrokeWidthUnit() );
2828 mSvgStrokeWidthUnitWidget->setMapUnitScale( mLayer->svgStrokeWidthMapUnitScale() );
2829 mSvgStrokeWidthUnitWidget->blockSignals( false );
2830 mChangeColorButton->blockSignals( true );
2831 mChangeColorButton->setColor( mLayer->svgFillColor() );
2832 mChangeColorButton->blockSignals( false );
2833 mChangeStrokeColorButton->blockSignals( true );
2834 mChangeStrokeColorButton->setColor( mLayer->svgStrokeColor() );
2835 mChangeStrokeColorButton->blockSignals( false );
2836 mStrokeWidthSpinBox->blockSignals( true );
2837 mStrokeWidthSpinBox->setValue( mLayer->svgStrokeWidth() );
2838 mStrokeWidthSpinBox->blockSignals( false );
2839 }
2840 updateParamGui( false );
2841
2847
2848 registerDataDefinedButton( mSvgSelectorWidget->sourceLineEdit()->propertyOverrideToolButton(), QgsSymbolLayer::Property::File );
2849}
2850
2855
2857{
2859 mSvgSelectorWidget->sourceLineEdit()->setMessageBar( context.messageBar() );
2860}
2861
2862void QgsSVGFillSymbolLayerWidget::mTextureWidthSpinBox_valueChanged( double d )
2863{
2864 if ( mLayer )
2865 {
2866 mLayer->setPatternWidth( d );
2867 emit changed();
2868 }
2869}
2870
2871void QgsSVGFillSymbolLayerWidget::svgSourceChanged( const QString &text )
2872{
2873 if ( !mLayer )
2874 {
2875 return;
2876 }
2877
2878 mLayer->setSvgFilePath( text );
2880 emit changed();
2881}
2882
2883void QgsSVGFillSymbolLayerWidget::setFile( const QString &name )
2884{
2885 mLayer->setSvgFilePath( name );
2886 whileBlocking( mSvgSelectorWidget->sourceLineEdit() )->setSource( name );
2887
2889 emit changed();
2890}
2891
2892void QgsSVGFillSymbolLayerWidget::setSvgParameters( const QMap<QString, QgsProperty> &parameters )
2893{
2894 mLayer->setParameters( parameters );
2895 whileBlocking( mSvgSelectorWidget )->setSvgParameters( parameters );
2896
2898 emit changed();
2899}
2900
2901
2902void QgsSVGFillSymbolLayerWidget::mRotationSpinBox_valueChanged( double d )
2903{
2904 if ( mLayer )
2905 {
2906 mLayer->setAngle( d );
2907 emit changed();
2908 }
2909}
2910
2912{
2913 //activate gui for svg parameters only if supported by the svg file
2914 bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2915 QColor defaultFill, defaultStroke;
2916 double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2917 bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
2918 QgsApplication::svgCache()->containsParams( mSvgSelectorWidget->sourceLineEdit()->source(), hasFillParam, hasDefaultFillColor, defaultFill, hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity, hasStrokeParam, hasDefaultStrokeColor, defaultStroke, hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth, hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
2919 if ( resetValues )
2920 {
2921 QColor fill = mChangeColorButton->color();
2922 const double newOpacity = hasFillOpacityParam ? fill.alphaF() : 1.0;
2923 if ( hasDefaultFillColor )
2924 {
2925 fill = defaultFill;
2926 }
2927 fill.setAlphaF( hasDefaultFillOpacity ? defaultFillOpacity : newOpacity );
2928 mChangeColorButton->setColor( fill );
2929 }
2930 mChangeColorButton->setEnabled( hasFillParam );
2931 mChangeColorButton->setAllowOpacity( hasFillOpacityParam );
2932 if ( resetValues )
2933 {
2934 QColor stroke = mChangeStrokeColorButton->color();
2935 const double newOpacity = hasStrokeOpacityParam ? stroke.alphaF() : 1.0;
2936 if ( hasDefaultStrokeColor )
2937 {
2938 stroke = defaultStroke;
2939 }
2940 stroke.setAlphaF( hasDefaultStrokeOpacity ? defaultStrokeOpacity : newOpacity );
2941 mChangeStrokeColorButton->setColor( stroke );
2942 }
2943 mChangeStrokeColorButton->setEnabled( hasStrokeParam );
2944 mChangeStrokeColorButton->setAllowOpacity( hasStrokeOpacityParam );
2945 if ( hasDefaultStrokeWidth && resetValues )
2946 {
2947 mStrokeWidthSpinBox->setValue( defaultStrokeWidth );
2948 }
2949 mStrokeWidthSpinBox->setEnabled( hasStrokeWidthParam );
2950}
2951
2952void QgsSVGFillSymbolLayerWidget::mChangeColorButton_colorChanged( const QColor &color )
2953{
2954 if ( !mLayer )
2955 {
2956 return;
2957 }
2958
2959 mLayer->setSvgFillColor( color );
2960 emit changed();
2961}
2962
2963void QgsSVGFillSymbolLayerWidget::mChangeStrokeColorButton_colorChanged( const QColor &color )
2964{
2965 if ( !mLayer )
2966 {
2967 return;
2968 }
2969
2970 mLayer->setSvgStrokeColor( color );
2971 emit changed();
2972}
2973
2974void QgsSVGFillSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
2975{
2976 if ( mLayer )
2977 {
2978 mLayer->setSvgStrokeWidth( d );
2979 emit changed();
2980 }
2981}
2982
2983void QgsSVGFillSymbolLayerWidget::mTextureWidthUnitWidget_changed()
2984{
2985 if ( mLayer )
2986 {
2987 mLayer->setPatternWidthUnit( mTextureWidthUnitWidget->unit() );
2988 mLayer->setPatternWidthMapUnitScale( mTextureWidthUnitWidget->getMapUnitScale() );
2989 emit changed();
2990 }
2991}
2992
2993void QgsSVGFillSymbolLayerWidget::mSvgStrokeWidthUnitWidget_changed()
2994{
2995 if ( mLayer )
2996 {
2997 mLayer->setSvgStrokeWidthUnit( mSvgStrokeWidthUnitWidget->unit() );
2998 mLayer->setSvgStrokeWidthMapUnitScale( mSvgStrokeWidthUnitWidget->getMapUnitScale() );
2999 emit changed();
3000 }
3001}
3002
3004
3006 : QgsSymbolLayerWidget( parent, vl )
3007{
3008 setupUi( this );
3009 connect( mAngleSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLinePatternFillSymbolLayerWidget::mAngleSpinBox_valueChanged );
3010 connect( mDistanceSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLinePatternFillSymbolLayerWidget::mDistanceSpinBox_valueChanged );
3011 connect( mOffsetSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLinePatternFillSymbolLayerWidget::mOffsetSpinBox_valueChanged );
3012 connect( mDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsLinePatternFillSymbolLayerWidget::mDistanceUnitWidget_changed );
3013 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsLinePatternFillSymbolLayerWidget::mOffsetUnitWidget_changed );
3016 mOffsetSpinBox->setClearValue( 0 );
3017 mAngleSpinBox->setClearValue( 0 );
3018
3019 mCoordinateReferenceComboBox->addItem( tr( "Align Pattern to Feature" ), static_cast<int>( Qgis::SymbolCoordinateReference::Feature ) );
3020 mCoordinateReferenceComboBox->addItem( tr( "Align Pattern to Map Extent" ), static_cast<int>( Qgis::SymbolCoordinateReference::Viewport ) );
3021 connect( mCoordinateReferenceComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this] {
3022 if ( mLayer )
3023 {
3024 mLayer->setCoordinateReference( static_cast<Qgis::SymbolCoordinateReference>( mCoordinateReferenceComboBox->currentData().toInt() ) );
3025 emit changed();
3026 }
3027 } );
3028
3029 mClipModeComboBox->addItem( tr( "Clip During Render Only" ), static_cast<int>( Qgis::LineClipMode::ClipPainterOnly ) );
3030 mClipModeComboBox->addItem( tr( "Clip Lines Before Render" ), static_cast<int>( Qgis::LineClipMode::ClipToIntersection ) );
3031 mClipModeComboBox->addItem( tr( "No Clipping" ), static_cast<int>( Qgis::LineClipMode::NoClipping ) );
3032 connect( mClipModeComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this] {
3033 if ( mLayer )
3034 {
3035 mLayer->setClipMode( static_cast<Qgis::LineClipMode>( mClipModeComboBox->currentData().toInt() ) );
3036 emit changed();
3037 }
3038 } );
3039}
3040
3042{
3043 if ( layer->layerType() != "LinePatternFill"_L1 )
3044 {
3045 return;
3046 }
3047
3048 QgsLinePatternFillSymbolLayer *patternLayer = static_cast<QgsLinePatternFillSymbolLayer *>( layer );
3049 if ( patternLayer )
3050 {
3051 mLayer = patternLayer;
3052 whileBlocking( mAngleSpinBox )->setValue( mLayer->lineAngle() );
3053 whileBlocking( mDistanceSpinBox )->setValue( mLayer->distance() );
3054 whileBlocking( mOffsetSpinBox )->setValue( mLayer->offset() );
3055
3056 //units
3057 mDistanceUnitWidget->blockSignals( true );
3058 mDistanceUnitWidget->setUnit( mLayer->distanceUnit() );
3059 mDistanceUnitWidget->setMapUnitScale( mLayer->distanceMapUnitScale() );
3060 mDistanceUnitWidget->blockSignals( false );
3061 mOffsetUnitWidget->blockSignals( true );
3062 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
3063 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
3064 mOffsetUnitWidget->blockSignals( false );
3065
3066 whileBlocking( mCoordinateReferenceComboBox )->setCurrentIndex( mCoordinateReferenceComboBox->findData( static_cast<int>( mLayer->coordinateReference() ) ) );
3067
3068 whileBlocking( mClipModeComboBox )->setCurrentIndex( mClipModeComboBox->findData( static_cast<int>( mLayer->clipMode() ) ) );
3069 }
3070
3075}
3076
3081
3082void QgsLinePatternFillSymbolLayerWidget::mAngleSpinBox_valueChanged( double d )
3083{
3084 if ( mLayer )
3085 {
3086 mLayer->setLineAngle( d );
3087 emit changed();
3088 }
3089}
3090
3091void QgsLinePatternFillSymbolLayerWidget::mDistanceSpinBox_valueChanged( double d )
3092{
3093 if ( mLayer )
3094 {
3095 mLayer->setDistance( d );
3096 emit changed();
3097 }
3098}
3099
3100void QgsLinePatternFillSymbolLayerWidget::mOffsetSpinBox_valueChanged( double d )
3101{
3102 if ( mLayer )
3103 {
3104 mLayer->setOffset( d );
3105 emit changed();
3106 }
3107}
3108
3109void QgsLinePatternFillSymbolLayerWidget::mDistanceUnitWidget_changed()
3110{
3111 if ( mLayer )
3112 {
3113 mLayer->setDistanceUnit( mDistanceUnitWidget->unit() );
3114 mLayer->setDistanceMapUnitScale( mDistanceUnitWidget->getMapUnitScale() );
3115 emit changed();
3116 }
3117}
3118
3119void QgsLinePatternFillSymbolLayerWidget::mOffsetUnitWidget_changed()
3120{
3121 if ( mLayer )
3122 {
3123 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
3124 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
3125 emit changed();
3126 }
3127}
3128
3130
3132 : QgsSymbolLayerWidget( parent, vl )
3133{
3134 setupUi( this );
3135 connect( mHorizontalDistanceSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceSpinBox_valueChanged );
3136 connect( mVerticalDistanceSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceSpinBox_valueChanged );
3137 connect( mHorizontalDisplacementSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementSpinBox_valueChanged );
3138 connect( mVerticalDisplacementSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementSpinBox_valueChanged );
3139 connect( mHorizontalOffsetSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetSpinBox_valueChanged );
3140 connect( mVerticalOffsetSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetSpinBox_valueChanged );
3141 connect( mHorizontalDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceUnitWidget_changed );
3142 connect( mVerticalDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceUnitWidget_changed );
3143 connect( mHorizontalDisplacementUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementUnitWidget_changed );
3144 connect( mVerticalDisplacementUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementUnitWidget_changed );
3145 connect( mHorizontalOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetUnitWidget_changed );
3146 connect( mVerticalOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetUnitWidget_changed );
3153
3154 mClipModeComboBox->addItem( tr( "Clip to Shape" ), static_cast<int>( Qgis::MarkerClipMode::Shape ) );
3155 mClipModeComboBox->addItem( tr( "Marker Centroid Within Shape" ), static_cast<int>( Qgis::MarkerClipMode::CentroidWithin ) );
3156 mClipModeComboBox->addItem( tr( "Marker Completely Within Shape" ), static_cast<int>( Qgis::MarkerClipMode::CompletelyWithin ) );
3157 mClipModeComboBox->addItem( tr( "No Clipping" ), static_cast<int>( Qgis::MarkerClipMode::NoClipping ) );
3158 connect( mClipModeComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this] {
3159 if ( mLayer )
3160 {
3161 mLayer->setClipMode( static_cast<Qgis::MarkerClipMode>( mClipModeComboBox->currentData().toInt() ) );
3162 emit changed();
3163 }
3164 } );
3165
3166 mCoordinateReferenceComboBox->addItem( tr( "Align Pattern to Feature" ), static_cast<int>( Qgis::SymbolCoordinateReference::Feature ) );
3167 mCoordinateReferenceComboBox->addItem( tr( "Align Pattern to Map Extent" ), static_cast<int>( Qgis::SymbolCoordinateReference::Viewport ) );
3168 connect( mCoordinateReferenceComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this] {
3169 if ( mLayer )
3170 {
3171 mLayer->setCoordinateReference( static_cast<Qgis::SymbolCoordinateReference>( mCoordinateReferenceComboBox->currentData().toInt() ) );
3172 emit changed();
3173 }
3174 } );
3175
3176 mSeedSpinBox->setShowClearButton( true );
3177 mSeedSpinBox->setClearValue( 0 );
3178 mRandomXSpinBox->setClearValue( 0 );
3179 mRandomYSpinBox->setClearValue( 0 );
3180
3183 connect( mRandomXSpinBox, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double d ) {
3184 if ( mLayer )
3185 {
3186 mLayer->setMaximumRandomDeviationX( d );
3187 emit changed();
3188 }
3189 } );
3190 connect( mRandomYSpinBox, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double d ) {
3191 if ( mLayer )
3192 {
3193 mLayer->setMaximumRandomDeviationY( d );
3194 emit changed();
3195 }
3196 } );
3197 connect( mRandomXOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
3198 if ( mLayer )
3199 {
3200 mLayer->setRandomDeviationXUnit( mRandomXOffsetUnitWidget->unit() );
3201 mLayer->setRandomDeviationXMapUnitScale( mRandomXOffsetUnitWidget->getMapUnitScale() );
3202 emit changed();
3203 }
3204 } );
3205 connect( mRandomYOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
3206 if ( mLayer )
3207 {
3208 mLayer->setRandomDeviationYUnit( mRandomYOffsetUnitWidget->unit() );
3209 mLayer->setRandomDeviationYMapUnitScale( mRandomYOffsetUnitWidget->getMapUnitScale() );
3210 emit changed();
3211 }
3212 } );
3213 connect( mSeedSpinBox, qOverload<int>( &QSpinBox::valueChanged ), this, [this]( int v ) {
3214 if ( mLayer )
3215 {
3216 mLayer->setSeed( v );
3217 emit changed();
3218 }
3219 } );
3220
3221 mAngleSpinBox->setShowClearButton( true );
3222 mAngleSpinBox->setClearValue( 0 );
3223 connect( mAngleSpinBox, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double d ) {
3224 if ( mLayer )
3225 {
3226 mLayer->setAngle( d );
3227 emit changed();
3228 }
3229 } );
3230}
3231
3233{
3234 if ( !layer || layer->layerType() != "PointPatternFill"_L1 )
3235 {
3236 return;
3237 }
3238
3239 mLayer = static_cast<QgsPointPatternFillSymbolLayer *>( layer );
3240 whileBlocking( mHorizontalDistanceSpinBox )->setValue( mLayer->distanceX() );
3241 whileBlocking( mVerticalDistanceSpinBox )->setValue( mLayer->distanceY() );
3242 whileBlocking( mHorizontalDisplacementSpinBox )->setValue( mLayer->displacementX() );
3243 whileBlocking( mVerticalDisplacementSpinBox )->setValue( mLayer->displacementY() );
3244 whileBlocking( mHorizontalOffsetSpinBox )->setValue( mLayer->offsetX() );
3245 whileBlocking( mVerticalOffsetSpinBox )->setValue( mLayer->offsetY() );
3246 whileBlocking( mAngleSpinBox )->setValue( mLayer->angle() );
3247
3248 mHorizontalDistanceUnitWidget->blockSignals( true );
3249 mHorizontalDistanceUnitWidget->setUnit( mLayer->distanceXUnit() );
3250 mHorizontalDistanceUnitWidget->setMapUnitScale( mLayer->distanceXMapUnitScale() );
3251 mHorizontalDistanceUnitWidget->blockSignals( false );
3252 mVerticalDistanceUnitWidget->blockSignals( true );
3253 mVerticalDistanceUnitWidget->setUnit( mLayer->distanceYUnit() );
3254 mVerticalDistanceUnitWidget->setMapUnitScale( mLayer->distanceYMapUnitScale() );
3255 mVerticalDistanceUnitWidget->blockSignals( false );
3256 mHorizontalDisplacementUnitWidget->blockSignals( true );
3257 mHorizontalDisplacementUnitWidget->setUnit( mLayer->displacementXUnit() );
3258 mHorizontalDisplacementUnitWidget->setMapUnitScale( mLayer->displacementXMapUnitScale() );
3259 mHorizontalDisplacementUnitWidget->blockSignals( false );
3260 mVerticalDisplacementUnitWidget->blockSignals( true );
3261 mVerticalDisplacementUnitWidget->setUnit( mLayer->displacementYUnit() );
3262 mVerticalDisplacementUnitWidget->setMapUnitScale( mLayer->displacementYMapUnitScale() );
3263 mVerticalDisplacementUnitWidget->blockSignals( false );
3264 mHorizontalOffsetUnitWidget->blockSignals( true );
3265 mHorizontalOffsetUnitWidget->setUnit( mLayer->offsetXUnit() );
3266 mHorizontalOffsetUnitWidget->setMapUnitScale( mLayer->offsetXMapUnitScale() );
3267 mHorizontalOffsetUnitWidget->blockSignals( false );
3268 mVerticalOffsetUnitWidget->blockSignals( true );
3269 mVerticalOffsetUnitWidget->setUnit( mLayer->offsetYUnit() );
3270 mVerticalOffsetUnitWidget->setMapUnitScale( mLayer->offsetYMapUnitScale() );
3271 mVerticalOffsetUnitWidget->blockSignals( false );
3272
3273 whileBlocking( mClipModeComboBox )->setCurrentIndex( mClipModeComboBox->findData( static_cast<int>( mLayer->clipMode() ) ) );
3274 whileBlocking( mCoordinateReferenceComboBox )->setCurrentIndex( mCoordinateReferenceComboBox->findData( static_cast<int>( mLayer->coordinateReference() ) ) );
3275
3276 whileBlocking( mRandomXSpinBox )->setValue( mLayer->maximumRandomDeviationX() );
3277 whileBlocking( mRandomYSpinBox )->setValue( mLayer->maximumRandomDeviationY() );
3278 whileBlocking( mRandomXOffsetUnitWidget )->setUnit( mLayer->randomDeviationXUnit() );
3279 whileBlocking( mRandomXOffsetUnitWidget )->setMapUnitScale( mLayer->randomDeviationXMapUnitScale() );
3280 whileBlocking( mRandomYOffsetUnitWidget )->setUnit( mLayer->randomDeviationYUnit() );
3281 whileBlocking( mRandomYOffsetUnitWidget )->setMapUnitScale( mLayer->randomDeviationYMapUnitScale() );
3282 whileBlocking( mSeedSpinBox )->setValue( mLayer->seed() );
3283
3296}
3297
3302
3303void QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceSpinBox_valueChanged( double d )
3304{
3305 if ( mLayer )
3306 {
3307 mLayer->setDistanceX( d );
3308 emit changed();
3309 }
3310}
3311
3312void QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceSpinBox_valueChanged( double d )
3313{
3314 if ( mLayer )
3315 {
3316 mLayer->setDistanceY( d );
3317 emit changed();
3318 }
3319}
3320
3321void QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementSpinBox_valueChanged( double d )
3322{
3323 if ( mLayer )
3324 {
3325 mLayer->setDisplacementX( d );
3326 emit changed();
3327 }
3328}
3329
3330void QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementSpinBox_valueChanged( double d )
3331{
3332 if ( mLayer )
3333 {
3334 mLayer->setDisplacementY( d );
3335 emit changed();
3336 }
3337}
3338
3339void QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetSpinBox_valueChanged( double d )
3340{
3341 if ( mLayer )
3342 {
3343 mLayer->setOffsetX( d );
3344 emit changed();
3345 }
3346}
3347
3348void QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetSpinBox_valueChanged( double d )
3349{
3350 if ( mLayer )
3351 {
3352 mLayer->setOffsetY( d );
3353 emit changed();
3354 }
3355}
3356
3357void QgsPointPatternFillSymbolLayerWidget::mHorizontalDistanceUnitWidget_changed()
3358{
3359 if ( mLayer )
3360 {
3361 mLayer->setDistanceXUnit( mHorizontalDistanceUnitWidget->unit() );
3362 mLayer->setDistanceXMapUnitScale( mHorizontalDistanceUnitWidget->getMapUnitScale() );
3363 emit changed();
3364 }
3365}
3366
3367void QgsPointPatternFillSymbolLayerWidget::mVerticalDistanceUnitWidget_changed()
3368{
3369 if ( mLayer )
3370 {
3371 mLayer->setDistanceYUnit( mVerticalDistanceUnitWidget->unit() );
3372 mLayer->setDistanceYMapUnitScale( mVerticalDistanceUnitWidget->getMapUnitScale() );
3373 emit changed();
3374 }
3375}
3376
3377void QgsPointPatternFillSymbolLayerWidget::mHorizontalDisplacementUnitWidget_changed()
3378{
3379 if ( mLayer )
3380 {
3381 mLayer->setDisplacementXUnit( mHorizontalDisplacementUnitWidget->unit() );
3382 mLayer->setDisplacementXMapUnitScale( mHorizontalDisplacementUnitWidget->getMapUnitScale() );
3383 emit changed();
3384 }
3385}
3386
3387void QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementUnitWidget_changed()
3388{
3389 if ( mLayer )
3390 {
3391 mLayer->setDisplacementYUnit( mVerticalDisplacementUnitWidget->unit() );
3392 mLayer->setDisplacementYMapUnitScale( mVerticalDisplacementUnitWidget->getMapUnitScale() );
3393 emit changed();
3394 }
3395}
3396
3397void QgsPointPatternFillSymbolLayerWidget::mHorizontalOffsetUnitWidget_changed()
3398{
3399 if ( mLayer )
3400 {
3401 mLayer->setOffsetXUnit( mHorizontalOffsetUnitWidget->unit() );
3402 mLayer->setOffsetXMapUnitScale( mHorizontalOffsetUnitWidget->getMapUnitScale() );
3403 emit changed();
3404 }
3405}
3406
3407void QgsPointPatternFillSymbolLayerWidget::mVerticalOffsetUnitWidget_changed()
3408{
3409 if ( mLayer )
3410 {
3411 mLayer->setOffsetYUnit( mVerticalOffsetUnitWidget->unit() );
3412 mLayer->setOffsetYMapUnitScale( mVerticalOffsetUnitWidget->getMapUnitScale() );
3413 emit changed();
3414 }
3415}
3416
3418
3420 : QgsSymbolLayerWidget( parent, vl )
3421{
3422 mLayer = nullptr;
3423
3424 setupUi( this );
3425
3426 mHorizontalAnchorComboBox->addItem( tr( "Left" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Left ) );
3427 mHorizontalAnchorComboBox->addItem( tr( "Horizontal Center" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Center ) );
3428 mHorizontalAnchorComboBox->addItem( tr( "Right" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Right ) );
3429
3430 mVerticalAnchorComboBox->addItem( tr( "Top" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Top ) );
3431 mVerticalAnchorComboBox->addItem( tr( "Vertical Center" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Center ) );
3432 mVerticalAnchorComboBox->addItem( tr( "Bottom on Baseline" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Baseline ) );
3433 mVerticalAnchorComboBox->addItem( tr( "Bottom" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Bottom ) );
3434
3435 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
3436 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
3437 connect( mStrokeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed );
3438 connect( mStrokeWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged );
3439 connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
3440 connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
3444
3446 scrollArea->setWidget( widgetChar );
3447 scrollArea->setVerticalOnly( true );
3448
3449 btnColor->setAllowOpacity( true );
3450 btnColor->setColorDialogTitle( tr( "Select Symbol Fill Color" ) );
3451 btnColor->setContext( u"symbology"_s );
3452 btnStrokeColor->setAllowOpacity( true );
3453 btnStrokeColor->setColorDialogTitle( tr( "Select Symbol Stroke Color" ) );
3454 btnStrokeColor->setContext( u"symbology"_s );
3455
3456 mColorDDBtn->registerLinkedWidget( btnColor );
3457 mStrokeColorDDBtn->registerLinkedWidget( btnStrokeColor );
3458
3459 spinOffsetX->setClearValue( 0.0 );
3460 spinOffsetY->setClearValue( 0.0 );
3461 spinAngle->setClearValue( 0.0 );
3462
3463 //make a temporary symbol for the size assistant preview
3464 mAssistantPreviewSymbol = std::make_shared<QgsMarkerSymbol>();
3465
3466 if ( vectorLayer() )
3467 mSizeDDBtn->setSymbol( mAssistantPreviewSymbol );
3468
3469 connect( cboFont, &QFontComboBox::currentFontChanged, this, &QgsFontMarkerSymbolLayerWidget::setFontFamily );
3470 connect( mFontStyleComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::mFontStyleComboBox_currentIndexChanged );
3471 connect( spinSize, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setSize );
3472 connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::penJoinStyleChanged );
3475 connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFontMarkerSymbolLayerWidget::penJoinStyleChanged );
3476 connect( spinAngle, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setAngle );
3477 connect( spinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setOffset );
3478 connect( spinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setOffset );
3480 connect( mCharLineEdit, &QLineEdit::textChanged, this, &QgsFontMarkerSymbolLayerWidget::setCharacterFromText );
3481
3482 connect( this, &QgsSymbolLayerWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::updateAssistantSymbol );
3483}
3484
3486
3488{
3489 if ( layer->layerType() != "FontMarker"_L1 )
3490 return;
3491
3492 // layer type is correct, we can do the cast
3493 mLayer = static_cast<QgsFontMarkerSymbolLayer *>( layer );
3494
3495 QgsFontUtils::setFontFamily( mRefFont, mLayer->fontFamily() );
3496 mRefFont.setStyleName( QgsFontUtils::translateNamedStyle( mLayer->fontStyle() ) );
3497
3498 mFontStyleComboBox->blockSignals( true );
3499 populateFontStyleComboBox();
3500 mFontStyleComboBox->blockSignals( false );
3501
3502 // set values
3503 whileBlocking( cboFont )->setCurrentFont( mRefFont );
3504 whileBlocking( spinSize )->setValue( mLayer->size() );
3505 whileBlocking( btnColor )->setColor( mLayer->color() );
3506 whileBlocking( btnStrokeColor )->setColor( mLayer->strokeColor() );
3507 whileBlocking( mStrokeWidthSpinBox )->setValue( mLayer->strokeWidth() );
3508 whileBlocking( spinAngle )->setValue( mLayer->angle() );
3509
3510 widgetChar->blockSignals( true );
3511 widgetChar->setFont( mRefFont );
3512 if ( mLayer->character().length() == 1 )
3513 {
3514 widgetChar->setCharacter( mLayer->character().at( 0 ) );
3515 }
3516 widgetChar->blockSignals( false );
3517 whileBlocking( mCharLineEdit )->setText( mLayer->character() );
3518 mCharPreview->setFont( mRefFont );
3519
3520 //block
3521 whileBlocking( spinOffsetX )->setValue( mLayer->offset().x() );
3522 whileBlocking( spinOffsetY )->setValue( mLayer->offset().y() );
3523
3524 mSizeUnitWidget->blockSignals( true );
3525 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
3526 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
3527 mSizeUnitWidget->blockSignals( false );
3528
3529 mStrokeWidthUnitWidget->blockSignals( true );
3530 mStrokeWidthUnitWidget->setUnit( mLayer->strokeWidthUnit() );
3531 mStrokeWidthUnitWidget->setMapUnitScale( mLayer->strokeWidthMapUnitScale() );
3532 mStrokeWidthUnitWidget->blockSignals( false );
3533
3534 mOffsetUnitWidget->blockSignals( true );
3535 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
3536 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
3537 mOffsetUnitWidget->blockSignals( false );
3538
3539 whileBlocking( cboJoinStyle )->setPenJoinStyle( mLayer->penJoinStyle() );
3540
3541 //anchor points
3542 whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mHorizontalAnchorComboBox->findData( QVariant::fromValue( mLayer->horizontalAnchorPoint() ) ) );
3543 whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mVerticalAnchorComboBox->findData( QVariant::fromValue( mLayer->verticalAnchorPoint() ) ) );
3544
3557
3558 updateAssistantSymbol();
3559}
3560
3565
3567{
3568 if ( mLayer )
3569 {
3570 mLayer->setFontFamily( font.family() );
3571 QgsFontUtils::setFontFamily( mRefFont, font.family() );
3572 widgetChar->setFont( mRefFont );
3573 mCharPreview->setFont( mRefFont );
3574 populateFontStyleComboBox();
3575 emit changed();
3576 }
3577}
3578
3579void QgsFontMarkerSymbolLayerWidget::setFontStyle( const QString &style )
3580{
3581 if ( mLayer )
3582 {
3583 QgsFontUtils::updateFontViaStyle( mRefFont, style );
3585 widgetChar->setFont( mRefFont );
3586 mCharPreview->setFont( mRefFont );
3587 emit changed();
3588 }
3589}
3590
3592{
3593 mLayer->setColor( color );
3594 emit changed();
3595}
3596
3598{
3599 mLayer->setStrokeColor( color );
3600 emit changed();
3601}
3602
3604{
3605 mLayer->setSize( size );
3606 //widgetChar->updateSize(size);
3607 emit changed();
3608}
3609
3611{
3612 mLayer->setAngle( angle );
3613 emit changed();
3614}
3615
3617{
3618 mCharPreview->setText( text );
3619
3620 if ( text.isEmpty() )
3621 return;
3622
3623 // take the last character of a string for a better experience when users cycle through several characters on their keyboard
3624 QString character = text;
3625 if ( text.contains( QRegularExpression( u"^0x[0-9a-fA-F]{1,4}$"_s ) ) )
3626 {
3627 bool ok = false;
3628 const unsigned int value = text.toUInt( &ok, 0 );
3629 if ( ok )
3630 {
3631 character = QChar( value );
3632 mCharPreview->setText( character );
3633 }
3634 }
3635
3636 if ( character != mLayer->character() )
3637 {
3638 mLayer->setCharacter( character );
3639 if ( mLayer->character().length() == 1 )
3640 {
3641 whileBlocking( widgetChar )->setCharacter( mLayer->character().at( 0 ) );
3642 }
3643 else
3644 {
3645 widgetChar->clearCharacter();
3646 }
3647 emit changed();
3648 }
3649}
3650
3652{
3653 if ( mLayer->character().length() > 1 || QGuiApplication::keyboardModifiers() & Qt::ControlModifier )
3654 {
3655 mCharLineEdit->insert( chr );
3656 return;
3657 }
3658
3659 mLayer->setCharacter( chr );
3660 whileBlocking( mCharLineEdit )->setText( chr );
3661 mCharPreview->setText( chr );
3662 emit changed();
3663}
3664
3665void QgsFontMarkerSymbolLayerWidget::setOffset()
3666{
3667 mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
3668 emit changed();
3669}
3670
3671void QgsFontMarkerSymbolLayerWidget::penJoinStyleChanged()
3672{
3673 mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
3674 emit changed();
3675}
3676
3677void QgsFontMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
3678{
3679 if ( mLayer )
3680 {
3681 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
3682 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
3683 emit changed();
3684 }
3685}
3686
3687void QgsFontMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
3688{
3689 if ( mLayer )
3690 {
3691 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
3692 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
3693 emit changed();
3694 }
3695}
3696
3697void QgsFontMarkerSymbolLayerWidget::mStrokeWidthUnitWidget_changed()
3698{
3699 if ( mLayer )
3700 {
3701 mLayer->setStrokeWidthUnit( mSizeUnitWidget->unit() );
3702 mLayer->setStrokeWidthMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
3703 emit changed();
3704 }
3705}
3706
3707void QgsFontMarkerSymbolLayerWidget::populateFontStyleComboBox()
3708{
3709 mFontStyleComboBox->clear();
3710 const QStringList styles = mFontDB.styles( mRefFont.family() );
3711 const auto constStyles = styles;
3712 for ( const QString &style : constStyles )
3713 {
3714 mFontStyleComboBox->addItem( style );
3715 }
3716
3717 QString targetStyle = mFontDB.styleString( mRefFont );
3718 if ( !styles.contains( targetStyle ) )
3719 {
3720 const QFont f = QgsFontUtils::createFont( mRefFont.family() );
3721 targetStyle = QFontInfo( f ).styleName();
3722 mRefFont.setStyleName( targetStyle );
3723 }
3724 int curIndx = 0;
3725 const int stylIndx = mFontStyleComboBox->findText( targetStyle );
3726 if ( stylIndx > -1 )
3727 {
3728 curIndx = stylIndx;
3729 }
3730
3731 mFontStyleComboBox->setCurrentIndex( curIndx );
3732}
3733
3734void QgsFontMarkerSymbolLayerWidget::mFontStyleComboBox_currentIndexChanged( int index )
3735{
3736 Q_UNUSED( index );
3737 setFontStyle( mFontStyleComboBox->currentText() );
3738}
3739
3740void QgsFontMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int )
3741{
3742 if ( mLayer )
3743 {
3744 mLayer->setHorizontalAnchorPoint( mHorizontalAnchorComboBox->currentData().value< Qgis::HorizontalAnchorPoint >() );
3745 emit changed();
3746 }
3747}
3748
3749void QgsFontMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int )
3750{
3751 if ( mLayer )
3752 {
3753 mLayer->setVerticalAnchorPoint( mVerticalAnchorComboBox->currentData().value< Qgis::VerticalAnchorPoint >() );
3754 emit changed();
3755 }
3756}
3757
3758void QgsFontMarkerSymbolLayerWidget::mStrokeWidthSpinBox_valueChanged( double d )
3759{
3760 if ( mLayer )
3761 {
3762 mLayer->setStrokeWidth( d );
3763 emit changed();
3764 }
3765}
3766
3767void QgsFontMarkerSymbolLayerWidget::updateAssistantSymbol()
3768{
3769 for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1; i >= 0; --i )
3770 {
3771 mAssistantPreviewSymbol->deleteSymbolLayer( i );
3772 }
3773 mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
3774 const QgsProperty ddSize = mLayer->dataDefinedProperties().property( QgsSymbolLayer::Property::Size );
3775 if ( ddSize )
3776 mAssistantPreviewSymbol->setDataDefinedSize( ddSize );
3777}
3778
3780
3781
3783 : QgsSymbolLayerWidget( parent, vl )
3784{
3785 mLayer = nullptr;
3786
3787 setupUi( this );
3788 connect( mDrawInsideCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mDrawInsideCheckBox_stateChanged );
3789 connect( mDrawAllPartsCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mDrawAllPartsCheckBox_stateChanged );
3790 connect( mClipPointsCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mClipPointsCheckBox_stateChanged );
3791 connect( mClipOnCurrentPartOnlyCheckBox, &QCheckBox::stateChanged, this, &QgsCentroidFillSymbolLayerWidget::mClipOnCurrentPartOnlyCheckBox_stateChanged );
3792}
3793
3795{
3796 if ( layer->layerType() != "CentroidFill"_L1 )
3797 return;
3798
3799 // layer type is correct, we can do the cast
3800 mLayer = static_cast<QgsCentroidFillSymbolLayer *>( layer );
3801
3802 // set values
3803 whileBlocking( mDrawInsideCheckBox )->setChecked( mLayer->pointOnSurface() );
3804 whileBlocking( mDrawAllPartsCheckBox )->setChecked( mLayer->pointOnAllParts() );
3805 whileBlocking( mClipPointsCheckBox )->setChecked( mLayer->clipPoints() );
3806 whileBlocking( mClipOnCurrentPartOnlyCheckBox )->setChecked( mLayer->clipOnCurrentPartOnly() );
3807}
3808
3813
3814void QgsCentroidFillSymbolLayerWidget::mDrawInsideCheckBox_stateChanged( int state )
3815{
3816 mLayer->setPointOnSurface( state == Qt::Checked );
3817 emit changed();
3818}
3819
3820void QgsCentroidFillSymbolLayerWidget::mDrawAllPartsCheckBox_stateChanged( int state )
3821{
3822 mLayer->setPointOnAllParts( state == Qt::Checked );
3823 emit changed();
3824}
3825
3826void QgsCentroidFillSymbolLayerWidget::mClipPointsCheckBox_stateChanged( int state )
3827{
3828 mLayer->setClipPoints( state == Qt::Checked );
3829 emit changed();
3830}
3831
3832void QgsCentroidFillSymbolLayerWidget::mClipOnCurrentPartOnlyCheckBox_stateChanged( int state )
3833{
3834 mLayer->setClipOnCurrentPartOnly( state == Qt::Checked );
3835 emit changed();
3836}
3837
3839
3841 : QgsSymbolLayerWidget( parent, vl )
3842{
3843 mLayer = nullptr;
3844
3845 setupUi( this );
3846
3847 mHorizontalAnchorComboBox->addItem( tr( "Left" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Left ) );
3848 mHorizontalAnchorComboBox->addItem( tr( "Horizontal Center" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Center ) );
3849 mHorizontalAnchorComboBox->addItem( tr( "Right" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Right ) );
3850
3851 mVerticalAnchorComboBox->addItem( tr( "Top" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Top ) );
3852 mVerticalAnchorComboBox->addItem( tr( "Vertical Center" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Center ) );
3853 mVerticalAnchorComboBox->addItem( tr( "Bottom" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Bottom ) );
3854
3855 mImageSourceLineEdit->setLastPathSettingsKey( u"/UI/lastRasterMarkerImageDir"_s );
3856
3857 connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsRasterMarkerSymbolLayerWidget::imageSourceChanged );
3858 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
3859 connect( mRotationSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setAngle );
3860 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
3861 connect( mWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setWidth );
3862 connect( mHeightSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setHeight );
3863 connect( mLockAspectRatio, static_cast<void ( QgsRatioLockButton::* )( bool )>( &QgsRatioLockButton::lockChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setLockAspectRatio );
3864
3867
3868 mSpinOffsetX->setClearValue( 0.0 );
3869 mSpinOffsetY->setClearValue( 0.0 );
3870 mRotationSpinBox->setClearValue( 0.0 );
3871
3872 connect( mSpinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setOffset );
3873 connect( mSpinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterMarkerSymbolLayerWidget::setOffset );
3874 connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsRasterMarkerSymbolLayerWidget::setOpacity );
3875
3876 connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
3877 connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
3878}
3879
3881{
3882 if ( !layer )
3883 {
3884 return;
3885 }
3886
3887 if ( layer->layerType() != "RasterMarker"_L1 )
3888 return;
3889
3890 // layer type is correct, we can do the cast
3891 mLayer = static_cast<QgsRasterMarkerSymbolLayer *>( layer );
3892
3893 // set values
3894 whileBlocking( mImageSourceLineEdit )->setSource( mLayer->path() );
3895
3896 whileBlocking( mWidthSpinBox )->setValue( mLayer->size() );
3897 const bool preservedAspectRatio = mLayer->preservedAspectRatio();
3898 mHeightSpinBox->blockSignals( true );
3899 if ( preservedAspectRatio )
3900 {
3901 mHeightSpinBox->setValue( mLayer->size() );
3902 }
3903 else
3904 {
3905 mHeightSpinBox->setValue( mLayer->size() * mLayer->fixedAspectRatio() );
3906 }
3907 mHeightSpinBox->setEnabled( mLayer->defaultAspectRatio() > 0.0 );
3908 mHeightSpinBox->blockSignals( false );
3909 whileBlocking( mLockAspectRatio )->setLocked( preservedAspectRatio );
3910
3911 whileBlocking( mRotationSpinBox )->setValue( mLayer->angle() );
3912 whileBlocking( mOpacityWidget )->setOpacity( mLayer->opacity() );
3913
3914 whileBlocking( mSpinOffsetX )->setValue( mLayer->offset().x() );
3915 whileBlocking( mSpinOffsetY )->setValue( mLayer->offset().y() );
3916
3917 mSizeUnitWidget->blockSignals( true );
3918 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
3919 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
3920 mSizeUnitWidget->blockSignals( false );
3921 mOffsetUnitWidget->blockSignals( true );
3922 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
3923 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
3924 mOffsetUnitWidget->blockSignals( false );
3925
3926 //anchor points
3927 whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mHorizontalAnchorComboBox->findData( QVariant::fromValue( mLayer->horizontalAnchorPoint() ) ) );
3928 whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mVerticalAnchorComboBox->findData( QVariant::fromValue( mLayer->verticalAnchorPoint() ) ) );
3929
3938
3939 updatePreviewImage();
3940}
3941
3946
3948{
3950 mImageSourceLineEdit->setMessageBar( context.messageBar() );
3951}
3952
3953void QgsRasterMarkerSymbolLayerWidget::imageSourceChanged( const QString &text )
3954{
3955 mLayer->setPath( text );
3956 updatePreviewImage();
3957 emit changed();
3958}
3959
3960void QgsRasterMarkerSymbolLayerWidget::updatePreviewImage()
3961{
3962 bool fitsInCache = false;
3963 const QImage image = QgsApplication::imageCache()->pathAsImage( mLayer->path(), QSize( 150, 150 ), true, 1.0, fitsInCache );
3964 if ( image.isNull() )
3965 {
3966 mLabelImagePreview->setPixmap( QPixmap() );
3967 return;
3968 }
3969
3970 QImage previewImage( 150, 150, QImage::Format_ARGB32 );
3971 previewImage.fill( Qt::transparent );
3972 const QRect imageRect( ( 150 - image.width() ) / 2.0, ( 150 - image.height() ) / 2.0, image.width(), image.height() );
3973 QPainter p;
3974 p.begin( &previewImage );
3975 //draw a checkerboard background
3976 uchar pixDataRGB[] = { 150, 150, 150, 150, 100, 100, 100, 150, 100, 100, 100, 150, 150, 150, 150, 150 };
3977 const QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
3978 const QPixmap pix = QPixmap::fromImage( img.scaled( 8, 8 ) );
3979 QBrush checkerBrush;
3980 checkerBrush.setTexture( pix );
3981 p.fillRect( imageRect, checkerBrush );
3982
3983 if ( mLayer->opacity() < 1.0 )
3984 {
3985 p.setOpacity( mLayer->opacity() );
3986 }
3987
3988 p.drawImage( imageRect.left(), imageRect.top(), image );
3989 p.end();
3990 mLabelImagePreview->setPixmap( QPixmap::fromImage( previewImage ) );
3991}
3992
3993void QgsRasterMarkerSymbolLayerWidget::setWidth()
3994{
3995 const double defaultAspectRatio = mLayer->defaultAspectRatio();
3996 double fixedAspectRatio = 0.0;
3997 mHeightSpinBox->blockSignals( true );
3998 if ( defaultAspectRatio <= 0.0 )
3999 {
4000 mHeightSpinBox->setValue( mWidthSpinBox->value() );
4001 }
4002 else if ( mLockAspectRatio->locked() )
4003 {
4004 mHeightSpinBox->setValue( mWidthSpinBox->value() * defaultAspectRatio );
4005 }
4006 else
4007 {
4008 fixedAspectRatio = mHeightSpinBox->value() / mWidthSpinBox->value();
4009 }
4010 mHeightSpinBox->blockSignals( false );
4011 mLayer->setSize( mWidthSpinBox->value() );
4012 mLayer->setFixedAspectRatio( fixedAspectRatio );
4013 emit changed();
4014}
4015
4016void QgsRasterMarkerSymbolLayerWidget::setHeight()
4017{
4018 const double defaultAspectRatio = mLayer->defaultAspectRatio();
4019 double fixedAspectRatio = 0.0;
4020 mWidthSpinBox->blockSignals( true );
4021 if ( defaultAspectRatio <= 0.0 )
4022 {
4023 mWidthSpinBox->setValue( mHeightSpinBox->value() );
4024 }
4025 else if ( mLockAspectRatio->locked() )
4026 {
4027 mWidthSpinBox->setValue( mHeightSpinBox->value() / defaultAspectRatio );
4028 }
4029 else
4030 {
4031 fixedAspectRatio = mHeightSpinBox->value() / mWidthSpinBox->value();
4032 }
4033 mWidthSpinBox->blockSignals( false );
4034 mLayer->setSize( mWidthSpinBox->value() );
4035 mLayer->setFixedAspectRatio( fixedAspectRatio );
4036 emit changed();
4037}
4038
4039void QgsRasterMarkerSymbolLayerWidget::setLockAspectRatio( const bool locked )
4040{
4041 const double defaultAspectRatio = mLayer->defaultAspectRatio();
4042 if ( defaultAspectRatio <= 0.0 )
4043 {
4044 whileBlocking( mLockAspectRatio )->setLocked( true );
4045 }
4046 else if ( locked )
4047 {
4048 mLayer->setFixedAspectRatio( 0.0 );
4049 setWidth();
4050 }
4051 else
4052 {
4053 mLayer->setFixedAspectRatio( mHeightSpinBox->value() / mWidthSpinBox->value() );
4054 }
4055}
4056
4057void QgsRasterMarkerSymbolLayerWidget::setAngle()
4058{
4059 mLayer->setAngle( mRotationSpinBox->value() );
4060 emit changed();
4061}
4062
4063void QgsRasterMarkerSymbolLayerWidget::setOpacity( double value )
4064{
4065 mLayer->setOpacity( value );
4066 emit changed();
4067 updatePreviewImage();
4068}
4069
4070void QgsRasterMarkerSymbolLayerWidget::setOffset()
4071{
4072 mLayer->setOffset( QPointF( mSpinOffsetX->value(), mSpinOffsetY->value() ) );
4073 emit changed();
4074}
4075
4076void QgsRasterMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
4077{
4078 if ( mLayer )
4079 {
4080 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
4081 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
4082 emit changed();
4083 }
4084}
4085
4086void QgsRasterMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
4087{
4088 if ( mLayer )
4089 {
4090 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
4091 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
4092 emit changed();
4093 }
4094}
4095
4096void QgsRasterMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int )
4097{
4098 if ( mLayer )
4099 {
4100 mLayer->setHorizontalAnchorPoint( mHorizontalAnchorComboBox->currentData().value< Qgis::HorizontalAnchorPoint >() );
4101 emit changed();
4102 }
4103}
4104
4105void QgsRasterMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int )
4106{
4107 if ( mLayer )
4108 {
4109 mLayer->setVerticalAnchorPoint( mVerticalAnchorComboBox->currentData().value< Qgis::VerticalAnchorPoint >() );
4110 emit changed();
4111 }
4112}
4113
4114
4116
4118 : QgsSymbolLayerWidget( parent, vl )
4119{
4120 mLayer = nullptr;
4121
4122 setupUi( this );
4123
4124 mHorizontalAnchorComboBox->addItem( tr( "Left" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Left ) );
4125 mHorizontalAnchorComboBox->addItem( tr( "Horizontal Center" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Center ) );
4126 mHorizontalAnchorComboBox->addItem( tr( "Right" ), QVariant::fromValue( Qgis::HorizontalAnchorPoint::Right ) );
4127
4128 mVerticalAnchorComboBox->addItem( tr( "Top" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Top ) );
4129 mVerticalAnchorComboBox->addItem( tr( "Vertical Center" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Center ) );
4130 mVerticalAnchorComboBox->addItem( tr( "Bottom" ), QVariant::fromValue( Qgis::VerticalAnchorPoint::Bottom ) );
4131
4132 mImageSourceLineEdit->setLastPathSettingsKey( u"/UI/lastAnimatedMarkerImageDir"_s );
4133
4134 connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsAnimatedMarkerSymbolLayerWidget::imageSourceChanged );
4135 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsAnimatedMarkerSymbolLayerWidget::mOffsetUnitWidget_changed );
4136 connect( mRotationSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::setAngle );
4137 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsAnimatedMarkerSymbolLayerWidget::mSizeUnitWidget_changed );
4138 connect( mWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::setWidth );
4139 connect( mHeightSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::setHeight );
4140 connect( mLockAspectRatio, static_cast<void ( QgsRatioLockButton::* )( bool )>( &QgsRatioLockButton::lockChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::setLockAspectRatio );
4141
4142 mFrameRateSpin->setClearValue( 10 );
4143 mFrameRateSpin->setShowClearButton( true );
4144 connect( mFrameRateSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double value ) {
4145 mLayer->setFrameRate( value );
4146 emit changed();
4147 } );
4148
4151
4152 mSpinOffsetX->setClearValue( 0.0 );
4153 mSpinOffsetY->setClearValue( 0.0 );
4154 mRotationSpinBox->setClearValue( 0.0 );
4155
4156 connect( mSpinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::setOffset );
4157 connect( mSpinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::setOffset );
4158 connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsAnimatedMarkerSymbolLayerWidget::setOpacity );
4159
4160 connect( mHorizontalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged );
4161 connect( mVerticalAnchorComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsAnimatedMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged );
4162}
4163
4165{
4166 if ( !layer )
4167 {
4168 return;
4169 }
4170
4171 if ( layer->layerType() != "AnimatedMarker"_L1 )
4172 return;
4173
4174 // layer type is correct, we can do the cast
4175 mLayer = static_cast<QgsAnimatedMarkerSymbolLayer *>( layer );
4176
4177 // set values
4178 whileBlocking( mImageSourceLineEdit )->setSource( mLayer->path() );
4179
4180 const double firstFrameTime = QgsApplication::imageCache()->nextFrameDelay( mLayer->path() );
4181 if ( firstFrameTime > 0 )
4182 {
4183 mFrameRateSpin->setClearValue( 1000 / firstFrameTime );
4184 }
4185 else
4186 {
4187 mFrameRateSpin->setClearValue( 10 );
4188 }
4189
4190 whileBlocking( mWidthSpinBox )->setValue( mLayer->size() );
4191 const bool preservedAspectRatio = mLayer->preservedAspectRatio();
4192 mHeightSpinBox->blockSignals( true );
4193 if ( preservedAspectRatio )
4194 {
4195 mHeightSpinBox->setValue( mLayer->size() );
4196 }
4197 else
4198 {
4199 mHeightSpinBox->setValue( mLayer->size() * mLayer->fixedAspectRatio() );
4200 }
4201 mHeightSpinBox->setEnabled( mLayer->defaultAspectRatio() > 0.0 );
4202 mHeightSpinBox->blockSignals( false );
4203 whileBlocking( mLockAspectRatio )->setLocked( preservedAspectRatio );
4204
4205 whileBlocking( mRotationSpinBox )->setValue( mLayer->angle() );
4206 whileBlocking( mOpacityWidget )->setOpacity( mLayer->opacity() );
4207
4208 whileBlocking( mSpinOffsetX )->setValue( mLayer->offset().x() );
4209 whileBlocking( mSpinOffsetY )->setValue( mLayer->offset().y() );
4210
4211 whileBlocking( mFrameRateSpin )->setValue( mLayer->frameRate() );
4212
4213 mSizeUnitWidget->blockSignals( true );
4214 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
4215 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
4216 mSizeUnitWidget->blockSignals( false );
4217 mOffsetUnitWidget->blockSignals( true );
4218 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
4219 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
4220 mOffsetUnitWidget->blockSignals( false );
4221
4222 //anchor points
4223 whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mHorizontalAnchorComboBox->findData( QVariant::fromValue( mLayer->horizontalAnchorPoint() ) ) );
4224 whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mVerticalAnchorComboBox->findData( QVariant::fromValue( mLayer->verticalAnchorPoint() ) ) );
4225
4234
4235 updatePreviewImage();
4236}
4237
4242
4244{
4246 mImageSourceLineEdit->setMessageBar( context.messageBar() );
4247}
4248
4249void QgsAnimatedMarkerSymbolLayerWidget::imageSourceChanged( const QString &text )
4250{
4251 mLayer->setPath( text );
4252
4253 const double firstFrameTime = QgsApplication::imageCache()->nextFrameDelay( text );
4254 if ( firstFrameTime > 0 )
4255 {
4256 mFrameRateSpin->setClearValue( 1000 / firstFrameTime );
4257 }
4258 else
4259 {
4260 mFrameRateSpin->setClearValue( 10 );
4261 }
4262 updatePreviewImage();
4263 emit changed();
4264}
4265
4266void QgsAnimatedMarkerSymbolLayerWidget::updatePreviewImage()
4267{
4268 if ( mPreviewMovie )
4269 {
4270 mLabelImagePreview->setMovie( nullptr );
4271 mPreviewMovie->deleteLater();
4272 mPreviewMovie = nullptr;
4273 }
4274
4275 mPreviewMovie = new QMovie( mLayer->path(), QByteArray(), this );
4276 mPreviewMovie->setScaledSize( QSize( 150, 150 ) );
4277 mLabelImagePreview->setMovie( mPreviewMovie );
4278 mPreviewMovie->start();
4279}
4280
4281void QgsAnimatedMarkerSymbolLayerWidget::setWidth()
4282{
4283 const double defaultAspectRatio = mLayer->defaultAspectRatio();
4284 double fixedAspectRatio = 0.0;
4285 mHeightSpinBox->blockSignals( true );
4286 if ( defaultAspectRatio <= 0.0 )
4287 {
4288 mHeightSpinBox->setValue( mWidthSpinBox->value() );
4289 }
4290 else if ( mLockAspectRatio->locked() )
4291 {
4292 mHeightSpinBox->setValue( mWidthSpinBox->value() * defaultAspectRatio );
4293 }
4294 else
4295 {
4296 fixedAspectRatio = mHeightSpinBox->value() / mWidthSpinBox->value();
4297 }
4298 mHeightSpinBox->blockSignals( false );
4299 mLayer->setSize( mWidthSpinBox->value() );
4300 mLayer->setFixedAspectRatio( fixedAspectRatio );
4301 emit changed();
4302}
4303
4304void QgsAnimatedMarkerSymbolLayerWidget::setHeight()
4305{
4306 const double defaultAspectRatio = mLayer->defaultAspectRatio();
4307 double fixedAspectRatio = 0.0;
4308 mWidthSpinBox->blockSignals( true );
4309 if ( defaultAspectRatio <= 0.0 )
4310 {
4311 mWidthSpinBox->setValue( mHeightSpinBox->value() );
4312 }
4313 else if ( mLockAspectRatio->locked() )
4314 {
4315 mWidthSpinBox->setValue( mHeightSpinBox->value() / defaultAspectRatio );
4316 }
4317 else
4318 {
4319 fixedAspectRatio = mHeightSpinBox->value() / mWidthSpinBox->value();
4320 }
4321 mWidthSpinBox->blockSignals( false );
4322 mLayer->setSize( mWidthSpinBox->value() );
4323 mLayer->setFixedAspectRatio( fixedAspectRatio );
4324 emit changed();
4325}
4326
4327void QgsAnimatedMarkerSymbolLayerWidget::setLockAspectRatio( const bool locked )
4328{
4329 const double defaultAspectRatio = mLayer->defaultAspectRatio();
4330 if ( defaultAspectRatio <= 0.0 )
4331 {
4332 whileBlocking( mLockAspectRatio )->setLocked( true );
4333 }
4334 else if ( locked )
4335 {
4336 mLayer->setFixedAspectRatio( 0.0 );
4337 setWidth();
4338 }
4339 else
4340 {
4341 mLayer->setFixedAspectRatio( mHeightSpinBox->value() / mWidthSpinBox->value() );
4342 }
4343}
4344
4345void QgsAnimatedMarkerSymbolLayerWidget::setAngle()
4346{
4347 mLayer->setAngle( mRotationSpinBox->value() );
4348 emit changed();
4349}
4350
4351void QgsAnimatedMarkerSymbolLayerWidget::setOpacity( double value )
4352{
4353 mLayer->setOpacity( value );
4354 emit changed();
4355 updatePreviewImage();
4356}
4357
4358void QgsAnimatedMarkerSymbolLayerWidget::setOffset()
4359{
4360 mLayer->setOffset( QPointF( mSpinOffsetX->value(), mSpinOffsetY->value() ) );
4361 emit changed();
4362}
4363
4364void QgsAnimatedMarkerSymbolLayerWidget::mSizeUnitWidget_changed()
4365{
4366 if ( mLayer )
4367 {
4368 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
4369 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
4370 emit changed();
4371 }
4372}
4373
4374void QgsAnimatedMarkerSymbolLayerWidget::mOffsetUnitWidget_changed()
4375{
4376 if ( mLayer )
4377 {
4378 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
4379 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
4380 emit changed();
4381 }
4382}
4383
4384void QgsAnimatedMarkerSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int )
4385{
4386 if ( mLayer )
4387 {
4388 mLayer->setHorizontalAnchorPoint( mHorizontalAnchorComboBox->currentData().value< Qgis::HorizontalAnchorPoint >() );
4389 emit changed();
4390 }
4391}
4392
4393void QgsAnimatedMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged( int )
4394{
4395 if ( mLayer )
4396 {
4397 mLayer->setVerticalAnchorPoint( mVerticalAnchorComboBox->currentData().value< Qgis::VerticalAnchorPoint >() );
4398 emit changed();
4399 }
4400}
4401
4403
4405 : QgsSymbolLayerWidget( parent, vl )
4406{
4407 mLayer = nullptr;
4408 setupUi( this );
4409
4410 mImageSourceLineEdit->setLastPathSettingsKey( u"/UI/lastRasterMarkerImageDir"_s );
4411 connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsRasterFillSymbolLayerWidget::imageSourceChanged );
4412
4413 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRasterFillSymbolLayerWidget::mOffsetUnitWidget_changed );
4414 connect( mRotationSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::mRotationSpinBox_valueChanged );
4415
4416 connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
4417 if ( !mLayer )
4418 {
4419 return;
4420 }
4421 mLayer->setSizeUnit( mSizeUnitWidget->unit() );
4422 mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
4423 emit changed();
4424 } );
4425 connect( mWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, [this]( double d ) {
4426 if ( !mLayer )
4427 {
4428 return;
4429 }
4430 mLayer->setWidth( d );
4431 emit changed();
4432 } );
4433
4434 connect( mHeightSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, [this]( double d ) {
4435 if ( !mLayer )
4436 {
4437 return;
4438 }
4439 mLayer->setHeight( d );
4440 emit changed();
4441 } );
4442
4445
4446 mSpinOffsetX->setClearValue( 0.0 );
4447 mSpinOffsetY->setClearValue( 0.0 );
4448 mRotationSpinBox->setClearValue( 0.0 );
4449
4450 connect( cboCoordinateMode, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterFillSymbolLayerWidget::setCoordinateMode );
4451 connect( mSpinOffsetX, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::offsetChanged );
4452 connect( mSpinOffsetY, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterFillSymbolLayerWidget::offsetChanged );
4453 connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsRasterFillSymbolLayerWidget::opacityChanged );
4454}
4455
4456
4458{
4459 if ( !layer )
4460 {
4461 return;
4462 }
4463
4464 if ( layer->layerType() != "RasterFill"_L1 )
4465 {
4466 return;
4467 }
4468
4469 mLayer = dynamic_cast<QgsRasterFillSymbolLayer *>( layer );
4470 if ( !mLayer )
4471 {
4472 return;
4473 }
4474
4475 whileBlocking( mImageSourceLineEdit )->setSource( mLayer->imageFilePath() );
4476
4477 cboCoordinateMode->blockSignals( true );
4478 switch ( mLayer->coordinateMode() )
4479 {
4481 cboCoordinateMode->setCurrentIndex( 1 );
4482 break;
4484 default:
4485 cboCoordinateMode->setCurrentIndex( 0 );
4486 break;
4487 }
4488 cboCoordinateMode->blockSignals( false );
4489 whileBlocking( mOpacityWidget )->setOpacity( mLayer->opacity() );
4490 whileBlocking( mRotationSpinBox )->setValue( mLayer->angle() );
4491
4492 whileBlocking( mSpinOffsetX )->setValue( mLayer->offset().x() );
4493 whileBlocking( mSpinOffsetY )->setValue( mLayer->offset().y() );
4494 mOffsetUnitWidget->blockSignals( true );
4495 mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
4496 mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
4497 mOffsetUnitWidget->blockSignals( false );
4498
4499 whileBlocking( mWidthSpinBox )->setValue( mLayer->width() );
4500 mSizeUnitWidget->blockSignals( true );
4501 mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
4502 mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
4503 mSizeUnitWidget->blockSignals( false );
4504
4505 whileBlocking( mHeightSpinBox )->setValue( mLayer->height() );
4506
4507 updatePreviewImage();
4508
4515}
4516
4521
4522void QgsRasterFillSymbolLayerWidget::imageSourceChanged( const QString &text )
4523{
4524 mLayer->setImageFilePath( text );
4525 updatePreviewImage();
4526 emit changed();
4527}
4528
4529void QgsRasterFillSymbolLayerWidget::setCoordinateMode( int index )
4530{
4531 switch ( index )
4532 {
4533 case 0:
4534 //feature coordinate mode
4536 break;
4537 case 1:
4538 //viewport coordinate mode
4540 break;
4541 }
4542
4543 emit changed();
4544}
4545
4546void QgsRasterFillSymbolLayerWidget::opacityChanged( double value )
4547{
4548 if ( !mLayer )
4549 {
4550 return;
4551 }
4552
4553 mLayer->setOpacity( value );
4554 emit changed();
4555 updatePreviewImage();
4556}
4557
4558void QgsRasterFillSymbolLayerWidget::offsetChanged()
4559{
4560 mLayer->setOffset( QPointF( mSpinOffsetX->value(), mSpinOffsetY->value() ) );
4561 emit changed();
4562}
4563
4564void QgsRasterFillSymbolLayerWidget::mOffsetUnitWidget_changed()
4565{
4566 if ( !mLayer )
4567 {
4568 return;
4569 }
4570 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
4571 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
4572 emit changed();
4573}
4574
4575void QgsRasterFillSymbolLayerWidget::mRotationSpinBox_valueChanged( double d )
4576{
4577 if ( mLayer )
4578 {
4579 mLayer->setAngle( d );
4580 emit changed();
4581 }
4582}
4583
4584void QgsRasterFillSymbolLayerWidget::updatePreviewImage()
4585{
4586 bool fitsInCache = false;
4587 const QImage image = QgsApplication::imageCache()->pathAsImage( mLayer->imageFilePath(), QSize( 150, 150 ), true, 1.0, fitsInCache );
4588 if ( image.isNull() )
4589 {
4590 mLabelImagePreview->setPixmap( QPixmap() );
4591 return;
4592 }
4593
4594 QImage previewImage( 150, 150, QImage::Format_ARGB32 );
4595 previewImage.fill( Qt::transparent );
4596 const QRect imageRect( ( 150 - image.width() ) / 2.0, ( 150 - image.height() ) / 2.0, image.width(), image.height() );
4597 QPainter p;
4598 p.begin( &previewImage );
4599 //draw a checkerboard background
4600 uchar pixDataRGB[] = { 150, 150, 150, 150, 100, 100, 100, 150, 100, 100, 100, 150, 150, 150, 150, 150 };
4601 const QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
4602 const QPixmap pix = QPixmap::fromImage( img.scaled( 8, 8 ) );
4603 QBrush checkerBrush;
4604 checkerBrush.setTexture( pix );
4605 p.fillRect( imageRect, checkerBrush );
4606
4607 if ( mLayer->opacity() < 1.0 )
4608 {
4609 p.setOpacity( mLayer->opacity() );
4610 }
4611
4612 p.drawImage( imageRect.left(), imageRect.top(), image );
4613 p.end();
4614 mLabelImagePreview->setPixmap( QPixmap::fromImage( previewImage ) );
4615}
4616
4617//
4618// QgsRasterLineSymbolLayerWidget
4619//
4620
4621
4623 : QgsSymbolLayerWidget( parent, vl )
4624{
4625 mLayer = nullptr;
4626 setupUi( this );
4627
4628 mImageSourceLineEdit->setLastPathSettingsKey( u"/UI/lastRasterMarkerImageDir"_s );
4629
4632
4633 connect( mPenWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
4634 if ( mLayer )
4635 {
4636 mLayer->setWidthUnit( mPenWidthUnitWidget->unit() );
4637 mLayer->setWidthMapUnitScale( mPenWidthUnitWidget->getMapUnitScale() );
4638 emit changed();
4639 }
4640 } );
4641
4642 connect( spinWidth, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this] {
4643 if ( mLayer )
4644 {
4645 mLayer->setWidth( spinWidth->value() );
4646 emit changed();
4647 }
4648 } );
4649
4650 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
4651 if ( mLayer )
4652 {
4653 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
4654 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
4655 emit changed();
4656 }
4657 } );
4658
4659
4660 spinOffset->setClearValue( 0.0 );
4661 connect( spinOffset, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double val ) {
4662 if ( mLayer )
4663 {
4664 mLayer->setOffset( val );
4665 emit changed();
4666 }
4667 } );
4668
4669 connect( cboCapStyle, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this] {
4670 if ( mLayer )
4671 {
4672 mLayer->setPenCapStyle( cboCapStyle->penCapStyle() );
4673 emit changed();
4674 }
4675 } );
4676 connect( cboJoinStyle, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this] {
4677 if ( mLayer )
4678 {
4679 mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
4680 emit changed();
4681 }
4682 } );
4683
4684 connect( mImageSourceLineEdit, &QgsImageSourceLineEdit::sourceChanged, this, &QgsRasterLineSymbolLayerWidget::imageSourceChanged );
4685 connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, [this]( double opacity ) {
4686 if ( mLayer )
4687 {
4688 mLayer->setOpacity( opacity );
4689 updatePreviewImage();
4690 emit changed();
4691 }
4692 } );
4693}
4694
4696{
4697 if ( !layer )
4698 {
4699 return;
4700 }
4701
4702 if ( layer->layerType() != "RasterLine"_L1 )
4703 {
4704 return;
4705 }
4706
4707 mLayer = dynamic_cast<QgsRasterLineSymbolLayer *>( layer );
4708 if ( !mLayer )
4709 {
4710 return;
4711 }
4712
4713 whileBlocking( mImageSourceLineEdit )->setSource( mLayer->path() );
4714 whileBlocking( mOpacityWidget )->setOpacity( mLayer->opacity() );
4715
4716 whileBlocking( spinWidth )->setValue( mLayer->width() );
4717 whileBlocking( mPenWidthUnitWidget )->setUnit( mLayer->widthUnit() );
4718 whileBlocking( mPenWidthUnitWidget )->setMapUnitScale( mLayer->widthMapUnitScale() );
4719 whileBlocking( cboJoinStyle )->setPenJoinStyle( mLayer->penJoinStyle() );
4720 whileBlocking( cboCapStyle )->setPenCapStyle( mLayer->penCapStyle() );
4721
4722 whileBlocking( mOffsetUnitWidget )->setUnit( mLayer->offsetUnit() );
4723 whileBlocking( mOffsetUnitWidget )->setMapUnitScale( mLayer->offsetMapUnitScale() );
4724 whileBlocking( spinOffset )->setValue( mLayer->offset() );
4725
4726 updatePreviewImage();
4727
4734}
4735
4740
4741void QgsRasterLineSymbolLayerWidget::imageSourceChanged( const QString &text )
4742{
4743 mLayer->setPath( text );
4744 updatePreviewImage();
4745 emit changed();
4746}
4747
4748void QgsRasterLineSymbolLayerWidget::updatePreviewImage()
4749{
4750 bool fitsInCache = false;
4751 const QImage image = QgsApplication::imageCache()->pathAsImage( mLayer->path(), QSize( 150, 150 ), true, 1.0, fitsInCache );
4752 if ( image.isNull() )
4753 {
4754 mLabelImagePreview->setPixmap( QPixmap() );
4755 return;
4756 }
4757
4758 QImage previewImage( 150, 150, QImage::Format_ARGB32 );
4759 previewImage.fill( Qt::transparent );
4760 const QRect imageRect( ( 150 - image.width() ) / 2.0, ( 150 - image.height() ) / 2.0, image.width(), image.height() );
4761 QPainter p;
4762 p.begin( &previewImage );
4763 //draw a checkerboard background
4764 uchar pixDataRGB[] = { 150, 150, 150, 150, 100, 100, 100, 150, 100, 100, 100, 150, 150, 150, 150, 150 };
4765 const QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
4766 const QPixmap pix = QPixmap::fromImage( img.scaled( 8, 8 ) );
4767 QBrush checkerBrush;
4768 checkerBrush.setTexture( pix );
4769 p.fillRect( imageRect, checkerBrush );
4770
4771 if ( mLayer->opacity() < 1.0 )
4772 {
4773 p.setOpacity( mLayer->opacity() );
4774 }
4775
4776 p.drawImage( imageRect.left(), imageRect.top(), image );
4777 p.end();
4778 mLabelImagePreview->setPixmap( QPixmap::fromImage( previewImage ) );
4779}
4780
4781
4782//
4783// QgsGeometryGeneratorSymbolLayerWidget
4784//
4785
4787 : QgsSymbolLayerWidget( parent, vl )
4788
4789{
4790 setupUi( this );
4791 modificationExpressionSelector->setMultiLine( true );
4792 modificationExpressionSelector->setLayer( const_cast<QgsVectorLayer *>( vl ) );
4793 modificationExpressionSelector->registerExpressionContextGenerator( this );
4794 cbxGeometryType->addItem( QgsIconUtils::iconPolygon(), tr( "Polygon / MultiPolygon" ), static_cast<int>( Qgis::SymbolType::Fill ) );
4795 cbxGeometryType->addItem( QgsIconUtils::iconLine(), tr( "LineString / MultiLineString" ), static_cast<int>( Qgis::SymbolType::Line ) );
4796 cbxGeometryType->addItem( QgsIconUtils::iconPoint(), tr( "Point / MultiPoint" ), static_cast<int>( Qgis::SymbolType::Marker ) );
4797
4799 mUnitWidget->setShowMapScaleButton( false );
4800
4801 connect( modificationExpressionSelector, &QgsExpressionLineEdit::expressionChanged, this, &QgsGeometryGeneratorSymbolLayerWidget::updateExpression );
4802 connect( cbxGeometryType, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGeometryGeneratorSymbolLayerWidget::updateSymbolType );
4803 connect( mUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
4804 if ( !mBlockSignals )
4805 {
4806 mLayer->setUnits( mUnitWidget->unit() );
4807 emit symbolChanged();
4808 }
4809 } );
4810}
4811
4813{
4814 mBlockSignals++;
4815 mLayer = static_cast<QgsGeometryGeneratorSymbolLayer *>( l );
4816 modificationExpressionSelector->setExpression( mLayer->geometryExpression() );
4817 cbxGeometryType->setCurrentIndex( cbxGeometryType->findData( static_cast<int>( mLayer->symbolType() ) ) );
4818 mUnitWidget->setUnit( mLayer->units() );
4819 mBlockSignals--;
4820}
4821
4826
4827void QgsGeometryGeneratorSymbolLayerWidget::updateExpression( const QString &string )
4828{
4829 mLayer->setGeometryExpression( string );
4830
4831 emit changed();
4832}
4833
4834void QgsGeometryGeneratorSymbolLayerWidget::updateSymbolType()
4835{
4836 // we try to keep the subsymbol, if we can!
4837 std::unique_ptr<QgsSymbol> subSymbol( mLayer->subSymbol()->clone() );
4838
4839 mLayer->setSymbolType( static_cast<Qgis::SymbolType>( cbxGeometryType->currentData().toInt() ) );
4840
4841 switch ( mLayer->symbolType() )
4842 {
4845 break;
4847 {
4848 if ( subSymbol->type() == Qgis::SymbolType::Fill )
4849 {
4850 // going from fill -> line type, so we can copy any LINE symbol layers across
4851 QgsSymbolLayerList layers;
4852 for ( int i = 0; i < subSymbol->symbolLayerCount(); ++i )
4853 {
4854 if ( dynamic_cast<const QgsLineSymbolLayer *>( subSymbol->symbolLayer( i ) ) )
4855 layers << subSymbol->symbolLayer( i )->clone();
4856 }
4857
4858 if ( !layers.empty() )
4859 mLayer->setSubSymbol( new QgsLineSymbol( layers ) );
4860 }
4861 break;
4862 }
4864 if ( subSymbol->type() == Qgis::SymbolType::Line )
4865 {
4866 // going from line -> fill type, so copy ALL line symbol layers across
4867 QgsSymbolLayerList layers;
4868 for ( int i = 0; i < subSymbol->symbolLayerCount(); ++i )
4869 layers << subSymbol->symbolLayer( i )->clone();
4870 mLayer->setSubSymbol( new QgsFillSymbol( layers ) );
4871 }
4872 break;
4873 }
4874
4875 emit symbolChanged();
4876}
4877
4878//
4879// QgsRandomMarkerFillSymbolLayerWidget
4880//
4881
4882
4884 : QgsSymbolLayerWidget( parent, vl )
4885{
4886 setupUi( this );
4887
4888 mCountMethodComboBox->addItem( tr( "Absolute Count" ), static_cast<int>( Qgis::PointCountMethod::Absolute ) );
4889 mCountMethodComboBox->addItem( tr( "Density-based Count" ), static_cast<int>( Qgis::PointCountMethod::DensityBased ) );
4890
4891 mPointCountSpinBox->setShowClearButton( true );
4892 mPointCountSpinBox->setClearValue( 100 );
4893 mSeedSpinBox->setShowClearButton( true );
4894 mSeedSpinBox->setClearValue( 0 );
4895
4896 connect( mCountMethodComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRandomMarkerFillSymbolLayerWidget::countMethodChanged );
4897 connect( mPointCountSpinBox, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ), this, &QgsRandomMarkerFillSymbolLayerWidget::countChanged );
4898 connect( mDensityAreaSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRandomMarkerFillSymbolLayerWidget::densityAreaChanged );
4899 connect( mSeedSpinBox, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ), this, &QgsRandomMarkerFillSymbolLayerWidget::seedChanged );
4900 connect( mClipPointsCheckBox, &QCheckBox::toggled, this, [this]( bool checked ) {
4901 if ( mLayer )
4902 {
4903 mLayer->setClipPoints( checked );
4904 emit changed();
4905 }
4906 } );
4907
4909
4910 connect( mDensityAreaUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsRandomMarkerFillSymbolLayerWidget::densityAreaUnitChanged );
4911}
4912
4914{
4915 if ( !layer || layer->layerType() != "RandomMarkerFill"_L1 )
4916 {
4917 return;
4918 }
4919
4920 mLayer = static_cast<QgsRandomMarkerFillSymbolLayer *>( layer );
4921 whileBlocking( mPointCountSpinBox )->setValue( mLayer->pointCount() );
4922 whileBlocking( mSeedSpinBox )->setValue( mLayer->seed() );
4923 whileBlocking( mClipPointsCheckBox )->setChecked( mLayer->clipPoints() );
4924
4925 bool showDensityBasedCountWidgets = false;
4926 switch ( mLayer->countMethod() )
4927 {
4929 showDensityBasedCountWidgets = true;
4930 break;
4932 break;
4933 }
4934 mDensityAreaLabel->setVisible( showDensityBasedCountWidgets );
4935 mDensityAreaSpinBox->setVisible( showDensityBasedCountWidgets );
4936 mDensityAreaUnitWidget->setVisible( showDensityBasedCountWidgets );
4937 mDensityAreaDdbtn->setVisible( showDensityBasedCountWidgets );
4938
4939 whileBlocking( mCountMethodComboBox )->setCurrentIndex( mCountMethodComboBox->findData( static_cast<int>( mLayer->countMethod() ) ) );
4940 whileBlocking( mDensityAreaSpinBox )->setValue( mLayer->densityArea() );
4941 mDensityAreaUnitWidget->blockSignals( true );
4942 mDensityAreaUnitWidget->setUnit( mLayer->densityAreaUnit() );
4943 mDensityAreaUnitWidget->setMapUnitScale( mLayer->densityAreaUnitScale() );
4944 mDensityAreaUnitWidget->blockSignals( false );
4945
4950}
4951
4956
4957void QgsRandomMarkerFillSymbolLayerWidget::countMethodChanged( int )
4958{
4959 bool showDensityBasedCountWidgets = false;
4960 switch ( static_cast<Qgis::PointCountMethod>( mCountMethodComboBox->currentData().toInt() ) )
4961 {
4963 showDensityBasedCountWidgets = true;
4964 break;
4966 break;
4967 }
4968 mDensityAreaLabel->setVisible( showDensityBasedCountWidgets );
4969 mDensityAreaSpinBox->setVisible( showDensityBasedCountWidgets );
4970 mDensityAreaUnitWidget->setVisible( showDensityBasedCountWidgets );
4971 mDensityAreaDdbtn->setVisible( showDensityBasedCountWidgets );
4972
4973 if ( mLayer )
4974 {
4975 mLayer->setCountMethod( static_cast<Qgis::PointCountMethod>( mCountMethodComboBox->currentData().toInt() ) );
4976 emit changed();
4977 }
4978}
4979
4980void QgsRandomMarkerFillSymbolLayerWidget::countChanged( int d )
4981{
4982 if ( mLayer )
4983 {
4984 mLayer->setPointCount( d );
4985 emit changed();
4986 }
4987}
4988
4989void QgsRandomMarkerFillSymbolLayerWidget::densityAreaChanged( double d )
4990{
4991 if ( mLayer )
4992 {
4993 mLayer->setDensityArea( d );
4994 emit changed();
4995 }
4996}
4997
4998void QgsRandomMarkerFillSymbolLayerWidget::densityAreaUnitChanged()
4999{
5000 if ( mLayer )
5001 {
5002 mLayer->setDensityAreaUnit( mDensityAreaUnitWidget->unit() );
5003 mLayer->setDensityAreaUnitScale( mDensityAreaUnitWidget->getMapUnitScale() );
5004 emit changed();
5005 }
5006}
5007
5008void QgsRandomMarkerFillSymbolLayerWidget::seedChanged( int d )
5009{
5010 if ( mLayer )
5011 {
5012 mLayer->setSeed( d );
5013 emit changed();
5014 }
5015}
5016
5017//
5018// QgsGradientLineSymbolLayerWidget
5019//
5020
5022 : QgsSymbolLayerWidget( parent, vl )
5023{
5024 mLayer = nullptr;
5025 setupUi( this );
5026
5027 btnColorRamp->setShowGradientOnly( true );
5028
5029 btnChangeColor->setAllowOpacity( true );
5030 btnChangeColor->setColorDialogTitle( tr( "Select Gradient Color" ) );
5031 btnChangeColor->setContext( u"symbology"_s );
5032 btnChangeColor->setShowNoColor( true );
5033 btnChangeColor->setNoColorString( tr( "Transparent" ) );
5034 btnChangeColor2->setAllowOpacity( true );
5035 btnChangeColor2->setColorDialogTitle( tr( "Select Gradient Color" ) );
5036 btnChangeColor2->setContext( u"symbology"_s );
5037 btnChangeColor2->setShowNoColor( true );
5038 btnChangeColor2->setNoColorString( tr( "Transparent" ) );
5039
5040 mStartColorDDBtn->registerLinkedWidget( btnChangeColor );
5041 mEndColorDDBtn->registerLinkedWidget( btnChangeColor2 );
5042
5043 connect( btnChangeColor, &QgsColorButton::colorChanged, this, [this]( const QColor &color ) {
5044 if ( mLayer )
5045 {
5046 mLayer->setColor( color );
5047 emit changed();
5048 }
5049 } );
5050 connect( btnChangeColor2, &QgsColorButton::colorChanged, this, [this]( const QColor &color ) {
5051 if ( mLayer )
5052 {
5053 mLayer->setColor2( color );
5054 emit changed();
5055 }
5056 } );
5057 connect( btnColorRamp, &QgsColorRampButton::colorRampChanged, this, [this] {
5058 if ( btnColorRamp->isNull() )
5059 return;
5060
5061 if ( mLayer )
5062 {
5063 mLayer->setColorRamp( btnColorRamp->colorRamp()->clone() );
5064 emit changed();
5065 }
5066 } );
5067
5068 connect( radioTwoColor, &QAbstractButton::toggled, this, [this] {
5069 if ( mLayer )
5070 {
5071 if ( radioTwoColor->isChecked() )
5072 {
5073 mLayer->setGradientColorType( Qgis::GradientColorSource::SimpleTwoColor );
5074 btnChangeColor->setEnabled( true );
5075 btnChangeColor2->setEnabled( true );
5076 btnColorRamp->setEnabled( false );
5077 }
5078 else
5079 {
5080 mLayer->setGradientColorType( Qgis::GradientColorSource::ColorRamp );
5081 btnColorRamp->setEnabled( true );
5082 btnChangeColor->setEnabled( false );
5083 btnChangeColor2->setEnabled( false );
5084 }
5085 emit changed();
5086 }
5087 } );
5088
5091
5092 connect( mPenWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
5093 if ( mLayer )
5094 {
5095 mLayer->setWidthUnit( mPenWidthUnitWidget->unit() );
5096 mLayer->setWidthMapUnitScale( mPenWidthUnitWidget->getMapUnitScale() );
5097 emit changed();
5098 }
5099 } );
5100
5101 connect( spinWidth, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, [this] {
5102 if ( mLayer )
5103 {
5104 mLayer->setWidth( spinWidth->value() );
5105 emit changed();
5106 }
5107 } );
5108
5109 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
5110 if ( mLayer )
5111 {
5112 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
5113 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
5114 emit changed();
5115 }
5116 } );
5117
5118 spinOffset->setClearValue( 0.0 );
5119 connect( spinOffset, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double val ) {
5120 if ( mLayer )
5121 {
5122 mLayer->setOffset( val );
5123 emit changed();
5124 }
5125 } );
5126
5127 connect( cboCapStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [this] {
5128 if ( mLayer )
5129 {
5130 mLayer->setPenCapStyle( cboCapStyle->penCapStyle() );
5131 emit changed();
5132 }
5133 } );
5134 connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [this] {
5135 if ( mLayer )
5136 {
5137 mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
5138 emit changed();
5139 }
5140 } );
5141}
5142
5144{
5145 if ( !layer )
5146 {
5147 return;
5148 }
5149
5150 if ( layer->layerType() != "Lineburst"_L1 )
5151 {
5152 return;
5153 }
5154
5155 mLayer = dynamic_cast<QgsLineburstSymbolLayer *>( layer );
5156 if ( !mLayer )
5157 {
5158 return;
5159 }
5160
5161 btnChangeColor->blockSignals( true );
5162 btnChangeColor->setColor( mLayer->color() );
5163 btnChangeColor->blockSignals( false );
5164 btnChangeColor2->blockSignals( true );
5165 btnChangeColor2->setColor( mLayer->color2() );
5166 btnChangeColor2->blockSignals( false );
5167
5168 if ( mLayer->gradientColorType() == Qgis::GradientColorSource::SimpleTwoColor )
5169 {
5170 radioTwoColor->setChecked( true );
5171 btnColorRamp->setEnabled( false );
5172 }
5173 else
5174 {
5175 radioColorRamp->setChecked( true );
5176 btnChangeColor->setEnabled( false );
5177 btnChangeColor2->setEnabled( false );
5178 }
5179
5180 // set source color ramp
5181 if ( mLayer->colorRamp() )
5182 {
5183 btnColorRamp->blockSignals( true );
5184 btnColorRamp->setColorRamp( mLayer->colorRamp() );
5185 btnColorRamp->blockSignals( false );
5186 }
5187
5188 whileBlocking( spinWidth )->setValue( mLayer->width() );
5189 whileBlocking( mPenWidthUnitWidget )->setUnit( mLayer->widthUnit() );
5190 whileBlocking( mPenWidthUnitWidget )->setMapUnitScale( mLayer->widthMapUnitScale() );
5191
5192 whileBlocking( mOffsetUnitWidget )->setUnit( mLayer->offsetUnit() );
5193 whileBlocking( mOffsetUnitWidget )->setMapUnitScale( mLayer->offsetMapUnitScale() );
5194 whileBlocking( spinOffset )->setValue( mLayer->offset() );
5195
5196 whileBlocking( cboJoinStyle )->setPenJoinStyle( mLayer->penJoinStyle() );
5197 whileBlocking( cboCapStyle )->setPenCapStyle( mLayer->penCapStyle() );
5198
5205}
5206
5211
5212//
5213// QgsFilledLineSymbolLayerWidget
5214//
5215
5217 : QgsSymbolLayerWidget( parent, vl )
5218{
5219 mLayer = nullptr;
5220 setupUi( this );
5221
5224
5225 connect( mPenWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
5226 if ( mLayer )
5227 {
5228 mLayer->setWidthUnit( mPenWidthUnitWidget->unit() );
5229 mLayer->setWidthMapUnitScale( mPenWidthUnitWidget->getMapUnitScale() );
5230 emit changed();
5231 }
5232 } );
5233
5234 connect( spinWidth, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, [this] {
5235 if ( mLayer )
5236 {
5237 mLayer->setWidth( spinWidth->value() );
5238 emit changed();
5239 }
5240 } );
5241
5242 connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
5243 if ( mLayer )
5244 {
5245 mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
5246 mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
5247 emit changed();
5248 }
5249 } );
5250
5251 spinOffset->setClearValue( 0.0 );
5252 connect( spinOffset, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double val ) {
5253 if ( mLayer )
5254 {
5255 mLayer->setOffset( val );
5256 emit changed();
5257 }
5258 } );
5259
5260 connect( cboCapStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [this] {
5261 if ( mLayer )
5262 {
5263 mLayer->setPenCapStyle( cboCapStyle->penCapStyle() );
5264 emit changed();
5265 }
5266 } );
5267 connect( cboJoinStyle, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [this] {
5268 if ( mLayer )
5269 {
5270 mLayer->setPenJoinStyle( cboJoinStyle->penJoinStyle() );
5271 emit changed();
5272 }
5273 } );
5274}
5275
5277
5279{
5280 if ( !layer )
5281 {
5282 return;
5283 }
5284
5285 if ( layer->layerType() != "FilledLine"_L1 )
5286 {
5287 return;
5288 }
5289
5290 mLayer = dynamic_cast<QgsFilledLineSymbolLayer *>( layer );
5291 if ( !mLayer )
5292 {
5293 return;
5294 }
5295
5296 whileBlocking( spinWidth )->setValue( mLayer->width() );
5297 whileBlocking( mPenWidthUnitWidget )->setUnit( mLayer->widthUnit() );
5298 whileBlocking( mPenWidthUnitWidget )->setMapUnitScale( mLayer->widthMapUnitScale() );
5299
5300 whileBlocking( mOffsetUnitWidget )->setUnit( mLayer->offsetUnit() );
5301 whileBlocking( mOffsetUnitWidget )->setMapUnitScale( mLayer->offsetMapUnitScale() );
5302 whileBlocking( spinOffset )->setValue( mLayer->offset() );
5303
5304 whileBlocking( cboJoinStyle )->setPenJoinStyle( mLayer->penJoinStyle() );
5305 whileBlocking( cboCapStyle )->setPenCapStyle( mLayer->penCapStyle() );
5306
5311}
5312
5317
5318//
5319// QgsLinearReferencingSymbolLayerWidget
5320//
5321
5323 : QgsSymbolLayerWidget( parent, vl )
5324{
5325 mLayer = nullptr;
5326
5327 setupUi( this );
5328
5329 mComboPlacement->addItem( tr( "Interval (Cartesian 2D Distances)" ), QVariant::fromValue( Qgis::LinearReferencingPlacement::IntervalCartesian2D ) );
5330 mComboPlacement->addItem( tr( "Interval (Z Values)" ), QVariant::fromValue( Qgis::LinearReferencingPlacement::IntervalZ ) );
5331 mComboPlacement->addItem( tr( "Interval (M Values)" ), QVariant::fromValue( Qgis::LinearReferencingPlacement::IntervalM ) );
5332 mComboPlacement->addItem( tr( "On Every Vertex" ), QVariant::fromValue( Qgis::LinearReferencingPlacement::Vertex ) );
5333
5334 mComboQuantity->addItem( tr( "Cartesian 2D Distance" ), QVariant::fromValue( Qgis::LinearReferencingLabelSource::CartesianDistance2D ) );
5335 mComboQuantity->addItem( tr( "Z Values" ), QVariant::fromValue( Qgis::LinearReferencingLabelSource::Z ) );
5336 mComboQuantity->addItem( tr( "M Values" ), QVariant::fromValue( Qgis::LinearReferencingLabelSource::M ) );
5337
5338 mSpinSkipMultiples->setClearValue( 0, tr( "Not set" ) );
5339 mSpinLabelOffsetX->setClearValue( 0 );
5340 mSpinLabelOffsetY->setClearValue( 0 );
5341 mSpinAverageAngleLength->setClearValue( 4.0 );
5344
5345 connect( mComboQuantity, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this] {
5346 if ( mLayer && !mBlockChangesSignal )
5347 {
5348 mLayer->setLabelSource( mComboQuantity->currentData().value<Qgis::LinearReferencingLabelSource>() );
5349 emit changed();
5350 }
5351 } );
5352 connect( mTextFormatButton, &QgsFontButton::changed, this, [this] {
5353 if ( mLayer && !mBlockChangesSignal )
5354 {
5355 mLayer->setTextFormat( mTextFormatButton->textFormat() );
5356 emit changed();
5357 }
5358 } );
5359 connect( spinInterval, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, [this] {
5360 if ( mLayer && !mBlockChangesSignal )
5361 {
5362 mLayer->setInterval( spinInterval->value() );
5363 emit changed();
5364 }
5365 } );
5366 connect( mSpinSkipMultiples, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, [this] {
5367 if ( mLayer && !mBlockChangesSignal )
5368 {
5369 mLayer->setSkipMultiplesOf( mSpinSkipMultiples->value() );
5370 emit changed();
5371 }
5372 } );
5373 connect( mCheckRotate, &QCheckBox::toggled, this, [this]( bool checked ) {
5374 if ( mLayer && !mBlockChangesSignal )
5375 {
5376 mLayer->setRotateLabels( checked );
5377 emit changed();
5378 }
5379 mSpinAverageAngleLength->setEnabled( checked );
5380 mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
5381 } );
5382 connect( mCheckShowMarker, &QCheckBox::toggled, this, [this]( bool checked ) {
5383 if ( mLayer && !mBlockChangesSignal )
5384 {
5385 mLayer->setShowMarker( checked );
5386 emit symbolChanged();
5387 }
5388 } );
5389
5390 connect( mSpinLabelOffsetX, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, [this] {
5391 if ( mLayer && !mBlockChangesSignal )
5392 {
5393 mLayer->setLabelOffset( QPointF( mSpinLabelOffsetX->value(), mSpinLabelOffsetY->value() ) );
5394 emit changed();
5395 }
5396 } );
5397 connect( mSpinLabelOffsetY, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, [this] {
5398 if ( mLayer && !mBlockChangesSignal )
5399 {
5400 mLayer->setLabelOffset( QPointF( mSpinLabelOffsetX->value(), mSpinLabelOffsetY->value() ) );
5401 emit changed();
5402 }
5403 } );
5404 connect( mLabelOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, [this] {
5405 if ( mLayer && !mBlockChangesSignal )
5406 {
5407 mLayer->setLabelOffsetUnit( mLabelOffsetUnitWidget->unit() );
5408 mLayer->setLabelOffsetMapUnitScale( mLabelOffsetUnitWidget->getMapUnitScale() );
5409 emit changed();
5410 }
5411 } );
5412
5413 connect( mComboPlacement, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this] {
5414 if ( mLayer && !mBlockChangesSignal )
5415 {
5416 const Qgis::LinearReferencingPlacement placement = mComboPlacement->currentData().value<Qgis::LinearReferencingPlacement>();
5417 mLayer->setPlacement( placement );
5418 switch ( placement )
5419 {
5423 mIntervalWidget->show();
5424 break;
5426 mIntervalWidget->hide();
5427 break;
5428 }
5429 emit changed();
5430 }
5431 } );
5432
5433 connect( mSpinAverageAngleLength, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, [this] {
5434 if ( mLayer && !mBlockChangesSignal )
5435 {
5436 mLayer->setAverageAngleLength( mSpinAverageAngleLength->value() );
5437 emit changed();
5438 }
5439 } );
5440 connect( mAverageAngleUnit, &QgsUnitSelectionWidget::changed, this, [this] {
5441 if ( mLayer && !mBlockChangesSignal )
5442 {
5443 mLayer->setAverageAngleUnit( mAverageAngleUnit->unit() );
5444 mLayer->setAverageAngleMapUnitScale( mAverageAngleUnit->getMapUnitScale() );
5445 emit changed();
5446 }
5447 } );
5448
5449 connect( mNumberFormatPushButton, &QPushButton::clicked, this, &QgsLinearReferencingSymbolLayerWidget::changeNumberFormat );
5450
5451 mTextFormatButton->registerExpressionContextGenerator( this );
5452}
5453
5455
5456
5458{
5459 if ( !layer || layer->layerType() != "LinearReferencing"_L1 )
5460 return;
5461
5462 // layer type is correct, we can do the cast
5463 mLayer = qgis::down_cast<QgsLinearReferencingSymbolLayer *>( layer );
5464
5465 mBlockChangesSignal = true;
5466
5467 mComboPlacement->setCurrentIndex( mComboPlacement->findData( QVariant::fromValue( mLayer->placement() ) ) );
5468 switch ( mLayer->placement() )
5469 {
5473 mIntervalWidget->show();
5474 break;
5476 mIntervalWidget->hide();
5477 break;
5478 }
5479
5480 mComboQuantity->setCurrentIndex( mComboQuantity->findData( QVariant::fromValue( mLayer->labelSource() ) ) );
5481
5482 mTextFormatButton->setTextFormat( mLayer->textFormat() );
5483 spinInterval->setValue( mLayer->interval() );
5484 mSpinSkipMultiples->setValue( mLayer->skipMultiplesOf() );
5485 mCheckRotate->setChecked( mLayer->rotateLabels() );
5486 mCheckShowMarker->setChecked( mLayer->showMarker() );
5487 mSpinLabelOffsetX->setValue( mLayer->labelOffset().x() );
5488 mSpinLabelOffsetY->setValue( mLayer->labelOffset().y() );
5489 mLabelOffsetUnitWidget->setUnit( mLayer->labelOffsetUnit() );
5490 mLabelOffsetUnitWidget->setMapUnitScale( mLayer->labelOffsetMapUnitScale() );
5491
5492 mAverageAngleUnit->setUnit( mLayer->averageAngleUnit() );
5493 mAverageAngleUnit->setMapUnitScale( mLayer->averageAngleMapUnitScale() );
5494 mSpinAverageAngleLength->setValue( mLayer->averageAngleLength() );
5495
5496 mSpinAverageAngleLength->setEnabled( mCheckRotate->isChecked() );
5497 mAverageAngleUnit->setEnabled( mSpinAverageAngleLength->isEnabled() );
5498
5503
5504 mBlockChangesSignal = false;
5505}
5506
5511
5513{
5515 mTextFormatButton->setMapCanvas( context.mapCanvas() );
5516 mTextFormatButton->setMessageBar( context.messageBar() );
5517}
5518
5519void QgsLinearReferencingSymbolLayerWidget::changeNumberFormat()
5520{
5522 if ( panel && panel->dockMode() )
5523 {
5525 widget->setPanelTitle( tr( "Number Format" ) );
5526 widget->setFormat( mLayer->numericFormat() );
5527 widget->registerExpressionContextGenerator( this );
5528 connect( widget, &QgsNumericFormatSelectorWidget::changed, this, [this, widget] {
5529 if ( !mBlockChangesSignal )
5530 {
5531 mLayer->setNumericFormat( widget->format() );
5532 emit changed();
5533 }
5534 } );
5535 panel->openPanel( widget );
5536 }
5537 else
5538 {
5539 QgsNumericFormatSelectorDialog dialog( this );
5540 dialog.setFormat( mLayer->numericFormat() );
5541 dialog.registerExpressionContextGenerator( this );
5542 if ( dialog.exec() )
5543 {
5544 mLayer->setNumericFormat( dialog.format() );
5545 emit changed();
5546 }
5547 }
5548}
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:3194
@ InnerVertices
Inner vertices (i.e. all vertices except the first and last vertex).
Definition qgis.h:3196
@ LastVertex
Place symbols on the last vertex in the line.
Definition qgis.h:3191
@ CentralPoint
Place symbols at the mid point of the line.
Definition qgis.h:3193
@ SegmentCenter
Place symbols at the center of every line segment.
Definition qgis.h:3195
@ Vertex
Place symbols on every vertex in the line.
Definition qgis.h:3190
@ Interval
Place symbols at regular intervals.
Definition qgis.h:3189
@ FirstVertex
Place symbols on the first vertex in the line.
Definition qgis.h:3192
MarkerClipMode
Marker clipping modes.
Definition qgis.h:3308
@ CompletelyWithin
Render complete markers wherever the completely fall within the polygon shape.
Definition qgis.h:3312
@ NoClipping
No clipping, render complete markers.
Definition qgis.h:3309
@ Shape
Clip to polygon shape.
Definition qgis.h:3310
@ CentroidWithin
Render complete markers wherever their centroid falls within the polygon shape.
Definition qgis.h:3311
LineClipMode
Line clipping modes.
Definition qgis.h:3322
@ NoClipping
Lines are not clipped, will extend to shape's bounding box.
Definition qgis.h:3325
@ ClipPainterOnly
Applying clipping on the painter only (i.e. line endpoints will coincide with polygon bounding box,...
Definition qgis.h:3323
@ ClipToIntersection
Clip lines to intersection with polygon shape (slower) (i.e. line endpoints will coincide with polygo...
Definition qgis.h:3324
@ ColorRamp
Gradient color ramp.
Definition qgis.h:3239
@ SimpleTwoColor
Simple two color gradient.
Definition qgis.h:3238
@ Repeat
Repeat gradient.
Definition qgis.h:3284
@ Reflect
Reflect gradient.
Definition qgis.h:3283
@ Pad
Pad out gradient using colors at endpoint of gradient.
Definition qgis.h:3282
PointCountMethod
Methods which define the number of points randomly filling a polygon.
Definition qgis.h:3296
@ Absolute
The point count is used as an absolute count of markers.
Definition qgis.h:3297
@ DensityBased
The point count is part of a marker density count.
Definition qgis.h:3298
@ Field
Field based property.
Definition qgis.h:704
MarkerShape
Marker shapes.
Definition qgis.h:3139
VerticalAnchorPoint
Marker symbol vertical anchor points.
Definition qgis.h:833
@ Bottom
Align to bottom of symbol.
Definition qgis.h:836
@ Center
Align to vertical center of symbol.
Definition qgis.h:835
@ Baseline
Align to baseline of symbol, e.g. font baseline for font marker symbol layers. Treated as Bottom if n...
Definition qgis.h:837
@ Top
Align to top of symbol.
Definition qgis.h:834
LinearReferencingPlacement
Defines how/where the labels should be placed in a linear referencing symbol layer.
Definition qgis.h:3208
@ IntervalZ
Place labels at regular intervals, linearly interpolated using Z values.
Definition qgis.h:3210
@ Vertex
Place labels on every vertex in the line.
Definition qgis.h:3212
@ IntervalM
Place labels at regular intervals, linearly interpolated using M values.
Definition qgis.h:3211
@ IntervalCartesian2D
Place labels at regular intervals, using Cartesian distance calculations on a 2D plane.
Definition qgis.h:3209
LinearReferencingLabelSource
Defines what quantity to use for the labels shown in a linear referencing symbol layer.
Definition qgis.h:3222
@ CartesianDistance2D
Distance along line, calculated using Cartesian calculations on a 2D plane.
Definition qgis.h:3223
@ Percentage
Percentage of another measurement (e.g., canvas size, feature size).
Definition qgis.h:5259
@ Millimeters
Millimeters.
Definition qgis.h:5256
@ Points
Points (e.g., for font sizes).
Definition qgis.h:5260
@ MapUnits
Map units.
Definition qgis.h:5257
@ Pixels
Pixels.
Definition qgis.h:5258
@ Inches
Inches.
Definition qgis.h:5261
@ MetersInMapUnits
Meters value as Map units.
Definition qgis.h:5263
@ Linear
Linear gradient.
Definition qgis.h:3252
@ Conical
Conical (polar) gradient.
Definition qgis.h:3254
@ Radial
Radial (circular) gradient.
Definition qgis.h:3253
SymbolType
Symbol types.
Definition qgis.h:629
@ Marker
Marker symbol.
Definition qgis.h:630
@ Line
Line symbol.
Definition qgis.h:631
@ Fill
Fill symbol.
Definition qgis.h:632
@ Hybrid
Hybrid symbol.
Definition qgis.h:633
SymbolCoordinateReference
Symbol coordinate reference modes.
Definition qgis.h:3266
@ Feature
Relative to feature/shape being rendered.
Definition qgis.h:3267
@ Viewport
Relative to the whole viewport/output device.
Definition qgis.h:3268
QFlags< MarkerLinePlacement > MarkerLinePlacements
Definition qgis.h:3199
HorizontalAnchorPoint
Marker symbol horizontal anchor points.
Definition qgis.h:819
@ Center
Align to horizontal center of symbol.
Definition qgis.h:821
@ Right
Align to right side of symbol.
Definition qgis.h:822
@ Left
Align to left side of symbol.
Definition qgis.h:820
static const double UI_SCALE_FACTOR
UI scaling factor.
Definition qgis.h:6499
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:6804
QList< QgsSymbolLayer * > QgsSymbolLayerList
Definition qgssymbol.h:30
class GUI_EXPORT QgsMapToolEditBlankSegments
Single variable definition for use within a QgsExpressionContextScope.