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