QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
Loading...
Searching...
No Matches
qgssymbolslistwidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgssymbolslist.cpp
3 ---------------------
4 begin : June 2012
5 copyright : (C) 2012 by Arunmozhi
6 email : aruntheguy at gmail.com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17
18#include "qgsauxiliarystorage.h"
20#include "qgslinesymbol.h"
21#include "qgsmarkersymbol.h"
25#include "qgsstylesavedialog.h"
28#include "qgsvectorlayer.h"
29
30#include <QAction>
31#include <QMenu>
32#include <QMessageBox>
33#include <QString>
34
35#include "moc_qgssymbolslistwidget.cpp"
36
37using namespace Qt::StringLiterals;
38
39QgsSymbolsListWidget::QgsSymbolsListWidget( QgsSymbol *symbol, QgsStyle *style, QMenu *menu, QWidget *parent, QgsVectorLayer *layer )
40 : QWidget( parent )
41 , mSymbol( symbol )
42 , mStyle( style )
43 , mAdvancedMenu( menu )
44 , mLayer( layer )
45{
46 setupUi( this );
47 spinAngle->setClearValue( 0 );
48
49 mStyleItemsListWidget->setStyle( mStyle );
50 mStyleItemsListWidget->setEntityType( QgsStyle::SymbolEntity );
51 if ( mSymbol )
52 mStyleItemsListWidget->setSymbolType( mSymbol->type() );
53 mStyleItemsListWidget->setAdvancedMenu( menu );
54
55 mClipFeaturesAction = new QAction( tr( "Clip Features to Canvas Extent" ), this );
56 mClipFeaturesAction->setCheckable( true );
57 connect( mClipFeaturesAction, &QAction::toggled, this, &QgsSymbolsListWidget::clipFeaturesToggled );
58 mStandardizeRingsAction = new QAction( tr( "Force Right-Hand-Rule Orientation" ), this );
59 mStandardizeRingsAction->setCheckable( true );
60 connect( mStandardizeRingsAction, &QAction::toggled, this, &QgsSymbolsListWidget::forceRHRToggled );
61
62 mBufferSettingsAction = new QAction( tr( "Buffer Settings…" ), this );
63 connect( mBufferSettingsAction, &QAction::triggered, this, &QgsSymbolsListWidget::showBufferSettings );
64
65 mAnimationSettingsAction = new QAction( tr( "Animation Settings…" ), this );
66 connect( mAnimationSettingsAction, &QAction::triggered, this, &QgsSymbolsListWidget::showAnimationSettings );
67
68 mExtentBufferAction = new QAction( tr( "Extent Buffer…" ), this );
69 connect( mExtentBufferAction, &QAction::triggered, this, &QgsSymbolsListWidget::showExtentBufferSettings );
70
71 // select correct page in stacked widget
72 QgsPropertyOverrideButton *opacityDDBtn = nullptr;
73 switch ( symbol->type() )
74 {
76 {
77 stackedWidget->removeWidget( stackedWidget->widget( 2 ) );
78 stackedWidget->removeWidget( stackedWidget->widget( 1 ) );
79 mSymbolColorButton = btnMarkerColor;
80 opacityDDBtn = mMarkerOpacityDDBtn;
81 mSymbolOpacityWidget = mMarkerOpacityWidget;
82 mSymbolUnitWidget = mMarkerUnitWidget;
83 connect( spinAngle, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSymbolsListWidget::setMarkerAngle );
84 connect( spinSize, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSymbolsListWidget::setMarkerSize );
85 registerDataDefinedButton( mSizeDDBtn, QgsSymbolLayer::Property::Size );
87 registerDataDefinedButton( mRotationDDBtn, QgsSymbolLayer::Property::Angle );
89 break;
90 }
91
93 {
94 stackedWidget->removeWidget( stackedWidget->widget( 2 ) );
95 stackedWidget->removeWidget( stackedWidget->widget( 0 ) );
96 mSymbolColorButton = btnLineColor;
97 opacityDDBtn = mLineOpacityDDBtn;
98 mSymbolOpacityWidget = mLineOpacityWidget;
99 mSymbolUnitWidget = mLineUnitWidget;
100 connect( spinWidth, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSymbolsListWidget::setLineWidth );
101 registerDataDefinedButton( mWidthDDBtn, QgsSymbolLayer::Property::StrokeWidth );
103 break;
104 }
105
107 {
108 stackedWidget->removeWidget( stackedWidget->widget( 1 ) );
109 stackedWidget->removeWidget( stackedWidget->widget( 0 ) );
110 mSymbolColorButton = btnFillColor;
111 opacityDDBtn = mFillOpacityDDBtn;
112 mSymbolOpacityWidget = mFillOpacityWidget;
113 mSymbolUnitWidget = mFillUnitWidget;
114 break;
115 }
116
118 break;
119 }
120
121 stackedWidget->setCurrentIndex( 0 );
122
123 mSymbolUnitWidget->setUnits(
125 );
126
127 if ( mSymbol )
128 {
129 updateSymbolInfo();
130 }
131
132 connect( mSymbolUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSymbolsListWidget::mSymbolUnitWidget_changed );
133 connect( mSymbolColorButton, &QgsColorButton::colorChanged, this, &QgsSymbolsListWidget::setSymbolColor );
134
135 if ( opacityDDBtn )
136 {
137 registerSymbolDataDefinedButton( opacityDDBtn, QgsSymbol::Property::Opacity );
138 }
139
140 connect( this, &QgsSymbolsListWidget::changed, this, &QgsSymbolsListWidget::updateAssistantSymbol );
141 if ( mSymbol )
142 {
143 updateAssistantSymbol();
144 }
145
146 mSymbolColorButton->setAllowOpacity( true );
147 mSymbolColorButton->setColorDialogTitle( tr( "Select Color" ) );
148 mSymbolColorButton->setContext( u"symbology"_s );
149
150 connect( mSymbolOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsSymbolsListWidget::opacityChanged );
151
152 connect( mStyleItemsListWidget, &QgsStyleItemsListWidget::selectionChangedWithStylePath, this, &QgsSymbolsListWidget::setSymbolFromStyle );
153 connect( mStyleItemsListWidget, &QgsStyleItemsListWidget::saveEntity, this, &QgsSymbolsListWidget::saveSymbol );
154}
155
157{
158 // This action was added to the menu by this widget, clean it up
159 // The menu can be passed in the constructor, so may live longer than this widget
160 mStyleItemsListWidget->advancedMenu()->removeAction( mClipFeaturesAction );
161 mStyleItemsListWidget->advancedMenu()->removeAction( mStandardizeRingsAction );
162 mStyleItemsListWidget->advancedMenu()->removeAction( mAnimationSettingsAction );
163 mStyleItemsListWidget->advancedMenu()->removeAction( mExtentBufferAction );
164 mStyleItemsListWidget->advancedMenu()->removeAction( mBufferSettingsAction );
165}
166
167void QgsSymbolsListWidget::registerDataDefinedButton( QgsPropertyOverrideButton *button, QgsSymbolLayer::Property key )
168{
169 button->setProperty( "propertyKey", static_cast<int>( key ) );
171
172 connect( button, &QgsPropertyOverrideButton::createAuxiliaryField, this, &QgsSymbolsListWidget::createAuxiliaryField );
173}
174
175void QgsSymbolsListWidget::createAuxiliaryField()
176{
177 // try to create an auxiliary layer if not yet created
178 if ( !mLayer->auxiliaryLayer() )
179 {
180 QgsNewAuxiliaryLayerDialog dlg( mLayer, this );
181 dlg.exec();
182 }
183
184 // return if still not exists
185 if ( !mLayer->auxiliaryLayer() )
186 return;
187
188 QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
189 const QgsSymbolLayer::Property key = static_cast<QgsSymbolLayer::Property>( button->propertyKey() );
190 const QgsPropertyDefinition def = QgsSymbolLayer::propertyDefinitions()[static_cast<int>( key )];
191
192 // create property in auxiliary storage if necessary
193 if ( !mLayer->auxiliaryLayer()->exists( def ) )
194 mLayer->auxiliaryLayer()->addAuxiliaryField( def );
195
196 // update property with join field name from auxiliary storage
197 QgsProperty property = button->toProperty();
198 property.setField( QgsAuxiliaryLayer::nameFromProperty( def, true ) );
199 property.setActive( true );
200 button->updateFieldLists();
201 button->setToProperty( property );
202
203 QgsMarkerSymbol *markerSymbol = static_cast<QgsMarkerSymbol *>( mSymbol );
204 QgsLineSymbol *lineSymbol = static_cast<QgsLineSymbol *>( mSymbol );
205 switch ( key )
206 {
208 if ( markerSymbol )
209 markerSymbol->setDataDefinedAngle( button->toProperty() );
210 break;
211
213 if ( markerSymbol )
214 {
215 markerSymbol->setDataDefinedSize( button->toProperty() );
217 }
218 break;
219
221 if ( lineSymbol )
222 lineSymbol->setDataDefinedWidth( button->toProperty() );
223 break;
224
225 default:
226 break;
227 }
228
229 emit changed();
230}
231
232void QgsSymbolsListWidget::createSymbolAuxiliaryField()
233{
234 // try to create an auxiliary layer if not yet created
235 if ( !mLayer->auxiliaryLayer() )
236 {
237 QgsNewAuxiliaryLayerDialog dlg( mLayer, this );
238 dlg.exec();
239 }
240
241 // return if still not exists
242 if ( !mLayer->auxiliaryLayer() )
243 return;
244
245 QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
246 const QgsSymbol::Property key = static_cast<QgsSymbol::Property>( button->propertyKey() );
247 const QgsPropertyDefinition def = QgsSymbol::propertyDefinitions()[static_cast<int>( key )];
248
249 // create property in auxiliary storage if necessary
250 if ( !mLayer->auxiliaryLayer()->exists( def ) )
251 mLayer->auxiliaryLayer()->addAuxiliaryField( def );
252
253 // update property with join field name from auxiliary storage
254 QgsProperty property = button->toProperty();
255 property.setField( QgsAuxiliaryLayer::nameFromProperty( def, true ) );
256 property.setActive( true );
257 button->updateFieldLists();
258 button->setToProperty( property );
259
260 mSymbol->setDataDefinedProperty( key, button->toProperty() );
261
262 emit changed();
263}
264
266{
267 mContext = context;
268 const auto unitSelectionWidgets { findChildren<QgsUnitSelectionWidget *>() };
269 for ( QgsUnitSelectionWidget *unitWidget : unitSelectionWidgets )
270 {
271 unitWidget->setMapCanvas( mContext.mapCanvas() );
272 }
273}
274
276{
277 return mContext;
278}
279
280void QgsSymbolsListWidget::forceRHRToggled( bool checked )
281{
282 if ( !mSymbol )
283 return;
284
285 mSymbol->setForceRHR( checked );
286 emit changed();
287}
288
289void QgsSymbolsListWidget::showAnimationSettings()
290{
291 QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( this );
292 if ( panel && panel->dockMode() )
293 {
294 QgsSymbolAnimationSettingsWidget *widget = new QgsSymbolAnimationSettingsWidget( panel );
295 widget->setPanelTitle( tr( "Animation Settings" ) );
296 widget->setAnimationSettings( mSymbol->animationSettings() );
297 connect( widget, &QgsPanelWidget::widgetChanged, this, [this, widget]() {
298 mSymbol->setAnimationSettings( widget->animationSettings() );
299 emit changed();
300 } );
301 panel->openPanel( widget );
302 return;
303 }
304
305 QgsSymbolAnimationSettingsDialog d( this );
306 d.setAnimationSettings( mSymbol->animationSettings() );
307 if ( d.exec() == QDialog::Accepted )
308 {
309 mSymbol->setAnimationSettings( d.animationSettings() );
310 emit changed();
311 }
312}
313
314void QgsSymbolsListWidget::showExtentBufferSettings()
315{
316 QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( this );
317 if ( panel && panel->dockMode() )
318 {
319 QgsExtentBufferWidget *widget = new QgsExtentBufferWidget( mSymbol, mLayer, panel );
320 widget->setPanelTitle( tr( "Extent Buffer" ) );
321 widget->setContext( mContext );
322
323 connect( widget, &QgsPanelWidget::widgetChanged, this, [this, widget]() {
324 mSymbol->setExtentBuffer( widget->extentBuffer() );
325 mSymbol->setDataDefinedProperty( QgsSymbol::Property::ExtentBuffer, widget->dataDefinedProperty() );
326 mSymbol->setExtentBufferSizeUnit( widget->sizeUnit() );
327
328 emit changed();
329 } );
330
331 panel->openPanel( widget );
332 }
333 else
334 {
335 QgsExtentBufferDialog dlg( mSymbol, mLayer, panel );
336
337 if ( dlg.widget() )
338 {
339 dlg.setContext( mContext );
340 }
341
342 if ( dlg.exec() == QDialog::Accepted )
343 {
344 mSymbol->setExtentBuffer( dlg.extentBuffer() );
345 mSymbol->setDataDefinedProperty( QgsSymbol::Property::ExtentBuffer, dlg.dataDefinedProperty() );
346 mSymbol->setExtentBufferSizeUnit( dlg.sizeUnit() );
347
348 emit changed();
349 }
350 }
351}
352
353void QgsSymbolsListWidget::showBufferSettings()
354{
355 QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( this );
356 if ( panel && panel->dockMode() )
357 {
358 QgsSymbolBufferSettingsWidget *widget = new QgsSymbolBufferSettingsWidget( panel );
359 widget->setPanelTitle( tr( "Buffer Settings" ) );
360 if ( const QgsSymbolBufferSettings *settings = mSymbol->bufferSettings() )
361 widget->setBufferSettings( *settings );
362
363 connect( widget, &QgsPanelWidget::widgetChanged, this, [this, widget]() {
364 mSymbol->setBufferSettings( new QgsSymbolBufferSettings( widget->bufferSettings() ) );
365 emit changed();
366 } );
367 panel->openPanel( widget );
368 return;
369 }
370
371 QgsSymbolBufferSettingsDialog d( this );
372 if ( const QgsSymbolBufferSettings *settings = mSymbol->bufferSettings() )
373 d.setBufferSettings( *settings );
374 if ( d.exec() == QDialog::Accepted )
375 {
376 mSymbol->setBufferSettings( new QgsSymbolBufferSettings( d.bufferSettings() ) );
377 emit changed();
378 }
379}
380
381void QgsSymbolsListWidget::saveSymbol()
382{
383 QgsStyleSaveDialog saveDlg( this );
384 saveDlg.setDefaultTags( mStyleItemsListWidget->currentTagFilter() );
385 if ( !saveDlg.exec() )
386 return;
387
388 if ( saveDlg.name().isEmpty() )
389 return;
390
391 QgsStyle *style = saveDlg.destinationStyle();
392 if ( !style )
393 return;
394
395 // check if there is no symbol with same name
396 if ( style->symbolNames().contains( saveDlg.name() ) )
397 {
398 const int res = QMessageBox::warning( this, tr( "Save Symbol" ), tr( "Symbol with name '%1' already exists. Overwrite?" ).arg( saveDlg.name() ), QMessageBox::Yes | QMessageBox::No );
399 if ( res != QMessageBox::Yes )
400 {
401 return;
402 }
403 style->removeSymbol( saveDlg.name() );
404 }
405
406 const QStringList symbolTags = saveDlg.tags().split( ',' );
407
408 // add new symbol to style and re-populate the list
409 QgsSymbol *newSymbol = mSymbol->clone();
410 style->addSymbol( saveDlg.name(), newSymbol );
411
412 // make sure the symbol is stored
413 style->saveSymbol( saveDlg.name(), newSymbol, saveDlg.isFavorite(), symbolTags );
414}
415
416void QgsSymbolsListWidget::updateSymbolDataDefinedProperty()
417{
418 if ( !mSymbol )
419 return;
420
421 QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
422 const QgsSymbol::Property key = static_cast<QgsSymbol::Property>( button->propertyKey() );
423 mSymbol->setDataDefinedProperty( key, button->toProperty() );
424 emit changed();
425}
426
427void QgsSymbolsListWidget::registerSymbolDataDefinedButton( QgsPropertyOverrideButton *button, QgsSymbol::Property key )
428{
429 button->init( static_cast<int>( key ), mSymbol ? mSymbol->dataDefinedProperties() : QgsPropertyCollection(), QgsSymbol::propertyDefinitions(), mLayer, true );
430 connect( button, &QgsPropertyOverrideButton::changed, this, &QgsSymbolsListWidget::updateSymbolDataDefinedProperty );
431 connect( button, &QgsPropertyOverrideButton::createAuxiliaryField, this, &QgsSymbolsListWidget::createSymbolAuxiliaryField );
432
434}
435
437{
438 if ( !mSymbol )
439 return;
440
441 mSymbol->setClipFeaturesToExtent( checked );
442 emit changed();
443}
444
445void QgsSymbolsListWidget::setSymbolColor( const QColor &color )
446{
447 mSymbol->setColor( color );
448 emit changed();
449}
450
452{
453 QgsMarkerSymbol *markerSymbol = static_cast<QgsMarkerSymbol *>( mSymbol );
454 if ( markerSymbol->angle() == angle )
455 return;
456 markerSymbol->setAngle( angle );
457 emit changed();
458}
459
461{
462 QgsMarkerSymbol *markerSymbol = static_cast<QgsMarkerSymbol *>( mSymbol );
463 const QgsProperty dd( mRotationDDBtn->toProperty() );
464
465 spinAngle->setEnabled( !mRotationDDBtn->isActive() );
466
467 const QgsProperty symbolDD( markerSymbol->dataDefinedAngle() );
468
469 if ( // shall we remove datadefined expressions for layers ?
470 ( !symbolDD && !dd )
471 // shall we set the "en masse" expression for properties ?
472 || dd
473 )
474 {
475 markerSymbol->setDataDefinedAngle( dd );
476 emit changed();
477 }
478}
479
481{
482 QgsMarkerSymbol *markerSymbol = static_cast<QgsMarkerSymbol *>( mSymbol );
483 if ( markerSymbol->size() == size )
484 return;
485 markerSymbol->setSize( size );
486 emit changed();
487}
488
490{
491 QgsMarkerSymbol *markerSymbol = static_cast<QgsMarkerSymbol *>( mSymbol );
492 const QgsProperty dd( mSizeDDBtn->toProperty() );
493
494 spinSize->setEnabled( !mSizeDDBtn->isActive() );
495
496 const QgsProperty symbolDD( markerSymbol->dataDefinedSize() );
497
498 if ( // shall we remove datadefined expressions for layers ?
499 ( !symbolDD && !dd )
500 // shall we set the "en masse" expression for properties ?
501 || dd
502 )
503 {
504 markerSymbol->setDataDefinedSize( dd );
506 emit changed();
507 }
508}
509
511{
512 QgsLineSymbol *lineSymbol = static_cast<QgsLineSymbol *>( mSymbol );
513 if ( lineSymbol->width() == width )
514 return;
515 lineSymbol->setWidth( width );
516 emit changed();
517}
518
520{
521 QgsLineSymbol *lineSymbol = static_cast<QgsLineSymbol *>( mSymbol );
522 const QgsProperty dd( mWidthDDBtn->toProperty() );
523
524 spinWidth->setEnabled( !mWidthDDBtn->isActive() );
525
526 const QgsProperty symbolDD( lineSymbol->dataDefinedWidth() );
527
528 if ( // shall we remove datadefined expressions for layers ?
529 ( !symbolDD && !dd )
530 // shall we set the "en masse" expression for properties ?
531 || dd
532 )
533 {
534 lineSymbol->setDataDefinedWidth( dd );
535 emit changed();
536 }
537}
538
539void QgsSymbolsListWidget::updateAssistantSymbol()
540{
541 mAssistantSymbol.reset( mSymbol->clone() );
542 if ( mSymbol->type() == Qgis::SymbolType::Marker )
543 mSizeDDBtn->setSymbol( mAssistantSymbol );
544 else if ( mSymbol->type() == Qgis::SymbolType::Line && mLayer )
545 mWidthDDBtn->setSymbol( mAssistantSymbol );
546}
547
548void QgsSymbolsListWidget::mSymbolUnitWidget_changed()
549{
550 if ( mSymbol )
551 {
552 mSymbol->setOutputUnit( mSymbolUnitWidget->unit() );
553 mSymbol->setMapUnitScale( mSymbolUnitWidget->getMapUnitScale() );
554
555 emit changed();
556 }
557}
558
559void QgsSymbolsListWidget::opacityChanged( double opacity )
560{
561 if ( mSymbol )
562 {
563 mSymbol->setOpacity( opacity );
564 emit changed();
565 }
566}
567
568void QgsSymbolsListWidget::updateSymbolColor()
569{
570 mSymbolColorButton->blockSignals( true );
571 mSymbolColorButton->setColor( mSymbol->color() );
572 mSymbolColorButton->blockSignals( false );
573}
574
576{
577 if ( auto *lExpressionContext = mContext.expressionContext() )
578 return QgsExpressionContext( *lExpressionContext );
579
580 //otherwise create a default symbol context
581 QgsExpressionContext expContext( mContext.globalProjectAtlasMapLayerScopes( layer() ) );
582
583 // additional scopes
584 const auto constAdditionalExpressionContextScopes = mContext.additionalExpressionContextScopes();
585 for ( const QgsExpressionContextScope &scope : constAdditionalExpressionContextScopes )
586 {
587 expContext.appendScope( new QgsExpressionContextScope( scope ) );
588 }
589
590 expContext.setHighlightedVariables(
591 QStringList()
601 << u"symbol_layer_count"_s
602 << u"symbol_layer_index"_s
603 << u"symbol_frame"_s
604 );
605
606 return expContext;
607}
608
609void QgsSymbolsListWidget::updateSymbolInfo()
610{
611 updateSymbolColor();
612
613 const QList<QgsPropertyOverrideButton *> overrideButtons { findChildren<QgsPropertyOverrideButton *>() };
614 for ( QgsPropertyOverrideButton *button : overrideButtons )
615 {
617 }
618
619 if ( mSymbol->type() == Qgis::SymbolType::Marker )
620 {
621 QgsMarkerSymbol *markerSymbol = static_cast<QgsMarkerSymbol *>( mSymbol );
622 spinSize->setValue( markerSymbol->size() );
623 spinAngle->setValue( markerSymbol->angle() );
624
625 if ( mLayer )
626 {
627 const QgsProperty ddSize( markerSymbol->dataDefinedSize() );
628 mSizeDDBtn->init( static_cast<int>( QgsSymbolLayer::Property::Size ), ddSize, QgsSymbolLayer::propertyDefinitions(), mLayer, true );
629 spinSize->setEnabled( !mSizeDDBtn->isActive() );
630 const QgsProperty ddAngle( markerSymbol->dataDefinedAngle() );
631 mRotationDDBtn->init( static_cast<int>( QgsSymbolLayer::Property::Angle ), ddAngle, QgsSymbolLayer::propertyDefinitions(), mLayer, true );
632 spinAngle->setEnabled( !mRotationDDBtn->isActive() );
633 }
634 else
635 {
636 mSizeDDBtn->setEnabled( false );
637 mRotationDDBtn->setEnabled( false );
638 }
639 }
640 else if ( mSymbol->type() == Qgis::SymbolType::Line )
641 {
642 QgsLineSymbol *lineSymbol = static_cast<QgsLineSymbol *>( mSymbol );
643 spinWidth->setValue( lineSymbol->width() );
644
645 if ( mLayer )
646 {
647 const QgsProperty dd( lineSymbol->dataDefinedWidth() );
648 mWidthDDBtn->init( static_cast<int>( QgsSymbolLayer::Property::StrokeWidth ), dd, QgsSymbolLayer::propertyDefinitions(), mLayer, true );
649 spinWidth->setEnabled( !mWidthDDBtn->isActive() );
650 }
651 else
652 {
653 mWidthDDBtn->setEnabled( false );
654 }
655 }
656
657 mSymbolUnitWidget->blockSignals( true );
658 mSymbolUnitWidget->setUnit( mSymbol->outputUnit() );
659 mSymbolUnitWidget->setMapUnitScale( mSymbol->mapUnitScale() );
660 mSymbolUnitWidget->blockSignals( false );
661
662 mSymbolOpacityWidget->setOpacity( mSymbol->opacity() );
663
664 // Clean up previous advanced symbol actions
665 const QList<QAction *> actionList( mStyleItemsListWidget->advancedMenu()->actions() );
666 for ( QAction *action : actionList )
667 {
668 for ( QAction *actionsToRemove : { mClipFeaturesAction, mStandardizeRingsAction, mAnimationSettingsAction, mExtentBufferAction, mBufferSettingsAction } )
669 {
670 if ( actionsToRemove->text() == action->text() )
671 {
672 mStyleItemsListWidget->advancedMenu()->removeAction( action );
673 break;
674 }
675 }
676 }
677
678 if ( mSymbol->type() == Qgis::SymbolType::Line || mSymbol->type() == Qgis::SymbolType::Fill )
679 {
680 //add clip features option for line or fill symbols
681 mStyleItemsListWidget->advancedMenu()->addAction( mClipFeaturesAction );
682 }
683 if ( mSymbol->type() == Qgis::SymbolType::Fill )
684 {
685 mStyleItemsListWidget->advancedMenu()->addAction( mStandardizeRingsAction );
686 }
687 if ( mSymbol->type() == Qgis::SymbolType::Marker )
688 {
689 mStyleItemsListWidget->advancedMenu()->addAction( mBufferSettingsAction );
690 }
691 mStyleItemsListWidget->advancedMenu()->addAction( mAnimationSettingsAction );
692 mStyleItemsListWidget->advancedMenu()->addAction( mExtentBufferAction );
693
694 mStyleItemsListWidget->showAdvancedButton( mAdvancedMenu || !mStyleItemsListWidget->advancedMenu()->isEmpty() );
695
696 whileBlocking( mClipFeaturesAction )->setChecked( mSymbol->clipFeaturesToExtent() );
697 whileBlocking( mStandardizeRingsAction )->setChecked( mSymbol->forceRHR() );
698}
699
700void QgsSymbolsListWidget::setSymbolFromStyle( const QString &name, QgsStyle::StyleEntity, const QString &stylePath )
701{
702 if ( name.isEmpty() )
703 return;
704
705 QgsStyle *style = nullptr;
706 if ( mStyle != QgsStyle::defaultStyle() )
707 {
708 // get new instance of symbol from style
709 style = mStyle;
710 }
711 else
712 {
713 style = QgsProject::instance()->styleSettings()->styleAtPath( stylePath );
714 }
715
716 if ( !style )
717 return;
718
719 // get new instance of symbol from style
720 std::unique_ptr<QgsSymbol> s( style->symbol( name ) );
721 if ( !s )
722 return;
723
724 // remove all symbol layers from original symbolgroupsCombo
725 while ( mSymbol->symbolLayerCount() )
726 mSymbol->deleteSymbolLayer( 0 );
727 // move all symbol layers to our symbol
728 while ( s->symbolLayerCount() )
729 {
730 QgsSymbolLayer *sl = s->takeSymbolLayer( 0 );
731 mSymbol->appendSymbolLayer( sl );
732 }
733 mSymbol->setOpacity( s->opacity() );
734 mSymbol->setFlags( s->flags() );
735
736 updateSymbolInfo();
737 emit changed();
738}
@ ScaleDiameter
Calculate scale by the diameter.
Definition qgis.h:652
@ Millimeters
Millimeters.
Definition qgis.h:5341
@ Points
Points (e.g., for font sizes).
Definition qgis.h:5345
@ MapUnits
Map units.
Definition qgis.h:5342
@ Pixels
Pixels.
Definition qgis.h:5343
@ Inches
Inches.
Definition qgis.h:5346
@ MetersInMapUnits
Meters value as Map units.
Definition qgis.h:5348
@ Marker
Marker symbol.
Definition qgis.h:637
@ Line
Line symbol.
Definition qgis.h:638
@ Fill
Fill symbol.
Definition qgis.h:639
@ Hybrid
Hybrid symbol.
Definition qgis.h:640
static QString nameFromProperty(const QgsPropertyDefinition &def, bool joined=false)
Returns the name of the auxiliary field for a property definition.
void colorChanged(const QColor &color)
Emitted whenever a new color is set for the button.
virtual QgsExpressionContext createExpressionContext() const =0
This method needs to be reimplemented in all classes which implement this interface and return an exp...
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
static const QString EXPR_GEOMETRY_PART_COUNT
Inbuilt variable name for geometry part count variable.
static const QString EXPR_GEOMETRY_POINT_COUNT
Inbuilt variable name for point count variable.
static const QString EXPR_CLUSTER_SIZE
Inbuilt variable name for cluster size variable.
static const QString EXPR_GEOMETRY_POINT_NUM
Inbuilt variable name for point number variable.
static const QString EXPR_GEOMETRY_RING_NUM
Inbuilt variable name for geometry ring number variable.
static const QString EXPR_GEOMETRY_PART_NUM
Inbuilt variable name for geometry part number variable.
static const QString EXPR_SYMBOL_COLOR
Inbuilt variable name for symbol color variable.
static const QString EXPR_ORIGINAL_VALUE
Inbuilt variable name for value original value variable.
static const QString EXPR_CLUSTER_COLOR
Inbuilt variable name for cluster color variable.
void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which widget is shown, e.g., the associated map canvas and expression contexts.
double extentBuffer() const
Returns the extent buffer value currently set in the widget.
QgsProperty dataDefinedProperty() const
Returns the data defined property currently set in the widget.
Qgis::RenderUnit sizeUnit() const
Returns the extent buffer unit currently set in the widget.
A line symbol type, for rendering LineString and MultiLineString geometries.
void setDataDefinedWidth(const QgsProperty &property) const
Set data defined width for whole symbol (including all symbol layers).
void setWidth(double width) const
Sets the width for the whole line symbol.
double width() const
Returns the estimated width for the whole symbol, which is the maximum width of all marker symbol lay...
QgsProperty dataDefinedWidth() const
Returns data defined width for whole symbol (including all symbol layers).
A marker symbol type, for rendering Point and MultiPoint geometries.
void setScaleMethod(Qgis::ScaleMethod scaleMethod) const
Sets the method to use for scaling the marker's size.
void setAngle(double symbolAngle) const
Sets the angle for the whole symbol.
void setSize(double size) const
Sets the size for the whole symbol.
QgsProperty dataDefinedAngle() const
Returns data defined angle for whole symbol (including all symbol layers).
double size() const
Returns the estimated size for the whole symbol, which is the maximum size of all marker symbol layer...
double angle() const
Returns the marker angle for the whole symbol.
QgsProperty dataDefinedSize() const
Returns data defined size for whole symbol (including all symbol layers).
void setDataDefinedSize(const QgsProperty &property) const
Set data defined size for whole symbol (including all symbol layers).
void setDataDefinedAngle(const QgsProperty &property)
Set data defined angle for whole symbol (including all symbol layers).
void opacityChanged(double opacity)
Emitted when the opacity is changed in the widget, where opacity ranges from 0.0 (transparent) to 1....
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
bool dockMode() const
Returns the dock mode state.
void widgetChanged()
Emitted when the widget state changes.
static QgsPanelWidget * findParentPanel(QWidget *widget)
Traces through the parents of a widget to find if it is contained within a QgsPanelWidget widget.
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
QgsStyle * styleAtPath(const QString &path)
Returns a reference to the style database associated with the project with matching file path.
static QgsProject * instance()
Returns the QgsProject singleton instance.
const QgsProjectStyleSettings * styleSettings() const
Returns the project's style settings, which contains settings and properties relating to how a QgsPro...
A button for controlling property overrides which may apply to a widget.
QgsProperty toProperty() const
Returns a QgsProperty object encapsulating the current state of the widget.
void updateFieldLists()
Updates list of fields.
void changed()
Emitted when property definition changes.
void init(int propertyKey, const QgsProperty &property, const QgsPropertiesDefinition &definitions, const QgsVectorLayer *layer=nullptr, bool auxiliaryStorageEnabled=false)
Initialize a newly constructed property button (useful if button was included in a UI layout).
void registerExpressionContextGenerator(QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
int propertyKey() const
Returns the property key linked to the button.
void setToProperty(const QgsProperty &property)
Sets the widget to reflect the current state of a QgsProperty.
void createAuxiliaryField()
Emitted when creating a new auxiliary field.
A store for object properties.
void setField(const QString &field)
Sets the field name the property references.
void saveEntity()
Emitted when the user has opted to save a new entity to the style database, by clicking the "Save" bu...
void selectionChangedWithStylePath(const QString &name, QgsStyle::StyleEntity type, const QString &stylePath)
Emitted when the selected item is changed in the widget.
A database of saved style entities, including symbols, color ramps, text formats and others.
Definition qgsstyle.h:89
bool removeSymbol(const QString &name)
Removes symbol from style (and delete it).
Definition qgsstyle.cpp:283
QgsSymbol * symbol(const QString &name)
Returns a NEW copy of symbol.
Definition qgsstyle.cpp:317
StyleEntity
Enum for Entities involved in a style.
Definition qgsstyle.h:204
@ SymbolEntity
Symbols.
Definition qgsstyle.h:205
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
Definition qgsstyle.cpp:148
bool saveSymbol(const QString &name, const QgsSymbol *symbol, bool favorite, const QStringList &tags)
Adds the symbol to the database with tags.
Definition qgsstyle.cpp:251
bool addSymbol(const QString &name, QgsSymbol *symbol, bool update=false)
Adds a symbol to style and takes symbol's ownership.
Definition qgsstyle.cpp:226
QStringList symbolNames() const
Returns a list of names of symbols.
Definition qgsstyle.cpp:339
void setAnimationSettings(const QgsSymbolAnimationSettings &settings)
Sets the animation settings to show in the widget.
QgsSymbolAnimationSettings animationSettings() const
Returns the animation settings as defined in the widget.
QgsSymbolBufferSettings bufferSettings() const
Returns the buffer settings as defined in the widget.
void setBufferSettings(const QgsSymbolBufferSettings &settings)
Sets the buffer settings to show in the widget.
Property
Data definable properties.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the symbol layer property definitions.
Contains settings which reflect the context in which a symbol (or renderer) widget is shown,...
Abstract base class for all rendered symbols.
Definition qgssymbol.h:227
Property
Data definable properties.
Definition qgssymbol.h:272
@ ExtentBuffer
Extent buffer.
Definition qgssymbol.h:274
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the symbol property definitions.
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
Qgis::SymbolType type() const
Returns the symbol's type.
Definition qgssymbol.h:296
void setForceRHR(bool force)
Sets whether polygon features drawn by the symbol should be reoriented to follow the standard right-h...
Definition qgssymbol.h:743
void setLineWidth(double width)
QgsSymbolWidgetContext context() const
Returns the context in which the symbol widget is shown, e.g., the associated map canvas and expressi...
void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
void setSymbolColor(const QColor &color)
void setMarkerAngle(double angle)
QgsSymbolsListWidget(QgsSymbol *symbol, QgsStyle *style, QMenu *menu, QWidget *parent, QgsVectorLayer *layer=nullptr)
Constructor for QgsSymbolsListWidget.
const QgsVectorLayer * layer() const
Returns the vector layer associated with the widget.
void changed()
Emitted when the symbol is modified in the widget.
void clipFeaturesToggled(bool checked)
void setMarkerSize(double size)
A widget displaying a combobox allowing the user to choose between various display units,...
void changed()
Emitted when the selected unit is changed, or the definition of the map unit scale is changed.
Represents a vector layer which manages a vector based dataset.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition qgis.h:6880