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