QGIS API Documentation 3.99.0-Master (2fe06baccd8)
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
34#include "moc_qgssymbolslistwidget.cpp"
35
36QgsSymbolsListWidget::QgsSymbolsListWidget( QgsSymbol *symbol, QgsStyle *style, QMenu *menu, QWidget *parent, QgsVectorLayer *layer )
37 : QWidget( parent )
38 , mSymbol( symbol )
39 , mStyle( style )
40 , mAdvancedMenu( menu )
41 , mLayer( layer )
42{
43 setupUi( this );
44 spinAngle->setClearValue( 0 );
45
46 mStyleItemsListWidget->setStyle( mStyle );
47 mStyleItemsListWidget->setEntityType( QgsStyle::SymbolEntity );
48 if ( mSymbol )
49 mStyleItemsListWidget->setSymbolType( mSymbol->type() );
50 mStyleItemsListWidget->setAdvancedMenu( menu );
51
52 mClipFeaturesAction = new QAction( tr( "Clip Features to Canvas Extent" ), this );
53 mClipFeaturesAction->setCheckable( true );
54 connect( mClipFeaturesAction, &QAction::toggled, this, &QgsSymbolsListWidget::clipFeaturesToggled );
55 mStandardizeRingsAction = new QAction( tr( "Force Right-Hand-Rule Orientation" ), this );
56 mStandardizeRingsAction->setCheckable( true );
57 connect( mStandardizeRingsAction, &QAction::toggled, this, &QgsSymbolsListWidget::forceRHRToggled );
58
59 mBufferSettingsAction = new QAction( tr( "Buffer Settings…" ), this );
60 connect( mBufferSettingsAction, &QAction::triggered, this, &QgsSymbolsListWidget::showBufferSettings );
61
62 mAnimationSettingsAction = new QAction( tr( "Animation Settings…" ), this );
63 connect( mAnimationSettingsAction, &QAction::triggered, this, &QgsSymbolsListWidget::showAnimationSettings );
64
65 mExtentBufferAction = new QAction( tr( "Extent Buffer…" ), this );
66 connect( mExtentBufferAction, &QAction::triggered, this, &QgsSymbolsListWidget::showExtentBufferSettings );
67
68 // select correct page in stacked widget
69 QgsPropertyOverrideButton *opacityDDBtn = nullptr;
70 switch ( symbol->type() )
71 {
73 {
74 stackedWidget->removeWidget( stackedWidget->widget( 2 ) );
75 stackedWidget->removeWidget( stackedWidget->widget( 1 ) );
76 mSymbolColorButton = btnMarkerColor;
77 opacityDDBtn = mMarkerOpacityDDBtn;
78 mSymbolOpacityWidget = mMarkerOpacityWidget;
79 mSymbolUnitWidget = mMarkerUnitWidget;
80 connect( spinAngle, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSymbolsListWidget::setMarkerAngle );
81 connect( spinSize, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSymbolsListWidget::setMarkerSize );
82 registerDataDefinedButton( mSizeDDBtn, QgsSymbolLayer::Property::Size );
84 registerDataDefinedButton( mRotationDDBtn, QgsSymbolLayer::Property::Angle );
86 break;
87 }
88
90 {
91 stackedWidget->removeWidget( stackedWidget->widget( 2 ) );
92 stackedWidget->removeWidget( stackedWidget->widget( 0 ) );
93 mSymbolColorButton = btnLineColor;
94 opacityDDBtn = mLineOpacityDDBtn;
95 mSymbolOpacityWidget = mLineOpacityWidget;
96 mSymbolUnitWidget = mLineUnitWidget;
97 connect( spinWidth, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsSymbolsListWidget::setLineWidth );
98 registerDataDefinedButton( mWidthDDBtn, QgsSymbolLayer::Property::StrokeWidth );
100 break;
101 }
102
104 {
105 stackedWidget->removeWidget( stackedWidget->widget( 1 ) );
106 stackedWidget->removeWidget( stackedWidget->widget( 0 ) );
107 mSymbolColorButton = btnFillColor;
108 opacityDDBtn = mFillOpacityDDBtn;
109 mSymbolOpacityWidget = mFillOpacityWidget;
110 mSymbolUnitWidget = mFillUnitWidget;
111 break;
112 }
113
115 break;
116 }
117
118 stackedWidget->setCurrentIndex( 0 );
119
121
122 if ( mSymbol )
123 {
124 updateSymbolInfo();
125 }
126
127 connect( mSymbolUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsSymbolsListWidget::mSymbolUnitWidget_changed );
128 connect( mSymbolColorButton, &QgsColorButton::colorChanged, this, &QgsSymbolsListWidget::setSymbolColor );
129
130 if ( opacityDDBtn )
131 {
132 registerSymbolDataDefinedButton( opacityDDBtn, QgsSymbol::Property::Opacity );
133 }
134
135 connect( this, &QgsSymbolsListWidget::changed, this, &QgsSymbolsListWidget::updateAssistantSymbol );
136 if ( mSymbol )
137 {
138 updateAssistantSymbol();
139 }
140
141 mSymbolColorButton->setAllowOpacity( true );
142 mSymbolColorButton->setColorDialogTitle( tr( "Select Color" ) );
143 mSymbolColorButton->setContext( QStringLiteral( "symbology" ) );
144
145 connect( mSymbolOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsSymbolsListWidget::opacityChanged );
146
147 connect( mStyleItemsListWidget, &QgsStyleItemsListWidget::selectionChangedWithStylePath, this, &QgsSymbolsListWidget::setSymbolFromStyle );
148 connect( mStyleItemsListWidget, &QgsStyleItemsListWidget::saveEntity, this, &QgsSymbolsListWidget::saveSymbol );
149}
150
152{
153 // This action was added to the menu by this widget, clean it up
154 // The menu can be passed in the constructor, so may live longer than this widget
155 mStyleItemsListWidget->advancedMenu()->removeAction( mClipFeaturesAction );
156 mStyleItemsListWidget->advancedMenu()->removeAction( mStandardizeRingsAction );
157 mStyleItemsListWidget->advancedMenu()->removeAction( mAnimationSettingsAction );
158 mStyleItemsListWidget->advancedMenu()->removeAction( mExtentBufferAction );
159 mStyleItemsListWidget->advancedMenu()->removeAction( mBufferSettingsAction );
160}
161
162void QgsSymbolsListWidget::registerDataDefinedButton( QgsPropertyOverrideButton *button, QgsSymbolLayer::Property key )
163{
164 button->setProperty( "propertyKey", static_cast<int>( key ) );
166
167 connect( button, &QgsPropertyOverrideButton::createAuxiliaryField, this, &QgsSymbolsListWidget::createAuxiliaryField );
168}
169
170void QgsSymbolsListWidget::createAuxiliaryField()
171{
172 // try to create an auxiliary layer if not yet created
173 if ( !mLayer->auxiliaryLayer() )
174 {
175 QgsNewAuxiliaryLayerDialog dlg( mLayer, this );
176 dlg.exec();
177 }
178
179 // return if still not exists
180 if ( !mLayer->auxiliaryLayer() )
181 return;
182
183 QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
184 const QgsSymbolLayer::Property key = static_cast<QgsSymbolLayer::Property>( button->propertyKey() );
185 const QgsPropertyDefinition def = QgsSymbolLayer::propertyDefinitions()[static_cast<int>( key )];
186
187 // create property in auxiliary storage if necessary
188 if ( !mLayer->auxiliaryLayer()->exists( def ) )
189 mLayer->auxiliaryLayer()->addAuxiliaryField( def );
190
191 // update property with join field name from auxiliary storage
192 QgsProperty property = button->toProperty();
193 property.setField( QgsAuxiliaryLayer::nameFromProperty( def, true ) );
194 property.setActive( true );
195 button->updateFieldLists();
196 button->setToProperty( property );
197
198 QgsMarkerSymbol *markerSymbol = static_cast<QgsMarkerSymbol *>( mSymbol );
199 QgsLineSymbol *lineSymbol = static_cast<QgsLineSymbol *>( mSymbol );
200 switch ( key )
201 {
203 if ( markerSymbol )
204 markerSymbol->setDataDefinedAngle( button->toProperty() );
205 break;
206
208 if ( markerSymbol )
209 {
210 markerSymbol->setDataDefinedSize( button->toProperty() );
212 }
213 break;
214
216 if ( lineSymbol )
217 lineSymbol->setDataDefinedWidth( button->toProperty() );
218 break;
219
220 default:
221 break;
222 }
223
224 emit changed();
225}
226
227void QgsSymbolsListWidget::createSymbolAuxiliaryField()
228{
229 // try to create an auxiliary layer if not yet created
230 if ( !mLayer->auxiliaryLayer() )
231 {
232 QgsNewAuxiliaryLayerDialog dlg( mLayer, this );
233 dlg.exec();
234 }
235
236 // return if still not exists
237 if ( !mLayer->auxiliaryLayer() )
238 return;
239
240 QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
241 const QgsSymbol::Property key = static_cast<QgsSymbol::Property>( button->propertyKey() );
242 const QgsPropertyDefinition def = QgsSymbol::propertyDefinitions()[static_cast<int>( key )];
243
244 // create property in auxiliary storage if necessary
245 if ( !mLayer->auxiliaryLayer()->exists( def ) )
246 mLayer->auxiliaryLayer()->addAuxiliaryField( def );
247
248 // update property with join field name from auxiliary storage
249 QgsProperty property = button->toProperty();
250 property.setField( QgsAuxiliaryLayer::nameFromProperty( def, true ) );
251 property.setActive( true );
252 button->updateFieldLists();
253 button->setToProperty( property );
254
255 mSymbol->setDataDefinedProperty( key, button->toProperty() );
256
257 emit changed();
258}
259
261{
262 mContext = context;
263 const auto unitSelectionWidgets { findChildren<QgsUnitSelectionWidget *>() };
264 for ( QgsUnitSelectionWidget *unitWidget : unitSelectionWidgets )
265 {
266 unitWidget->setMapCanvas( mContext.mapCanvas() );
267 }
268}
269
271{
272 return mContext;
273}
274
275void QgsSymbolsListWidget::forceRHRToggled( bool checked )
276{
277 if ( !mSymbol )
278 return;
279
280 mSymbol->setForceRHR( checked );
281 emit changed();
282}
283
284void QgsSymbolsListWidget::showAnimationSettings()
285{
286 QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( this );
287 if ( panel && panel->dockMode() )
288 {
289 QgsSymbolAnimationSettingsWidget *widget = new QgsSymbolAnimationSettingsWidget( panel );
290 widget->setPanelTitle( tr( "Animation Settings" ) );
291 widget->setAnimationSettings( mSymbol->animationSettings() );
292 connect( widget, &QgsPanelWidget::widgetChanged, this, [this, widget]() {
293 mSymbol->setAnimationSettings( widget->animationSettings() );
294 emit changed();
295 } );
296 panel->openPanel( widget );
297 return;
298 }
299
300 QgsSymbolAnimationSettingsDialog d( this );
301 d.setAnimationSettings( mSymbol->animationSettings() );
302 if ( d.exec() == QDialog::Accepted )
303 {
304 mSymbol->setAnimationSettings( d.animationSettings() );
305 emit changed();
306 }
307}
308
309void QgsSymbolsListWidget::showExtentBufferSettings()
310{
311 QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( this );
312 if ( panel && panel->dockMode() )
313 {
314 QgsExtentBufferWidget *widget = new QgsExtentBufferWidget( mSymbol, mLayer, panel );
315 widget->setPanelTitle( tr( "Extent Buffer" ) );
316 widget->setContext( mContext );
317
318 connect( widget, &QgsPanelWidget::widgetChanged, this, [this, widget]() {
319 mSymbol->setExtentBuffer( widget->extentBuffer() );
320 mSymbol->setDataDefinedProperty( QgsSymbol::Property::ExtentBuffer, widget->dataDefinedProperty() );
321 mSymbol->setExtentBufferSizeUnit( widget->sizeUnit() );
322
323 emit changed();
324 } );
325
326 panel->openPanel( widget );
327 }
328 else
329 {
330 QgsExtentBufferDialog dlg( mSymbol, mLayer, panel );
331
332 if ( dlg.widget() )
333 {
334 dlg.setContext( mContext );
335 }
336
337 if ( dlg.exec() == QDialog::Accepted )
338 {
339 mSymbol->setExtentBuffer( dlg.extentBuffer() );
340 mSymbol->setDataDefinedProperty( QgsSymbol::Property::ExtentBuffer, dlg.dataDefinedProperty() );
341 mSymbol->setExtentBufferSizeUnit( dlg.sizeUnit() );
342
343 emit changed();
344 }
345 }
346}
347
348void QgsSymbolsListWidget::showBufferSettings()
349{
350 QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( this );
351 if ( panel && panel->dockMode() )
352 {
353 QgsSymbolBufferSettingsWidget *widget = new QgsSymbolBufferSettingsWidget( panel );
354 widget->setPanelTitle( tr( "Buffer Settings" ) );
355 if ( const QgsSymbolBufferSettings *settings = mSymbol->bufferSettings() )
356 widget->setBufferSettings( *settings );
357
358 connect( widget, &QgsPanelWidget::widgetChanged, this, [this, widget]() {
359 mSymbol->setBufferSettings( new QgsSymbolBufferSettings( widget->bufferSettings() ) );
360 emit changed();
361 } );
362 panel->openPanel( widget );
363 return;
364 }
365
366 QgsSymbolBufferSettingsDialog d( this );
367 if ( const QgsSymbolBufferSettings *settings = mSymbol->bufferSettings() )
368 d.setBufferSettings( *settings );
369 if ( d.exec() == QDialog::Accepted )
370 {
371 mSymbol->setBufferSettings( new QgsSymbolBufferSettings( d.bufferSettings() ) );
372 emit changed();
373 }
374}
375
376void QgsSymbolsListWidget::saveSymbol()
377{
378 QgsStyleSaveDialog saveDlg( this );
379 saveDlg.setDefaultTags( mStyleItemsListWidget->currentTagFilter() );
380 if ( !saveDlg.exec() )
381 return;
382
383 if ( saveDlg.name().isEmpty() )
384 return;
385
386 QgsStyle *style = saveDlg.destinationStyle();
387 if ( !style )
388 return;
389
390 // check if there is no symbol with same name
391 if ( style->symbolNames().contains( saveDlg.name() ) )
392 {
393 const int res = QMessageBox::warning( this, tr( "Save Symbol" ), tr( "Symbol with name '%1' already exists. Overwrite?" ).arg( saveDlg.name() ), QMessageBox::Yes | QMessageBox::No );
394 if ( res != QMessageBox::Yes )
395 {
396 return;
397 }
398 style->removeSymbol( saveDlg.name() );
399 }
400
401 const QStringList symbolTags = saveDlg.tags().split( ',' );
402
403 // add new symbol to style and re-populate the list
404 QgsSymbol *newSymbol = mSymbol->clone();
405 style->addSymbol( saveDlg.name(), newSymbol );
406
407 // make sure the symbol is stored
408 style->saveSymbol( saveDlg.name(), newSymbol, saveDlg.isFavorite(), symbolTags );
409}
410
411void QgsSymbolsListWidget::updateSymbolDataDefinedProperty()
412{
413 if ( !mSymbol )
414 return;
415
416 QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
417 const QgsSymbol::Property key = static_cast<QgsSymbol::Property>( button->propertyKey() );
418 mSymbol->setDataDefinedProperty( key, button->toProperty() );
419 emit changed();
420}
421
422void QgsSymbolsListWidget::registerSymbolDataDefinedButton( QgsPropertyOverrideButton *button, QgsSymbol::Property key )
423{
424 button->init( static_cast<int>( key ), mSymbol ? mSymbol->dataDefinedProperties() : QgsPropertyCollection(), QgsSymbol::propertyDefinitions(), mLayer, true );
425 connect( button, &QgsPropertyOverrideButton::changed, this, &QgsSymbolsListWidget::updateSymbolDataDefinedProperty );
426 connect( button, &QgsPropertyOverrideButton::createAuxiliaryField, this, &QgsSymbolsListWidget::createSymbolAuxiliaryField );
427
429}
430
432{
433 if ( !mSymbol )
434 return;
435
436 mSymbol->setClipFeaturesToExtent( checked );
437 emit changed();
438}
439
440void QgsSymbolsListWidget::setSymbolColor( const QColor &color )
441{
442 mSymbol->setColor( color );
443 emit changed();
444}
445
447{
448 QgsMarkerSymbol *markerSymbol = static_cast<QgsMarkerSymbol *>( mSymbol );
449 if ( markerSymbol->angle() == angle )
450 return;
451 markerSymbol->setAngle( angle );
452 emit changed();
453}
454
456{
457 QgsMarkerSymbol *markerSymbol = static_cast<QgsMarkerSymbol *>( mSymbol );
458 const QgsProperty dd( mRotationDDBtn->toProperty() );
459
460 spinAngle->setEnabled( !mRotationDDBtn->isActive() );
461
462 const QgsProperty symbolDD( markerSymbol->dataDefinedAngle() );
463
464 if ( // shall we remove datadefined expressions for layers ?
465 ( !symbolDD && !dd )
466 // shall we set the "en masse" expression for properties ?
467 || dd
468 )
469 {
470 markerSymbol->setDataDefinedAngle( dd );
471 emit changed();
472 }
473}
474
476{
477 QgsMarkerSymbol *markerSymbol = static_cast<QgsMarkerSymbol *>( mSymbol );
478 if ( markerSymbol->size() == size )
479 return;
480 markerSymbol->setSize( size );
481 emit changed();
482}
483
485{
486 QgsMarkerSymbol *markerSymbol = static_cast<QgsMarkerSymbol *>( mSymbol );
487 const QgsProperty dd( mSizeDDBtn->toProperty() );
488
489 spinSize->setEnabled( !mSizeDDBtn->isActive() );
490
491 const QgsProperty symbolDD( markerSymbol->dataDefinedSize() );
492
493 if ( // shall we remove datadefined expressions for layers ?
494 ( !symbolDD && !dd )
495 // shall we set the "en masse" expression for properties ?
496 || dd
497 )
498 {
499 markerSymbol->setDataDefinedSize( dd );
501 emit changed();
502 }
503}
504
506{
507 QgsLineSymbol *lineSymbol = static_cast<QgsLineSymbol *>( mSymbol );
508 if ( lineSymbol->width() == width )
509 return;
510 lineSymbol->setWidth( width );
511 emit changed();
512}
513
515{
516 QgsLineSymbol *lineSymbol = static_cast<QgsLineSymbol *>( mSymbol );
517 const QgsProperty dd( mWidthDDBtn->toProperty() );
518
519 spinWidth->setEnabled( !mWidthDDBtn->isActive() );
520
521 const QgsProperty symbolDD( lineSymbol->dataDefinedWidth() );
522
523 if ( // shall we remove datadefined expressions for layers ?
524 ( !symbolDD && !dd )
525 // shall we set the "en masse" expression for properties ?
526 || dd
527 )
528 {
529 lineSymbol->setDataDefinedWidth( dd );
530 emit changed();
531 }
532}
533
534void QgsSymbolsListWidget::updateAssistantSymbol()
535{
536 mAssistantSymbol.reset( mSymbol->clone() );
537 if ( mSymbol->type() == Qgis::SymbolType::Marker )
538 mSizeDDBtn->setSymbol( mAssistantSymbol );
539 else if ( mSymbol->type() == Qgis::SymbolType::Line && mLayer )
540 mWidthDDBtn->setSymbol( mAssistantSymbol );
541}
542
543void QgsSymbolsListWidget::mSymbolUnitWidget_changed()
544{
545 if ( mSymbol )
546 {
547 mSymbol->setOutputUnit( mSymbolUnitWidget->unit() );
548 mSymbol->setMapUnitScale( mSymbolUnitWidget->getMapUnitScale() );
549
550 emit changed();
551 }
552}
553
554void QgsSymbolsListWidget::opacityChanged( double opacity )
555{
556 if ( mSymbol )
557 {
558 mSymbol->setOpacity( opacity );
559 emit changed();
560 }
561}
562
563void QgsSymbolsListWidget::updateSymbolColor()
564{
565 mSymbolColorButton->blockSignals( true );
566 mSymbolColorButton->setColor( mSymbol->color() );
567 mSymbolColorButton->blockSignals( false );
568}
569
571{
572 if ( auto *lExpressionContext = mContext.expressionContext() )
573 return QgsExpressionContext( *lExpressionContext );
574
575 //otherwise create a default symbol context
576 QgsExpressionContext expContext( mContext.globalProjectAtlasMapLayerScopes( layer() ) );
577
578 // additional scopes
579 const auto constAdditionalExpressionContextScopes = mContext.additionalExpressionContextScopes();
580 for ( const QgsExpressionContextScope &scope : constAdditionalExpressionContextScopes )
581 {
582 expContext.appendScope( new QgsExpressionContextScope( scope ) );
583 }
584
586
587 return expContext;
588}
589
590void QgsSymbolsListWidget::updateSymbolInfo()
591{
592 updateSymbolColor();
593
594 const QList<QgsPropertyOverrideButton *> overrideButtons { findChildren<QgsPropertyOverrideButton *>() };
595 for ( QgsPropertyOverrideButton *button : overrideButtons )
596 {
598 }
599
600 if ( mSymbol->type() == Qgis::SymbolType::Marker )
601 {
602 QgsMarkerSymbol *markerSymbol = static_cast<QgsMarkerSymbol *>( mSymbol );
603 spinSize->setValue( markerSymbol->size() );
604 spinAngle->setValue( markerSymbol->angle() );
605
606 if ( mLayer )
607 {
608 const QgsProperty ddSize( markerSymbol->dataDefinedSize() );
609 mSizeDDBtn->init( static_cast<int>( QgsSymbolLayer::Property::Size ), ddSize, QgsSymbolLayer::propertyDefinitions(), mLayer, true );
610 spinSize->setEnabled( !mSizeDDBtn->isActive() );
611 const QgsProperty ddAngle( markerSymbol->dataDefinedAngle() );
612 mRotationDDBtn->init( static_cast<int>( QgsSymbolLayer::Property::Angle ), ddAngle, QgsSymbolLayer::propertyDefinitions(), mLayer, true );
613 spinAngle->setEnabled( !mRotationDDBtn->isActive() );
614 }
615 else
616 {
617 mSizeDDBtn->setEnabled( false );
618 mRotationDDBtn->setEnabled( false );
619 }
620 }
621 else if ( mSymbol->type() == Qgis::SymbolType::Line )
622 {
623 QgsLineSymbol *lineSymbol = static_cast<QgsLineSymbol *>( mSymbol );
624 spinWidth->setValue( lineSymbol->width() );
625
626 if ( mLayer )
627 {
628 const QgsProperty dd( lineSymbol->dataDefinedWidth() );
629 mWidthDDBtn->init( static_cast<int>( QgsSymbolLayer::Property::StrokeWidth ), dd, QgsSymbolLayer::propertyDefinitions(), mLayer, true );
630 spinWidth->setEnabled( !mWidthDDBtn->isActive() );
631 }
632 else
633 {
634 mWidthDDBtn->setEnabled( false );
635 }
636 }
637
638 mSymbolUnitWidget->blockSignals( true );
639 mSymbolUnitWidget->setUnit( mSymbol->outputUnit() );
640 mSymbolUnitWidget->setMapUnitScale( mSymbol->mapUnitScale() );
641 mSymbolUnitWidget->blockSignals( false );
642
643 mSymbolOpacityWidget->setOpacity( mSymbol->opacity() );
644
645 // Clean up previous advanced symbol actions
646 const QList<QAction *> actionList( mStyleItemsListWidget->advancedMenu()->actions() );
647 for ( QAction *action : actionList )
648 {
649 for ( QAction *actionsToRemove :
650 {
651 mClipFeaturesAction,
652 mStandardizeRingsAction,
653 mAnimationSettingsAction,
654 mExtentBufferAction,
655 mBufferSettingsAction
656 } )
657 {
658 if ( actionsToRemove->text() == action->text() )
659 {
660 mStyleItemsListWidget->advancedMenu()->removeAction( action );
661 break;
662 }
663 }
664 }
665
666 if ( mSymbol->type() == Qgis::SymbolType::Line || mSymbol->type() == Qgis::SymbolType::Fill )
667 {
668 //add clip features option for line or fill symbols
669 mStyleItemsListWidget->advancedMenu()->addAction( mClipFeaturesAction );
670 }
671 if ( mSymbol->type() == Qgis::SymbolType::Fill )
672 {
673 mStyleItemsListWidget->advancedMenu()->addAction( mStandardizeRingsAction );
674 }
675 if ( mSymbol->type() == Qgis::SymbolType::Marker )
676 {
677 mStyleItemsListWidget->advancedMenu()->addAction( mBufferSettingsAction );
678 }
679 mStyleItemsListWidget->advancedMenu()->addAction( mAnimationSettingsAction );
680 mStyleItemsListWidget->advancedMenu()->addAction( mExtentBufferAction );
681
682 mStyleItemsListWidget->showAdvancedButton( mAdvancedMenu || !mStyleItemsListWidget->advancedMenu()->isEmpty() );
683
684 whileBlocking( mClipFeaturesAction )->setChecked( mSymbol->clipFeaturesToExtent() );
685 whileBlocking( mStandardizeRingsAction )->setChecked( mSymbol->forceRHR() );
686}
687
688void QgsSymbolsListWidget::setSymbolFromStyle( const QString &name, QgsStyle::StyleEntity, const QString &stylePath )
689{
690 if ( name.isEmpty() )
691 return;
692
693 QgsStyle *style = nullptr;
694 if ( mStyle != QgsStyle::defaultStyle() )
695 {
696 // get new instance of symbol from style
697 style = mStyle;
698 }
699 else
700 {
701 style = QgsProject::instance()->styleSettings()->styleAtPath( stylePath );
702 }
703
704 if ( !style )
705 return;
706
707 // get new instance of symbol from style
708 std::unique_ptr<QgsSymbol> s( style->symbol( name ) );
709 if ( !s )
710 return;
711
712 // remove all symbol layers from original symbolgroupsCombo
713 while ( mSymbol->symbolLayerCount() )
714 mSymbol->deleteSymbolLayer( 0 );
715 // move all symbol layers to our symbol
716 while ( s->symbolLayerCount() )
717 {
718 QgsSymbolLayer *sl = s->takeSymbolLayer( 0 );
719 mSymbol->appendSymbolLayer( sl );
720 }
721 mSymbol->setOpacity( s->opacity() );
722 mSymbol->setFlags( s->flags() );
723
724 updateSymbolInfo();
725 emit changed();
726}
@ ScaleDiameter
Calculate scale by the diameter.
Definition qgis.h:626
@ Millimeters
Millimeters.
Definition qgis.h:5184
@ Points
Points (e.g., for font sizes).
Definition qgis.h:5188
@ MapUnits
Map units.
Definition qgis.h:5185
@ Pixels
Pixels.
Definition qgis.h:5186
@ Inches
Inches.
Definition qgis.h:5189
@ MetersInMapUnits
Meters value as Map units.
Definition qgis.h:5191
@ Marker
Marker symbol.
Definition qgis.h:611
@ Line
Line symbol.
Definition qgis.h:612
@ Fill
Fill symbol.
Definition qgis.h:613
@ Hybrid
Hybrid symbol.
Definition qgis.h:614
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:88
bool removeSymbol(const QString &name)
Removes symbol from style (and delete it).
Definition qgsstyle.cpp:286
QgsSymbol * symbol(const QString &name)
Returns a NEW copy of symbol.
Definition qgsstyle.cpp:320
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:147
bool saveSymbol(const QString &name, const QgsSymbol *symbol, bool favorite, const QStringList &tags)
Adds the symbol to the database with tags.
Definition qgsstyle.cpp:250
bool addSymbol(const QString &name, QgsSymbol *symbol, bool update=false)
Adds a symbol to style and takes symbol's ownership.
Definition qgsstyle.cpp:225
QStringList symbolNames() const
Returns a list of names of symbols.
Definition qgsstyle.cpp:342
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:231
Property
Data definable properties.
Definition qgssymbol.h:270
@ ExtentBuffer
Extent buffer.
Definition qgssymbol.h:272
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:294
void setForceRHR(bool force)
Sets whether polygon features drawn by the symbol should be reoriented to follow the standard right-h...
Definition qgssymbol.h:725
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:6511