19#include "moc_qgslayoutlegendwidget.cpp"
51#include <QInputDialog>
52#include <QActionGroup>
67 int unfilteredNodeIndex = _unfilteredLegendNodeIndex( legendNode );
69 return ( unfilteredNodeIndex >= 0 && unfilteredNodeIndex < order.count() ? order[unfilteredNodeIndex] : -1 );
76 , mMapCanvas( mapCanvas )
81 connect( mWrapCharLineEdit, &QLineEdit::textChanged,
this, &QgsLayoutLegendWidget::mWrapCharLineEdit_textChanged );
82 connect( mTitleLineEdit, &QLineEdit::textChanged,
this, &QgsLayoutLegendWidget::mTitleLineEdit_textChanged );
87 connect( mColumnCountSpinBox,
static_cast < void ( QSpinBox::* )(
int )
> ( &QSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mColumnCountSpinBox_valueChanged );
88 connect( mSplitLayerCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mSplitLayerCheckBox_toggled );
89 connect( mEqualColumnWidthCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mEqualColumnWidthCheckBox_toggled );
90 connect( mSymbolWidthSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mSymbolWidthSpinBox_valueChanged );
91 connect( mSymbolHeightSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mSymbolHeightSpinBox_valueChanged );
92 connect( mMaxSymbolSizeSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mMaxSymbolSizeSpinBox_valueChanged );
93 connect( mMinSymbolSizeSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mMinSymbolSizeSpinBox_valueChanged );
94 connect( mWmsLegendWidthSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mWmsLegendWidthSpinBox_valueChanged );
95 connect( mWmsLegendHeightSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mWmsLegendHeightSpinBox_valueChanged );
96 connect( mTitleSpaceBottomSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mTitleSpaceBottomSpinBox_valueChanged );
97 connect( mGroupSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mGroupSpaceSpinBox_valueChanged );
98 connect( mGroupIndentSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mGroupIndentSpinBox_valueChanged );
99 connect( mSubgroupIndentSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mSubgroupIndentSpinBox_valueChanged );
100 connect( mSpaceBelowGroupHeadingSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceBelowGroupHeadingChanged );
101 connect( mGroupSideSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceGroupSideChanged );
102 connect( mLayerSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mLayerSpaceSpinBox_valueChanged );
103 connect( mSpaceBelowSubgroupHeadingSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceBelowSubGroupHeadingChanged );
104 connect( mSubgroupSideSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceSubGroupSideChanged );
105 connect( mSymbolSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mSymbolSpaceSpinBox_valueChanged );
106 connect( mSymbolSideSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceSymbolSideChanged );
107 connect( mIconLabelSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mIconLabelSpaceSpinBox_valueChanged );
108 connect( mBoxSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mBoxSpaceSpinBox_valueChanged );
109 connect( mColumnSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mColumnSpaceSpinBox_valueChanged );
110 connect( mCheckBoxAutoUpdate, &QCheckBox::stateChanged,
this, [ = ](
int state ) { mCheckBoxAutoUpdate_stateChanged( state ); } );
111 connect( mCheckboxResizeContents, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mCheckboxResizeContents_toggled );
112 connect( mRasterStrokeGroupBox, &QgsCollapsibleGroupBoxBasic::toggled,
this, &QgsLayoutLegendWidget::mRasterStrokeGroupBox_toggled );
113 connect( mRasterStrokeWidthSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mRasterStrokeWidthSpinBox_valueChanged );
114 connect( mRasterStrokeColorButton, &
QgsColorButton::colorChanged,
this, &QgsLayoutLegendWidget::mRasterStrokeColorButton_colorChanged );
115 connect( mExpandAllToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::expandLegendTree );
116 connect( mCollapseAllToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::collapseLegendTree );
117 connect( mMoveDownToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mMoveDownToolButton_clicked );
118 connect( mMoveUpToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mMoveUpToolButton_clicked );
119 connect( mRemoveToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mRemoveToolButton_clicked );
120 connect( mAddToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mAddToolButton_clicked );
121 connect( mEditPushButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mEditPushButton_clicked );
122 connect( mCountToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mCountToolButton_clicked );
123 connect( mExpressionFilterButton, &QgsLegendFilterButton::toggled,
this, &QgsLayoutLegendWidget::mExpressionFilterButton_toggled );
124 connect( mLayerExpressionButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mLayerExpressionButton_clicked );
125 connect( mFilterByMapCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mFilterByMapCheckBox_toggled );
126 connect( mUpdateAllPushButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mUpdateAllPushButton_clicked );
127 connect( mAddGroupToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mAddGroupToolButton_clicked );
128 connect( mFilterLegendByAtlasCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mFilterLegendByAtlasCheckBox_toggled );
129 connect( mItemTreeView, &QgsLayerTreeView::doubleClicked,
this, &QgsLayoutLegendWidget::mItemTreeView_doubleClicked );
131 connect( mFilterByMapCheckBox, &QCheckBox::toggled, mButtonLinkedMaps, &QWidget::setEnabled );
132 mButtonLinkedMaps->setEnabled(
false );
133 connect( mButtonLinkedMaps, &QToolButton::clicked,
this, [ = ]
135 mMapFilteringWidget =
new QgsLayoutLegendMapFilteringWidget( mLegend );
136 openPanel( mMapFilteringWidget );
139 setPanelTitle( tr(
"Legend Properties" ) );
146 mTitleAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
147 mGroupAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
148 mSubgroupAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
149 mItemAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
151 mArrangementCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignRight );
153 mArrangementCombo->customizeAlignmentDisplay( Qt::AlignLeft, tr(
"Symbols on Left" ),
QgsApplication::getThemeIcon( QStringLiteral(
"/mIconArrangeSymbolsLeft.svg" ) ) );
154 mArrangementCombo->customizeAlignmentDisplay( Qt::AlignRight, tr(
"Symbols on Right" ),
QgsApplication::getThemeIcon( QStringLiteral(
"/mIconArrangeSymbolsRight.svg" ) ) );
156 mSpaceBelowGroupHeadingSpinBox->setClearValue( 0 );
157 mGroupSideSpinBox->setClearValue( 0 );
158 mSpaceBelowSubgroupHeadingSpinBox->setClearValue( 0 );
159 mSubgroupSideSpinBox->setClearValue( 0 );
160 mSymbolSideSpaceSpinBox->setClearValue( 0 );
185 mRasterStrokeColorButton->setColorDialogTitle( tr(
"Select Stroke Color" ) );
186 mRasterStrokeColorButton->setAllowOpacity(
true );
187 mRasterStrokeColorButton->setContext( QStringLiteral(
"composer " ) );
189 mMapComboBox->setCurrentLayout( legend->
layout() );
195 mainLayout->addWidget( mItemPropertiesWidget );
197 mItemTreeView->setHeaderHidden(
true );
199 mItemTreeView->setModel( legend->
model() );
200 mItemTreeView->setMenuProvider(
new QgsLayoutLegendMenuProvider( mItemTreeView,
this ) );
201 setLegendMapViewData();
207 connect( layoutAtlas(), &
QgsLayoutAtlas::toggled,
this, &QgsLayoutLegendWidget::updateFilterLegendByAtlasButton );
211 mTitleFontButton->registerExpressionContextGenerator(
this );
212 mGroupFontButton->registerExpressionContextGenerator(
this );
213 mLayerFontButton->registerExpressionContextGenerator(
this );
214 mItemFontButton->registerExpressionContextGenerator(
this );
215 mExpressionFilterButton->registerExpressionContextGenerator(
this );
217 mTitleFontButton->setLayer( coverageLayer() );
218 mGroupFontButton->setLayer( coverageLayer() );
219 mLayerFontButton->setLayer( coverageLayer() );
220 mItemFontButton->setLayer( coverageLayer() );
221 if ( mLegend->layout() )
234 connect( mItemTreeView->selectionModel(), &QItemSelectionModel::currentChanged,
235 this, &QgsLayoutLegendWidget::selectedChanged );
244 if ( mItemPropertiesWidget )
245 mItemPropertiesWidget->setMasterLayout( masterLayout );
251 mTitleFontButton->setMessageBar( iface->
messageBar() );
252 mGroupFontButton->setMessageBar( iface->
messageBar() );
253 mLayerFontButton->setMessageBar( iface->
messageBar() );
254 mItemFontButton->setMessageBar( iface->
messageBar() );
257void QgsLayoutLegendWidget::setGuiElements()
264 blockAllSignals(
true );
265 mTitleLineEdit->setText( mLegend->title() );
266 whileBlocking( mTitleAlignCombo )->setCurrentAlignment( mLegend->titleAlignment() );
270 whileBlocking( mArrangementCombo )->setCurrentAlignment( mLegend->symbolAlignment() );
271 mFilterByMapCheckBox->setChecked( mLegend->legendFilterByMapEnabled() );
272 mButtonLinkedMaps->setEnabled( mLegend->legendFilterByMapEnabled() );
273 mColumnCountSpinBox->setValue( mLegend->columnCount() );
274 mSplitLayerCheckBox->setChecked( mLegend->splitLayer() );
275 mEqualColumnWidthCheckBox->setChecked( mLegend->equalColumnWidth() );
276 mSymbolWidthSpinBox->setValue( mLegend->symbolWidth() );
277 mSymbolHeightSpinBox->setValue( mLegend->symbolHeight() );
278 mMaxSymbolSizeSpinBox->setValue( mLegend->maximumSymbolSize() );
279 mMinSymbolSizeSpinBox->setValue( mLegend->minimumSymbolSize() );
280 mWmsLegendWidthSpinBox->setValue( mLegend->wmsLegendWidth() );
281 mWmsLegendHeightSpinBox->setValue( mLegend->wmsLegendHeight() );
295 mBoxSpaceSpinBox->setValue( mLegend->boxSpace() );
296 mColumnSpaceSpinBox->setValue( mLegend->columnSpace() );
298 mRasterStrokeGroupBox->setChecked( mLegend->drawRasterStroke() );
299 mRasterStrokeWidthSpinBox->setValue( mLegend->rasterStrokeWidth() );
300 mRasterStrokeColorButton->setColor( mLegend->rasterStrokeColor() );
302 mCheckBoxAutoUpdate->setChecked( mLegend->autoUpdateModel() );
304 mCheckboxResizeContents->setChecked( mLegend->resizeToContents() );
305 mFilterLegendByAtlasCheckBox->setChecked( mLegend->legendFilterOutAtlas() );
306 mWrapCharLineEdit->setText( mLegend->wrapString() );
309 mMapComboBox->setItem( map );
315 blockAllSignals(
false );
317 mCheckBoxAutoUpdate_stateChanged( mLegend->autoUpdateModel() ? Qt::Checked : Qt::Unchecked, false );
318 updateDataDefinedButton( mLegendTitleDDBtn );
319 updateDataDefinedButton( mColumnsDDBtn );
322void QgsLayoutLegendWidget::mWrapCharLineEdit_textChanged(
const QString &text )
326 mLegend->beginCommand( tr(
"Change Legend Wrap" ) );
327 mLegend->setWrapString( text );
328 mLegend->adjustBoxSize();
330 mLegend->endCommand();
334void QgsLayoutLegendWidget::mTitleLineEdit_textChanged(
const QString &text )
339 mLegend->setTitle( text );
340 mLegend->adjustBoxSize();
342 mLegend->endCommand();
346void QgsLayoutLegendWidget::titleAlignmentChanged()
350 Qt::AlignmentFlag alignment =
static_cast< Qt::AlignmentFlag
>(
static_cast< int >( mTitleAlignCombo->currentAlignment() & Qt::AlignHorizontal_Mask ) );
351 mLegend->beginCommand( tr(
"Change Title Alignment" ) );
352 mLegend->setTitleAlignment( alignment );
354 mLegend->endCommand();
358void QgsLayoutLegendWidget::groupAlignmentChanged()
362 mLegend->beginCommand( tr(
"Change Group Alignment" ) );
365 mLegend->endCommand();
369void QgsLayoutLegendWidget::subgroupAlignmentChanged()
373 mLegend->beginCommand( tr(
"Change Subgroup Alignment" ) );
376 mLegend->endCommand();
380void QgsLayoutLegendWidget::itemAlignmentChanged()
384 mLegend->beginCommand( tr(
"Change Item Alignment" ) );
387 mLegend->endCommand();
391void QgsLayoutLegendWidget::arrangementChanged()
395 Qt::AlignmentFlag alignment =
static_cast< Qt::AlignmentFlag
>(
static_cast< int >( mArrangementCombo->currentAlignment() & Qt::AlignHorizontal_Mask ) );
396 mLegend->beginCommand( tr(
"Change Legend Arrangement" ) );
397 mLegend->setSymbolAlignment( alignment );
399 mLegend->endCommand();
403void QgsLayoutLegendWidget::mColumnCountSpinBox_valueChanged(
int c )
408 mLegend->setColumnCount(
c );
409 mLegend->adjustBoxSize();
411 mLegend->endCommand();
413 mSplitLayerCheckBox->setEnabled(
c > 1 );
414 mEqualColumnWidthCheckBox->setEnabled(
c > 1 );
417void QgsLayoutLegendWidget::mSplitLayerCheckBox_toggled(
bool checked )
421 mLegend->beginCommand( tr(
"Split Legend Layers" ) );
422 mLegend->setSplitLayer( checked );
423 mLegend->adjustBoxSize();
425 mLegend->endCommand();
429void QgsLayoutLegendWidget::mEqualColumnWidthCheckBox_toggled(
bool checked )
433 mLegend->beginCommand( tr(
"Legend Column Width" ) );
434 mLegend->setEqualColumnWidth( checked );
435 mLegend->adjustBoxSize();
437 mLegend->endCommand();
441void QgsLayoutLegendWidget::mSymbolWidthSpinBox_valueChanged(
double d )
446 mLegend->setSymbolWidth( d );
447 mLegend->adjustBoxSize();
449 mLegend->endCommand();
453void QgsLayoutLegendWidget::mMaxSymbolSizeSpinBox_valueChanged(
double d )
458 mLegend->setMaximumSymbolSize( d );
459 mLegend->adjustBoxSize();
461 mLegend->endCommand();
465void QgsLayoutLegendWidget::mMinSymbolSizeSpinBox_valueChanged(
double d )
470 mLegend->setMinimumSymbolSize( d );
471 mLegend->adjustBoxSize();
473 mLegend->endCommand();
477void QgsLayoutLegendWidget::mSymbolHeightSpinBox_valueChanged(
double d )
482 mLegend->setSymbolHeight( d );
483 mLegend->adjustBoxSize();
485 mLegend->endCommand();
489void QgsLayoutLegendWidget::mWmsLegendWidthSpinBox_valueChanged(
double d )
494 mLegend->setWmsLegendWidth( d );
495 mLegend->adjustBoxSize();
497 mLegend->endCommand();
501void QgsLayoutLegendWidget::mWmsLegendHeightSpinBox_valueChanged(
double d )
506 mLegend->setWmsLegendHeight( d );
507 mLegend->adjustBoxSize();
509 mLegend->endCommand();
513void QgsLayoutLegendWidget::mTitleSpaceBottomSpinBox_valueChanged(
double d )
519 mLegend->adjustBoxSize();
521 mLegend->endCommand();
525void QgsLayoutLegendWidget::mGroupSpaceSpinBox_valueChanged(
double d )
531 mLegend->adjustBoxSize();
533 mLegend->endCommand();
537void QgsLayoutLegendWidget::mGroupIndentSpinBox_valueChanged(
double d )
543 mLegend->adjustBoxSize();
545 mLegend->endCommand();
549void QgsLayoutLegendWidget::mSubgroupIndentSpinBox_valueChanged(
double d )
555 mLegend->adjustBoxSize();
557 mLegend->endCommand();
561void QgsLayoutLegendWidget::spaceBelowGroupHeadingChanged(
double space )
567 mLegend->adjustBoxSize();
569 mLegend->endCommand();
573void QgsLayoutLegendWidget::spaceGroupSideChanged(
double space )
579 mLegend->adjustBoxSize();
581 mLegend->endCommand();
585void QgsLayoutLegendWidget::spaceSubGroupSideChanged(
double space )
591 mLegend->adjustBoxSize();
593 mLegend->endCommand();
597void QgsLayoutLegendWidget::spaceSymbolSideChanged(
double space )
603 mLegend->adjustBoxSize();
605 mLegend->endCommand();
609void QgsLayoutLegendWidget::mLayerSpaceSpinBox_valueChanged(
double d )
615 mLegend->adjustBoxSize();
617 mLegend->endCommand();
621void QgsLayoutLegendWidget::mSymbolSpaceSpinBox_valueChanged(
double d )
629 mLegend->adjustBoxSize();
631 mLegend->endCommand();
635void QgsLayoutLegendWidget::mIconLabelSpaceSpinBox_valueChanged(
double d )
641 mLegend->adjustBoxSize();
643 mLegend->endCommand();
647void QgsLayoutLegendWidget::titleFontChanged()
653 mLegend->adjustBoxSize();
655 mLegend->endCommand();
659void QgsLayoutLegendWidget::groupFontChanged()
665 mLegend->adjustBoxSize();
667 mLegend->endCommand();
671void QgsLayoutLegendWidget::layerFontChanged()
677 mLegend->adjustBoxSize();
679 mLegend->endCommand();
683void QgsLayoutLegendWidget::itemFontChanged()
689 mLegend->adjustBoxSize();
691 mLegend->endCommand();
695void QgsLayoutLegendWidget::spaceBelowSubGroupHeadingChanged(
double space )
701 mLegend->adjustBoxSize();
703 mLegend->endCommand();
707void QgsLayoutLegendWidget::mBoxSpaceSpinBox_valueChanged(
double d )
712 mLegend->setBoxSpace( d );
713 mLegend->adjustBoxSize();
715 mLegend->endCommand();
719void QgsLayoutLegendWidget::mColumnSpaceSpinBox_valueChanged(
double d )
724 mLegend->setColumnSpace( d );
725 mLegend->adjustBoxSize();
727 mLegend->endCommand();
731static void _moveLegendNode(
QgsLayerTreeLayer *nodeLayer,
int legendNodeIndex,
int offset )
735 if ( legendNodeIndex < 0 || legendNodeIndex >= order.count() )
737 if ( legendNodeIndex + offset < 0 || legendNodeIndex + offset >= order.count() )
740 int id = order.takeAt( legendNodeIndex );
741 order.insert( legendNodeIndex + offset,
id );
747void QgsLayoutLegendWidget::mMoveDownToolButton_clicked()
754 const QModelIndex index = mItemTreeView->selectionModel()->currentIndex();
755 const QModelIndex sourceIndex = mItemTreeView->proxyModel()->mapToSource( index );
756 const QModelIndex parentIndex = sourceIndex.parent();
757 if ( !sourceIndex.isValid() || sourceIndex.row() == mItemTreeView->layerTreeModel()->rowCount( parentIndex ) - 1 )
762 if ( !node && !legendNode )
765 mLegend->beginCommand( tr(
"Moved Legend Item Down" ) );
779 mItemTreeView->setCurrentIndex( mItemTreeView->proxyModel()->mapFromSource( mItemTreeView->layerTreeModel()->index( sourceIndex.row() + 1, 0, parentIndex ) ) );
782 mLegend->endCommand();
785void QgsLayoutLegendWidget::mMoveUpToolButton_clicked()
792 const QModelIndex index = mItemTreeView->selectionModel()->currentIndex();
793 const QModelIndex sourceIndex = mItemTreeView->proxyModel()->mapToSource( index );
794 const QModelIndex parentIndex = sourceIndex.parent();
795 if ( !sourceIndex.isValid() || sourceIndex.row() == 0 )
800 if ( !node && !legendNode )
803 mLegend->beginCommand( tr(
"Move Legend Item Up" ) );
817 mItemTreeView->setCurrentIndex( mItemTreeView->proxyModel()->mapFromSource( mItemTreeView->layerTreeModel()->index( sourceIndex.row() - 1, 0, parentIndex ) ) );
820 mLegend->endCommand();
823void QgsLayoutLegendWidget::expandLegendTree()
825 mItemTreeView -> expandAll();
828void QgsLayoutLegendWidget::collapseLegendTree()
830 mItemTreeView -> collapseAll();
833void QgsLayoutLegendWidget::mCheckBoxAutoUpdate_stateChanged(
int state,
bool userTriggered )
837 mLegend->beginCommand( tr(
"Change Auto Update" ) );
839 mLegend->setAutoUpdateModel( state == Qt::Checked );
841 mLegend->endCommand();
845 QList<QWidget *> widgets;
846 widgets << mMoveDownToolButton << mMoveUpToolButton << mRemoveToolButton << mAddToolButton
847 << mEditPushButton << mCountToolButton << mUpdateAllPushButton << mAddGroupToolButton
848 << mExpressionFilterButton << mCollapseAllToolButton << mExpandAllToolButton;
849 for ( QWidget *w : std::as_const( widgets ) )
850 w->setEnabled( state != Qt::Checked );
852 if ( state == Qt::Unchecked )
855 selectedChanged( QModelIndex(), QModelIndex() );
856 mItemTreeView->proxyModel()->setShowPrivateLayers(
true );
860 mItemTreeView->proxyModel()->setShowPrivateLayers(
false );
864void QgsLayoutLegendWidget::composerMapChanged(
QgsLayoutItem *item )
880 mLegend->beginCommand( tr(
"Change Legend Map" ) );
881 mLegend->setLinkedMap( map );
883 mLegend->endCommand();
885 setLegendMapViewData();
889void QgsLayoutLegendWidget::mCheckboxResizeContents_toggled(
bool checked )
896 mLegend->beginCommand( tr(
"Resize Legend to Contents" ) );
897 mLegend->setResizeToContents( checked );
899 mLegend->adjustBoxSize();
901 mLegend->endCommand();
904void QgsLayoutLegendWidget::mRasterStrokeGroupBox_toggled(
bool state )
911 mLegend->beginCommand( tr(
"Change Legend Borders" ) );
912 mLegend->setDrawRasterStroke( state );
913 mLegend->adjustBoxSize();
915 mLegend->endCommand();
918void QgsLayoutLegendWidget::mRasterStrokeWidthSpinBox_valueChanged(
double d )
926 mLegend->setRasterStrokeWidth( d );
927 mLegend->adjustBoxSize();
929 mLegend->endCommand();
932void QgsLayoutLegendWidget::mRasterStrokeColorButton_colorChanged(
const QColor &newColor )
940 mLegend->setRasterStrokeColor( newColor );
942 mLegend->endCommand();
945void QgsLayoutLegendWidget::mAddToolButton_clicked()
952 QList< QgsMapLayer * > visibleLayers;
953 if ( mLegend->linkedMap() )
955 visibleLayers = mLegend->linkedMap()->layersToRender();
957 if ( visibleLayers.isEmpty() )
960 visibleLayers = mMapCanvas->layers(
true );
964 addDialog.setVisibleLayers( visibleLayers );
965 if ( addDialog.exec() == QDialog::Accepted )
967 const QList<QgsMapLayer *> layers = addDialog.selectedLayers();
968 if ( !layers.empty() )
970 mLegend->beginCommand( tr(
"Add Legend Item(s)" ) );
973 mLegend->model()->rootGroup()->addLayer( layer );
975 mLegend->updateLegend();
977 mLegend->endCommand();
982void QgsLayoutLegendWidget::mRemoveToolButton_clicked()
989 QItemSelectionModel *selectionModel = mItemTreeView->selectionModel();
990 if ( !selectionModel )
995 mLegend->beginCommand( tr(
"Remove Legend Item" ) );
997 QList<QPersistentModelIndex> proxyIndexes;
998 const QModelIndexList viewSelection = selectionModel->selectedIndexes();
999 for (
const QModelIndex &index : viewSelection )
1000 proxyIndexes << index;
1003 QHash<QgsLayerTreeLayer *, QList<int> > nodesWithRemoval;
1004 for (
const QPersistentModelIndex &proxyIndex : std::as_const( proxyIndexes ) )
1009 nodesWithRemoval[nodeLayer].append( _unfilteredLegendNodeIndex( legendNode ) );
1012 for (
auto it = nodesWithRemoval.constBegin(); it != nodesWithRemoval.constEnd(); ++it )
1014 QList<int> toDelete = it.value();
1015 std::sort( toDelete.begin(), toDelete.end(), std::greater<int>() );
1018 for (
int i : std::as_const( toDelete ) )
1020 if ( i >= 0 && i < order.count() )
1021 order.removeAt( i );
1025 mItemTreeView->layerTreeModel()->refreshLayerLegend( it.key() );
1029 for (
const QPersistentModelIndex &proxyIndex : std::as_const( proxyIndexes ) )
1031 if ( proxyIndex.isValid() && mItemTreeView->index2node( proxyIndex ) )
1033 const QModelIndex sourceIndex = mItemTreeView->proxyModel()->mapToSource( proxyIndex );
1034 mLegend->model()->removeRow( sourceIndex.row(), sourceIndex.parent() );
1038 mLegend->updateLegend();
1040 mLegend->endCommand();
1043void QgsLayoutLegendWidget::mEditPushButton_clicked()
1050 QModelIndex idx = mItemTreeView->selectionModel()->currentIndex();
1051 mItemTreeView_doubleClicked( idx );
1054void QgsLayoutLegendWidget::resetLayerNodeToDefaults()
1062 QModelIndex currentIndex = mItemTreeView->currentIndex();
1063 if ( !currentIndex.isValid() )
1082 mLegend->beginCommand( tr(
"Update Legend" ) );
1085 for (
const QString &key : constCustomProperties )
1087 if ( key.startsWith( QLatin1String(
"legend/" ) ) )
1094 mItemTreeView->layerTreeModel()->refreshLayerLegend( nodeLayer );
1096 mLegend->updateLegend();
1098 mLegend->endCommand();
1101void QgsLayoutLegendWidget::mCountToolButton_clicked(
bool checked )
1108 const QList< QModelIndex > selectedIndexes = mItemTreeView->selectionModel()->selectedIndexes();
1109 if ( selectedIndexes.empty() )
1112 mLegend->beginCommand( tr(
"Update Legend" ) );
1113 for (
const QModelIndex &index : selectedIndexes )
1119 currentNode->
setCustomProperty( QStringLiteral(
"showFeatureCount" ), checked ? 1 : 0 );
1121 mLegend->updateFilterByMap();
1122 mLegend->adjustBoxSize();
1123 mLegend->endCommand();
1126void QgsLayoutLegendWidget::mFilterByMapCheckBox_toggled(
bool checked )
1128 mLegend->beginCommand( tr(
"Update Legend" ) );
1129 mLegend->setLegendFilterByMapEnabled( checked );
1130 mLegend->adjustBoxSize();
1132 mLegend->endCommand();
1135void QgsLayoutLegendWidget::mExpressionFilterButton_toggled(
bool checked )
1143 QModelIndex currentIndex = mItemTreeView->currentIndex();
1144 if ( !currentIndex.isValid() )
1154 mExpressionFilterButton->expressionText(),
1157 mLegend->beginCommand( tr(
"Update Legend" ) );
1158 mLegend->updateFilterByMap();
1159 mLegend->adjustBoxSize();
1160 mLegend->endCommand();
1163void QgsLayoutLegendWidget::mLayerExpressionButton_clicked()
1170 QModelIndex currentIndex = mItemTreeView->currentIndex();
1171 if ( !currentIndex.isValid() )
1178 QgsLayerTreeLayer *layerNode = qobject_cast<QgsLayerTreeLayer *>( currentNode );
1184 QString currentExpression;
1186 currentExpression = QStringLiteral(
"@symbol_label" );
1192 QStringList highlighted;
1195 const QList<QgsLayerTreeModelLegendNode *> legendNodes = model->layerLegendNodes( layerNode,
false );
1196 if ( !legendNodes.isEmpty() )
1198 if (
QgsSymbolLegendNode *symbolNode = qobject_cast<QgsSymbolLegendNode *>( legendNodes.first() ) )
1200 legendContext.
appendScope( symbolNode->createSymbolScope() );
1201 highlighted << QStringLiteral(
"symbol_label" ) << QStringLiteral(
"symbol_id" ) << QStringLiteral(
"symbol_count" );
1214 QgsExpressionBuilderDialog expressiondialog(
nullptr, currentExpression,
nullptr, QStringLiteral(
"generic" ), legendContext );
1215 if ( expressiondialog.exec() )
1218 mItemTreeView->layerTreeModel()->refreshLayerLegend( layerNode );
1221 mLegend->beginCommand( tr(
"Update Legend" ) );
1223 mLegend->adjustBoxSize();
1224 mLegend->endCommand();
1227void QgsLayoutLegendWidget::mUpdateAllPushButton_clicked()
1232void QgsLayoutLegendWidget::mAddGroupToolButton_clicked()
1236 mLegend->beginCommand( tr(
"Add Legend Group" ) );
1237 mLegend->model()->rootGroup()->addGroup( tr(
"Group" ) );
1238 mLegend->updateLegend();
1240 mLegend->endCommand();
1244void QgsLayoutLegendWidget::mFilterLegendByAtlasCheckBox_toggled(
bool toggled )
1249 mLegend->setLegendFilterOutAtlas( toggled );
1255void QgsLayoutLegendWidget::updateLegend()
1259 mLegend->beginCommand( tr(
"Update Legend" ) );
1262 mLegend->setAutoUpdateModel(
true );
1263 mLegend->setAutoUpdateModel(
false );
1265 mLegend->endCommand();
1269void QgsLayoutLegendWidget::setReportTypeString(
const QString &
string )
1271 mFilterLegendByAtlasCheckBox->setText( tr(
"Only show items inside current %1 feature" ).arg(
string ) );
1272 mFilterLegendByAtlasCheckBox->setToolTip( tr(
"Filter out legend elements that lie outside the current %1 feature." ).arg(
string ) );
1281bool QgsLayoutLegendWidget::setNewItem(
QgsLayoutItem *item )
1291 mLegend = qobject_cast< QgsLayoutItemLegend * >( item );
1292 mItemPropertiesWidget->setItem( mLegend );
1294 if ( mMapFilteringWidget )
1295 mMapFilteringWidget->setItem( mLegend );
1299 mItemTreeView->setModel( mLegend->model() );
1308void QgsLayoutLegendWidget::blockAllSignals(
bool b )
1310 mTitleLineEdit->blockSignals( b );
1311 mTitleAlignCombo->blockSignals( b );
1312 mItemTreeView->blockSignals( b );
1313 mCheckBoxAutoUpdate->blockSignals( b );
1314 mMapComboBox->blockSignals( b );
1315 mFilterByMapCheckBox->blockSignals( b );
1316 mColumnCountSpinBox->blockSignals( b );
1317 mSplitLayerCheckBox->blockSignals( b );
1318 mEqualColumnWidthCheckBox->blockSignals( b );
1319 mSymbolWidthSpinBox->blockSignals( b );
1320 mSymbolHeightSpinBox->blockSignals( b );
1321 mMaxSymbolSizeSpinBox->blockSignals( b );
1322 mMinSymbolSizeSpinBox->blockSignals( b );
1323 mGroupSpaceSpinBox->blockSignals( b );
1324 mGroupIndentSpinBox->blockSignals( b );
1325 mSubgroupIndentSpinBox->blockSignals( b );
1326 mSpaceBelowGroupHeadingSpinBox->blockSignals( b );
1327 mGroupSideSpinBox->blockSignals( b );
1328 mSpaceBelowSubgroupHeadingSpinBox->blockSignals( b );
1329 mSubgroupSideSpinBox->blockSignals( b );
1330 mLayerSpaceSpinBox->blockSignals( b );
1331 mSymbolSpaceSpinBox->blockSignals( b );
1332 mSymbolSideSpaceSpinBox->blockSignals( b );
1333 mIconLabelSpaceSpinBox->blockSignals( b );
1334 mBoxSpaceSpinBox->blockSignals( b );
1335 mColumnSpaceSpinBox->blockSignals( b );
1336 mRasterStrokeGroupBox->blockSignals( b );
1337 mRasterStrokeColorButton->blockSignals( b );
1338 mRasterStrokeWidthSpinBox->blockSignals( b );
1339 mWmsLegendWidthSpinBox->blockSignals( b );
1340 mWmsLegendHeightSpinBox->blockSignals( b );
1341 mCheckboxResizeContents->blockSignals( b );
1342 mTitleSpaceBottomSpinBox->blockSignals( b );
1343 mFilterLegendByAtlasCheckBox->blockSignals( b );
1344 mTitleFontButton->blockSignals( b );
1345 mGroupFontButton->blockSignals( b );
1346 mLayerFontButton->blockSignals( b );
1347 mItemFontButton->blockSignals( b );
1348 mWrapCharLineEdit->blockSignals( b );
1351void QgsLayoutLegendWidget::selectedChanged(
const QModelIndex ¤t,
const QModelIndex &previous )
1354 Q_UNUSED( previous )
1356 mLayerExpressionButton->setEnabled(
false );
1358 if ( mLegend && mLegend->autoUpdateModel() )
1369 mLayerExpressionButton->setEnabled(
true );
1373 mCountToolButton->setChecked(
false );
1374 mCountToolButton->setEnabled(
false );
1377 mExpressionFilterButton->blockSignals(
true );
1378 mExpressionFilterButton->setChecked(
false );
1379 mExpressionFilterButton->setEnabled(
false );
1380 mExpressionFilterButton->blockSignals(
false );
1391 mCountToolButton->setChecked( currentNode->
customProperty( QStringLiteral(
"showFeatureCount" ), 0 ).toInt() );
1392 mCountToolButton->setEnabled(
true );
1393 mLayerExpressionButton->setEnabled(
true );
1397 mExpressionFilterButton->blockSignals(
true );
1398 mExpressionFilterButton->setExpressionText( expr );
1399 mExpressionFilterButton->setVectorLayer( vl );
1400 mExpressionFilterButton->setEnabled(
true );
1401 mExpressionFilterButton->setChecked( exprEnabled );
1402 mExpressionFilterButton->blockSignals(
false );
1405void QgsLayoutLegendWidget::setCurrentNodeStyleFromAction()
1407 QAction *a = qobject_cast<QAction *>( sender() );
1408 if ( !a || !mItemTreeView->currentNode() )
1415void QgsLayoutLegendWidget::setLegendMapViewData()
1417 if ( mLegend->linkedMap() )
1421 measurementConverter.
setDpi( dpi );
1424 double mapUnitsPerPixelX = mLegend->linkedMap()->extent().width() / mapWidth;
1425 double mapUnitsPerPixelY = mLegend->linkedMap()->extent().height() / mapHeight;
1426 mLegend->model()->setLegendMapViewData( ( mapUnitsPerPixelX > mapUnitsPerPixelY ? mapUnitsPerPixelX : mapUnitsPerPixelY ), dpi, mLegend->linkedMap()->scale() );
1430void QgsLayoutLegendWidget::updateFilterLegendByAtlasButton()
1434 mFilterLegendByAtlasCheckBox->setEnabled( atlas->enabled() && mLegend->layout()->reportContext().layer() && mLegend->layout()->reportContext().layer()->geometryType() ==
Qgis::GeometryType::Polygon );
1438void QgsLayoutLegendWidget::mItemTreeView_doubleClicked(
const QModelIndex &idx )
1440 if ( !mLegend || !idx.isValid() )
1445 if ( mLegend->autoUpdateModel() )
1451 int originalIndex = -1;
1454 originalIndex = _originalLegendNodeIndex( legendNode );
1458 QgsLayoutLegendNodeWidget *widget =
new QgsLayoutLegendNodeWidget( mLegend, currentNode, legendNode, originalIndex );
1459 openPanel( widget );
1467QgsLayoutLegendMenuProvider::QgsLayoutLegendMenuProvider(
QgsLayerTreeView *view, QgsLayoutLegendWidget *w )
1472QMenu *QgsLayoutLegendMenuProvider::createContextMenu()
1474 if ( !mView->currentNode() )
1477 if ( mWidget->legend()->autoUpdateModel() )
1480 QMenu *menu =
new QMenu();
1484 menu->addAction( QObject::tr(
"Reset to Defaults" ), mWidget, &QgsLayoutLegendWidget::resetLayerNodeToDefaults );
1485 menu->addSeparator();
1490 QActionGroup *styleGroup =
new QActionGroup{ mWidget };
1491 styleGroup->setExclusive(
true );
1493 QList<QgsLegendStyle::Style> lst;
1497 QAction *action = menu->addAction(
QgsLegendStyle::styleLabel( style ), mWidget, &QgsLayoutLegendWidget::setCurrentNodeStyleFromAction );
1498 action->setActionGroup( styleGroup );
1499 action->setCheckable(
true );
1500 action->setChecked( currentStyle == style );
1501 action->setData(
static_cast< int >( style ) );
1516 , mOriginalLegendNodeIndex( originalLegendNodeIndex )
1519 setPanelTitle( tr(
"Legend Item Properties" ) );
1528 QString currentLabel;
1531 currentLabel = mLegendNode->data( Qt::EditRole ).toString();
1532 mColumnBreakBeforeCheckBox->setChecked( mLegendNode->columnBreak() );
1536 currentLabel = mLayer->name();
1537 QVariant v = mLayer->customProperty( QStringLiteral(
"legend/title-label" ) );
1539 currentLabel = v.toString();
1540 mColumnBreakBeforeCheckBox->setChecked( mLayer->customProperty( QStringLiteral(
"legend/column-break" ) ).toInt() );
1542 mColumnSplitBehaviorComboBox->setCurrentIndex( mColumnSplitBehaviorComboBox->findData( mLayer->legendSplitBehavior() ) );
1547 mColumnBreakBeforeCheckBox->setChecked( mNode->customProperty( QStringLiteral(
"legend/column-break" ) ).toInt() );
1550 mWidthSpinBox->setClearValue( 0, tr(
"Default" ) );
1551 mHeightSpinBox->setClearValue( 0, tr(
"Default" ) );
1552 mWidthSpinBox->setVisible( mLegendNode || mLayer );
1553 mHeightSpinBox->setVisible( mLegendNode || mLayer );
1554 mPatchGroup->setVisible( mLegendNode || mLayer );
1555 mPatchWidthLabel->setVisible( mLegendNode || mLayer );
1556 mPatchHeightLabel->setVisible( mLegendNode || mLayer );
1557 mCustomSymbolCheckBox->setVisible( mLegendNode || mLegend->model()->legendNodeEmbeddedInParent( mLayer ) );
1558 mColumnSplitLabel->setVisible( mLayer && !mLegendNode );
1559 mColumnSplitBehaviorComboBox->setVisible( mLayer && !mLegendNode );
1562 mWidthSpinBox->setValue( mLegendNode->userPatchSize().width() );
1563 mHeightSpinBox->setValue( mLegendNode->userPatchSize().height() );
1567 mWidthSpinBox->setValue( mLayer->patchSize().width() );
1568 mHeightSpinBox->setValue( mLayer->patchSize().height() );
1571 mCustomSymbolCheckBox->setChecked(
false );
1576 patchShape = symbolLegendNode->patchShape();
1578 std::unique_ptr< QgsSymbol > customSymbol( symbolLegendNode->customSymbol() ? symbolLegendNode->customSymbol()->clone() : nullptr );
1579 mCustomSymbolCheckBox->setChecked( customSymbol.get() );
1582 mPatchShapeButton->setPreviewSymbol( customSymbol->clone() );
1584 mCustomSymbolButton->setSymbol( customSymbol.release() );
1586 else if ( symbolLegendNode->symbol() )
1588 mPatchShapeButton->setPreviewSymbol( symbolLegendNode->symbol()->clone() );
1589 mCustomSymbolButton->setSymbolType( symbolLegendNode->symbol()->type() );
1590 mCustomSymbolButton->setSymbol( symbolLegendNode->symbol()->clone() );
1593 else if ( !mLegendNode && mLayer )
1595 patchShape = mLayer->patchShape();
1598 if (
QgsSymbol *customSymbol = symbolLegendNode->customSymbol() )
1600 mCustomSymbolCheckBox->setChecked(
true );
1601 mPatchShapeButton->setPreviewSymbol( customSymbol->clone() );
1603 mCustomSymbolButton->setSymbol( customSymbol->clone() );
1607 mPatchShapeButton->setPreviewSymbol( symbolLegendNode->symbol()->clone() );
1608 mCustomSymbolButton->setSymbolType( symbolLegendNode->symbol()->type() );
1609 mCustomSymbolButton->setSymbol( symbolLegendNode->symbol()->clone() );
1616 switch ( qobject_cast< QgsVectorLayer * >( mLayer->layer() )->geometryType() )
1631 mPatchShapeLabel->hide();
1632 mPatchShapeButton->hide();
1635 if ( !patchShape.
isNull() )
1636 mPatchShapeButton->setShape( patchShape );
1641 if ( symbolLegendNode->symbol() )
1643 mPatchShapeButton->setSymbolType( symbolLegendNode->symbol()->type() );
1647 mPatchShapeLabel->hide();
1648 mPatchShapeButton->hide();
1653 mPatchShapeLabel->hide();
1654 mPatchShapeButton->hide();
1659 mLabelGroup->hide();
1660 mColorRampLegendWidget->setSettings( colorRampNode->settings() );
1664 mColorRampLegendWidget->hide();
1677 mCustomSymbolCheckBox->hide();
1686 mLabelEdit->setPlainText( currentLabel );
1687 connect( mLabelEdit, &QPlainTextEdit::textChanged,
this, &QgsLayoutLegendNodeWidget::labelChanged );
1689 connect( mInsertExpressionButton, &QPushButton::clicked,
this, &QgsLayoutLegendNodeWidget::insertExpression );
1691 connect( mWidthSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendNodeWidget::sizeChanged );
1692 connect( mHeightSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendNodeWidget::sizeChanged );
1694 connect( mCustomSymbolCheckBox, &QGroupBox::toggled,
this, &QgsLayoutLegendNodeWidget::customSymbolChanged );
1697 connect( mColumnBreakBeforeCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendNodeWidget::columnBreakToggled );
1699 connect( mColumnSplitBehaviorComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsLayoutLegendNodeWidget::columnSplitChanged );
1703 connectChildPanel( mColorRampLegendWidget );
1706void QgsLayoutLegendNodeWidget::setDockMode(
bool dockMode )
1708 mColorRampLegendWidget->setDockMode( dockMode );
1712void QgsLayoutLegendNodeWidget::labelChanged()
1716 const QString label = mLabelEdit->toPlainText();
1721 else if ( mLegendNode )
1724 mLegend->model()->refreshLayerLegend( mLayer );
1728 mLayer->setCustomProperty( QStringLiteral(
"legend/title-label" ), label );
1732 embeddedNode->setUserLabel( QString() );
1735 mLegend->adjustBoxSize();
1736 mLegend->invalidateCache();
1738 mLegend->endCommand();
1741void QgsLayoutLegendNodeWidget::patchChanged()
1743 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1749 mLegend->model()->refreshLayerLegend( mLayer );
1753 mLayer->setPatchShape( shape );
1754 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1759 mLegend->model()->refreshLayerLegend( mLayer );
1762 mLegend->adjustBoxSize();
1764 mLegend->endCommand();
1767void QgsLayoutLegendNodeWidget::insertExpression()
1775 QgsVectorLayer *layer = mLegend->layout() ? mLegend->layout()->reportContext().layer() :
nullptr;
1779 if ( mLayer && mLayer->layer() )
1785 << QStringLiteral(
"legend_column_count" )
1786 << QStringLiteral(
"legend_split_layers" )
1787 << QStringLiteral(
"legend_wrap_string" )
1788 << QStringLiteral(
"legend_filter_by_map" )
1789 << QStringLiteral(
"legend_filter_out_atlas" ) );
1793 exprDlg.setWindowTitle( tr(
"Insert Expression" ) );
1794 if ( exprDlg.exec() == QDialog::Accepted )
1796 expression = exprDlg.expressionText();
1797 if ( !expression.isEmpty() )
1799 mLegend->beginCommand( tr(
"Insert expression" ) );
1800 mLabelEdit->insertPlainText(
"[%" + expression.trimmed() +
"%]" );
1801 mLegend->endCommand();
1806void QgsLayoutLegendNodeWidget::sizeChanged(
double )
1808 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1809 const QSizeF size = QSizeF( mWidthSpinBox->value(), mHeightSpinBox->value() );
1814 mLegend->model()->refreshLayerLegend( mLayer );
1818 mLayer->setPatchSize( size );
1819 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1824 mLegend->model()->refreshLayerLegend( mLayer );
1827 mLegend->adjustBoxSize();
1829 mLegend->endCommand();
1832void QgsLayoutLegendNodeWidget::customSymbolChanged()
1834 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1836 if ( mCustomSymbolCheckBox->isChecked() )
1841 mLegend->model()->refreshLayerLegend( mLayer );
1845 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1850 mLegend->model()->refreshLayerLegend( mLayer );
1858 mLegend->model()->refreshLayerLegend( mLayer );
1862 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1867 mLegend->model()->refreshLayerLegend( mLayer );
1871 mLegend->adjustBoxSize();
1873 mLegend->endCommand();
1876void QgsLayoutLegendNodeWidget::colorRampLegendChanged()
1878 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1882 mLegend->model()->refreshLayerLegend( mLayer );
1884 mLegend->adjustBoxSize();
1886 mLegend->endCommand();
1889void QgsLayoutLegendNodeWidget::columnBreakToggled(
bool checked )
1891 mLegend->beginCommand( tr(
"Edit Legend Columns" ) );
1896 mLegend->model()->refreshLayerLegend( mLayer );
1900 mLayer->setCustomProperty( QStringLiteral(
"legend/column-break" ), QString( checked ?
'1' :
'0' ) );
1904 mNode->setCustomProperty( QStringLiteral(
"legend/column-break" ), QString( checked ?
'1' :
'0' ) );
1907 mLegend->adjustBoxSize();
1909 mLegend->endCommand();
1912void QgsLayoutLegendNodeWidget::columnSplitChanged()
1914 mLegend->beginCommand( tr(
"Edit Legend Columns" ) );
1916 if ( mLayer && !mLegendNode )
1921 mLegend->adjustBoxSize();
1923 mLegend->endCommand();
1930QgsLayoutLegendMapFilteringWidget::QgsLayoutLegendMapFilteringWidget(
QgsLayoutItemLegend *legend )
1932 , mLegendItem( legend )
1935 setPanelTitle( tr(
"Legend Filtering" ) );
1937 setNewItem( legend );
1940bool QgsLayoutLegendMapFilteringWidget::setNewItem(
QgsLayoutItem *item )
1950 mLegendItem = qobject_cast< QgsLayoutItemLegend * >( item );
1957 updateGuiElements();
1962void QgsLayoutLegendMapFilteringWidget::updateGuiElements()
1964 if ( mBlockUpdates )
1967 mBlockUpdates =
true;
1969 if ( mFilterMapItemsListView->model() )
1971 QAbstractItemModel *oldModel = mFilterMapItemsListView->model();
1972 mFilterMapItemsListView->setModel(
nullptr );
1973 oldModel->deleteLater();
1976 QgsLayoutLegendMapFilteringModel *model =
new QgsLayoutLegendMapFilteringModel( mLegendItem, mLegendItem->layout()->itemsModel(), mFilterMapItemsListView );
1977 mFilterMapItemsListView->setModel( model );
1979 mBlockUpdates =
false;
1987 : QSortFilterProxyModel( parent )
1988 , mLayoutModel( layoutModel )
1989 , mLegendItem( legend )
1991 setSourceModel( layoutModel );
1994int QgsLayoutLegendMapFilteringModel::columnCount(
const QModelIndex & )
const
1999QVariant QgsLayoutLegendMapFilteringModel::data(
const QModelIndex &i,
int role )
const
2004 if ( i.column() != 0 )
2009 QgsLayoutItemMap *mapItem = qobject_cast< QgsLayoutItemMap * >( mLayoutModel->itemFromIndex( mapToSource( i ) ) );
2017 case Qt::CheckStateRole:
2018 switch ( i.column() )
2023 return Qt::Unchecked;
2025 return mLegendItem->filterByMapItems().contains( mapItem ) ? Qt::Checked : Qt::Unchecked;
2033 return mLayoutModel->data( sourceIndex, role );
2037bool QgsLayoutLegendMapFilteringModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
2041 if ( !index.isValid() )
2044 QgsLayoutItemMap *mapItem = qobject_cast< QgsLayoutItemMap * >( mLayoutModel->itemFromIndex( mapToSource( index ) ) );
2045 if ( !mapItem || !mLegendItem )
2050 mLegendItem->layout()->undoStack()->beginCommand( mLegendItem, tr(
"Change Legend Linked Maps" ) );
2052 QList< QgsLayoutItemMap * > linkedMaps = mLegendItem->filterByMapItems();
2053 if ( value.toBool() )
2055 if ( !linkedMaps.contains( mapItem ) )
2057 linkedMaps.append( mapItem );
2058 mLegendItem->setFilterByMapItems( linkedMaps );
2063 linkedMaps.removeAll( mapItem );
2064 mLegendItem->setFilterByMapItems( linkedMaps );
2066 emit dataChanged( index, index, QVector<int>() << role );
2068 mLegendItem->layout()->undoStack()->endCommand();
2069 mLegendItem->invalidateCache();
2074Qt::ItemFlags QgsLayoutLegendMapFilteringModel::flags(
const QModelIndex &index )
const
2076 Qt::ItemFlags flags = QSortFilterProxyModel::flags( index );
2078 if ( ! index.isValid() )
2083 QgsLayoutItemMap *mapItem = qobject_cast< QgsLayoutItemMap * >( mLayoutModel->itemFromIndex( mapToSource( index ) ) );
2084 const bool isMainLinkedMapItem = mLegendItem ? ( mLegendItem->linkedMap() == mapItem ) : false;
2090 if ( !isMainLinkedMapItem )
2092 flags |= Qt::ItemIsEnabled;
2096 flags &= ~Qt::ItemIsEnabled;
2099 switch ( index.column() )
2102 if ( !isMainLinkedMapItem )
2103 return flags | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
2105 return flags | Qt::ItemIsSelectable;
2108 return flags | Qt::ItemIsSelectable;
2112bool QgsLayoutLegendMapFilteringModel::filterAcceptsRow(
int source_row,
const QModelIndex &source_parent )
const
2114 QgsLayoutItem *item = mLayoutModel->itemFromIndex( mLayoutModel->index( source_row, 0, source_parent ) );
void changed()
Emitted when the alignment is changed.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
Settings for a color ramp legend node.
A legend node which renders a color ramp.
A generic dialog for building expression strings.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void setFields(const QgsFields &fields)
Convenience function for setting a fields for the scope.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user.
static QString findAndSelectActiveExpression(QgsCodeEditor *editor, const QString &pattern=QString())
Find the expression under the cursor in the given editor and select it.
Container of fields for a vector layer.
Layer tree group node serves as a container for layers and further groups.
void insertChildNode(int index, QgsLayerTreeNode *node)
Insert existing node at specified position.
void setName(const QString &n) override
Sets the group's name.
void removeChildNode(QgsLayerTreeNode *node)
Remove a child node from this group.
QString name() const override
Returns the group's name.
Layer tree node points to a map layer.
void setPatchSize(QSizeF size)
Sets the user (overridden) size for the legend node.
QString labelExpression() const
Returns the expression member of the LayerTreeNode.
LegendNodesSplitBehavior
Legend node column split behavior.
@ AllowSplittingLegendNodesOverMultipleColumns
Allow splitting node's legend nodes across multiple columns.
@ PreventSplittingLegendNodesOverMultipleColumns
Prevent splitting node's legend nodes across multiple columns.
@ UseDefaultLegendSetting
Inherit default legend column splitting setting.
void setLabelExpression(const QString &expression)
set the expression to evaluate
void setPatchShape(const QgsLegendPatchShape &shape)
Sets the symbol patch shape to use when rendering the legend node symbol.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
The QgsLegendRendererItem class is abstract interface for legend items returned from QgsMapLayerLegen...
NodeTypes
Types of legend nodes.
@ SimpleLegend
Simple label with icon legend node type.
@ RasterSymbolLegend
Raster symbol legend node type.
@ ImageLegend
Raster image legend node type.
@ DataDefinedSizeLegend
Marker symbol legend node type.
@ WmsLegend
WMS legend node type.
@ EmbeddedWidget
Embedded widget placeholder node type.
@ ColorRampLegend
Color ramp legend.
@ SymbolLegend
Vector symbol legend node type.
@ NodeType
Type of node. Added in 3.16.
QgsLayerTreeModel * model() const
Returns pointer to model owning this legend node.
QgsLayerTreeLayer * layerNode() const
Returns pointer to the parent layer node.
QgsLayerTreeModelLegendNode * legendNodeEmbeddedInParent(QgsLayerTreeLayer *nodeLayer) const
Returns legend node that may be embedded in parent (i.e.
QList< QgsLayerTreeModelLegendNode * > layerOriginalLegendNodes(QgsLayerTreeLayer *nodeLayer)
Returns original (unfiltered) list of legend nodes attached to a particular layer node.
This class is a base class for nodes in a layer tree.
void setCustomProperty(const QString &key, const QVariant &value)
Sets a custom property for the node. Properties are stored in a map and saved in project file.
void removeCustomProperty(const QString &key)
Remove a custom property from layer. Properties are stored in a map and saved in project file.
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer. Properties are stored in a map and saved in project file.
QgsLayerTreeNode * parent()
Gets pointer to the parent. If parent is nullptr, the node is a root node.
QStringList customProperties() const
Returns list of keys stored in custom properties.
virtual QgsLayerTreeNode * clone() const =0
Create a copy of the node. Returns new instance.
static void setLegendFilterByExpression(QgsLayerTreeLayer &layer, const QString &expr, bool enabled=true)
Sets the expression filter of a legend layer.
static QString legendFilterByExpression(const QgsLayerTreeLayer &layer, bool *enabled=nullptr)
Returns the expression filter of a legend layer.
The QgsLayerTreeView class extends QTreeView and provides some additional functionality when working ...
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
static bool isLayer(const QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
static bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
static QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group.
Class used to render QgsLayout as an atlas, by iterating over the features from an associated vector ...
void toggled(bool enabled)
Emitted when atlas is enabled or disabled.
A common interface for layout designer dialogs and widgets.
virtual QgsMessageBar * messageBar()=0
Returns the designer's message bar.
void itemChanged(QgsLayoutItem *item)
Emitted whenever the currently selected item changes.
A layout item subclass for map legends.
QgsLegendModel * model()
Returns the legend model.
Layout graphical items for displaying a map.
@ LayoutLegend
Legend item.
Base class for graphical items within a QgsLayout.
@ UndoLegendMinSymbolSize
Legend minimum symbol size.
@ UndoLegendTitleSpaceBottom
Legend title space.
@ UndoLegendIconSymbolSpace
Legend icon symbol space.
@ UndoLegendLayerFont
Legend layer font.
@ UndoLegendBoxSpace
Legend box space.
@ UndoLegendRasterStrokeColor
Legend raster stroke color.
@ UndoLegendTitleFont
Legend title font.
@ UndoLegendItemFont
Legend item font.
@ UndoLegendWmsLegendWidth
Legend WMS width.
@ UndoLegendLayerSpace
Legend layer spacing.
@ UndoLegendColumnSpace
Legend column space.
@ UndoLegendMaxSymbolSize
Legend maximum symbol size.
@ UndoLegendSymbolSpace
Legend symbol spacing.
@ UndoLegendSymbolWidth
Legend symbol width.
@ UndoLegendColumnCount
Legend column count.
@ UndoLegendSymbolHeight
Legend symbol height.
@ UndoLegendGroupSpace
Legend group spacing.
@ UndoLegendSubgroupIndent
Legend subgroup indent.
@ UndoLegendRasterStrokeWidth
Legend raster stroke width.
@ UndoLegendGroupIndent
Legend group indent.
@ UndoLegendText
Legend text.
@ UndoLegendWmsLegendHeight
Legend WMS height.
@ UndoLegendGroupFont
Legend group font.
int type() const override
Returns a unique graphics item type identifier.
A dialog to add new layers to the legend.
This class provides a method of converting QgsLayoutMeasurements from one unit to another.
QgsLayoutMeasurement convert(QgsLayoutMeasurement measurement, Qgis::LayoutUnit targetUnits) const
Converts a measurement from one unit to another.
void setDpi(const double dpi)
Sets the dots per inch (dpi) for the measurement converter.
A model for items attached to a layout.
const QgsLayout * layout() const
Returns the layout the object is attached to.
void changed()
Emitted when the object's properties change.
@ LegendTitle
Legend title.
@ LegendColumnCount
Legend column count.
void layerChanged(QgsVectorLayer *layer)
Emitted when the context's layer is changed.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
QgsLayoutReportContext & reportContext()
Returns a reference to the layout's report context, which stores information relating to the current ...
Item model implementation based on layer tree model for layout legend.
Represents a patch shape for use in map legends.
void setSymbolType(Qgis::SymbolType type)
Sets the symbol type associated with this patch.
bool isNull() const
Returns true if the patch shape is a null QgsLegendPatchShape, which indicates that the default legen...
static void setNodeLegendStyle(QgsLayerTreeNode *node, QgsLegendStyle::Style style)
Sets the style of a node.
static QgsLegendStyle::Style nodeLegendStyle(QgsLayerTreeNode *node, QgsLayerTreeModel *model)
Returns the style for the given node, within the specified model.
static QString styleLabel(Style s)
Returns a translated string representing a style component, for use in UI.
Style
Component of legends which can be styled.
@ Group
Legend group title.
@ Symbol
Symbol icon (excluding label)
@ Subgroup
Legend subgroup title.
@ Hidden
Special style, item is hidden including margins around.
@ SymbolLabel
Symbol label (excluding icon)
Map canvas is a class for displaying all GIS data types on a canvas.
static void setLegendNodeOrder(QgsLayerTreeLayer *nodeLayer, const QList< int > &order)
static void setLegendNodeColorRampSettings(QgsLayerTreeLayer *nodeLayer, int originalIndex, const QgsColorRampLegendNodeSettings *settings)
Sets a custom legend color ramp settings for the legend node belonging to nodeLayer at the specified ...
static void setLegendNodeCustomSymbol(QgsLayerTreeLayer *nodeLayer, int originalIndex, const QgsSymbol *symbol)
Sets a custom legend symbol for the legend node belonging to nodeLayer at the specified originalIndex...
static void setLegendNodeUserLabel(QgsLayerTreeLayer *nodeLayer, int originalIndex, const QString &newLabel)
static void setLegendNodeSymbolSize(QgsLayerTreeLayer *nodeLayer, int originalIndex, QSizeF size)
Sets the legend symbol size for the legend node belonging to nodeLayer at the specified originalIndex...
static void setLegendNodeColumnBreak(QgsLayerTreeLayer *nodeLayer, int originalIndex, bool columnBreakBeforeNode)
Sets whether a forced column break should occur before the node.
static void setLegendNodePatchShape(QgsLayerTreeLayer *nodeLayer, int originalIndex, const QgsLegendPatchShape &shape)
Sets the legend patch shape for the legend node belonging to nodeLayer at the specified originalIndex...
static QList< int > legendNodeOrder(QgsLayerTreeLayer *nodeLayer)
Base class for all map layer types.
Interface for master layout type objects, such as print layouts and reports.
static int qtDefaultDpiX()
Returns the default Qt horizontal DPI.
Implementation of legend node interface for displaying preview of vector symbols and their labels and...
Abstract base class for all rendered symbols.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
Represents a vector layer which manages a vector based data sets.
QgsExpressionContextScope * createExpressionContextScope() const FINAL
This method needs to be reimplemented in all classes which implement this interface and return an exp...
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
QgsLayerTreeModelLegendNode * legendNode(const QString &rule, QgsLayerTreeModel &model)
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.