49#include <QInputDialog>
50#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() );
859void QgsLayoutLegendWidget::composerMapChanged(
QgsLayoutItem *item )
875 mLegend->beginCommand( tr(
"Change Legend Map" ) );
876 mLegend->setLinkedMap( map );
878 mLegend->endCommand();
880 setLegendMapViewData();
884void QgsLayoutLegendWidget::mCheckboxResizeContents_toggled(
bool checked )
891 mLegend->beginCommand( tr(
"Resize Legend to Contents" ) );
892 mLegend->setResizeToContents( checked );
894 mLegend->adjustBoxSize();
896 mLegend->endCommand();
899void QgsLayoutLegendWidget::mRasterStrokeGroupBox_toggled(
bool state )
906 mLegend->beginCommand( tr(
"Change Legend Borders" ) );
907 mLegend->setDrawRasterStroke( state );
908 mLegend->adjustBoxSize();
910 mLegend->endCommand();
913void QgsLayoutLegendWidget::mRasterStrokeWidthSpinBox_valueChanged(
double d )
921 mLegend->setRasterStrokeWidth( d );
922 mLegend->adjustBoxSize();
924 mLegend->endCommand();
927void QgsLayoutLegendWidget::mRasterStrokeColorButton_colorChanged(
const QColor &newColor )
935 mLegend->setRasterStrokeColor( newColor );
937 mLegend->endCommand();
940void QgsLayoutLegendWidget::mAddToolButton_clicked()
947 QList< QgsMapLayer * > visibleLayers;
948 if ( mLegend->linkedMap() )
950 visibleLayers = mLegend->linkedMap()->layersToRender();
952 if ( visibleLayers.isEmpty() )
955 visibleLayers = mMapCanvas->layers(
true );
959 addDialog.setVisibleLayers( visibleLayers );
960 if ( addDialog.exec() == QDialog::Accepted )
962 const QList<QgsMapLayer *> layers = addDialog.selectedLayers();
963 if ( !layers.empty() )
965 mLegend->beginCommand( tr(
"Add Legend Item(s)" ) );
968 mLegend->model()->rootGroup()->addLayer( layer );
970 mLegend->updateLegend();
972 mLegend->endCommand();
977void QgsLayoutLegendWidget::mRemoveToolButton_clicked()
984 QItemSelectionModel *selectionModel = mItemTreeView->selectionModel();
985 if ( !selectionModel )
990 mLegend->beginCommand( tr(
"Remove Legend Item" ) );
992 QList<QPersistentModelIndex> proxyIndexes;
993 const QModelIndexList viewSelection = selectionModel->selectedIndexes();
994 for (
const QModelIndex &index : viewSelection )
995 proxyIndexes << index;
998 QHash<QgsLayerTreeLayer *, QList<int> > nodesWithRemoval;
999 for (
const QPersistentModelIndex &proxyIndex : std::as_const( proxyIndexes ) )
1004 nodesWithRemoval[nodeLayer].append( _unfilteredLegendNodeIndex( legendNode ) );
1007 for (
auto it = nodesWithRemoval.constBegin(); it != nodesWithRemoval.constEnd(); ++it )
1009 QList<int> toDelete = it.value();
1010 std::sort( toDelete.begin(), toDelete.end(), std::greater<int>() );
1013 for (
int i : std::as_const( toDelete ) )
1015 if ( i >= 0 && i < order.count() )
1016 order.removeAt( i );
1020 mItemTreeView->layerTreeModel()->refreshLayerLegend( it.key() );
1024 for (
const QPersistentModelIndex &proxyIndex : std::as_const( proxyIndexes ) )
1026 if ( proxyIndex.isValid() && mItemTreeView->index2node( proxyIndex ) )
1028 const QModelIndex sourceIndex = mItemTreeView->proxyModel()->mapToSource( proxyIndex );
1029 mLegend->model()->removeRow( sourceIndex.row(), sourceIndex.parent() );
1033 mLegend->updateLegend();
1035 mLegend->endCommand();
1038void QgsLayoutLegendWidget::mEditPushButton_clicked()
1045 QModelIndex idx = mItemTreeView->selectionModel()->currentIndex();
1046 mItemTreeView_doubleClicked( idx );
1049void QgsLayoutLegendWidget::resetLayerNodeToDefaults()
1057 QModelIndex currentIndex = mItemTreeView->currentIndex();
1058 if ( !currentIndex.isValid() )
1077 mLegend->beginCommand( tr(
"Update Legend" ) );
1080 for (
const QString &key : constCustomProperties )
1082 if ( key.startsWith( QLatin1String(
"legend/" ) ) )
1089 mItemTreeView->layerTreeModel()->refreshLayerLegend( nodeLayer );
1091 mLegend->updateLegend();
1093 mLegend->endCommand();
1096void QgsLayoutLegendWidget::mCountToolButton_clicked(
bool checked )
1103 const QList< QModelIndex > selectedIndexes = mItemTreeView->selectionModel()->selectedIndexes();
1104 if ( selectedIndexes.empty() )
1107 mLegend->beginCommand( tr(
"Update Legend" ) );
1108 for (
const QModelIndex &index : selectedIndexes )
1114 currentNode->
setCustomProperty( QStringLiteral(
"showFeatureCount" ), checked ? 1 : 0 );
1116 mLegend->updateFilterByMap();
1117 mLegend->adjustBoxSize();
1118 mLegend->endCommand();
1121void QgsLayoutLegendWidget::mFilterByMapCheckBox_toggled(
bool checked )
1123 mLegend->beginCommand( tr(
"Update Legend" ) );
1124 mLegend->setLegendFilterByMapEnabled( checked );
1125 mLegend->adjustBoxSize();
1127 mLegend->endCommand();
1130void QgsLayoutLegendWidget::mExpressionFilterButton_toggled(
bool checked )
1138 QModelIndex currentIndex = mItemTreeView->currentIndex();
1139 if ( !currentIndex.isValid() )
1149 mExpressionFilterButton->expressionText(),
1152 mLegend->beginCommand( tr(
"Update Legend" ) );
1153 mLegend->updateFilterByMap();
1154 mLegend->adjustBoxSize();
1155 mLegend->endCommand();
1158void QgsLayoutLegendWidget::mLayerExpressionButton_clicked()
1165 QModelIndex currentIndex = mItemTreeView->currentIndex();
1166 if ( !currentIndex.isValid() )
1173 QgsLayerTreeLayer *layerNode = qobject_cast<QgsLayerTreeLayer *>( currentNode );
1179 QString currentExpression;
1181 currentExpression = QStringLiteral(
"@symbol_label" );
1187 QStringList highlighted;
1190 const QList<QgsLayerTreeModelLegendNode *> legendNodes = model->layerLegendNodes( layerNode,
false );
1191 if ( !legendNodes.isEmpty() )
1193 if (
QgsSymbolLegendNode *symbolNode = qobject_cast<QgsSymbolLegendNode *>( legendNodes.first() ) )
1195 legendContext.
appendScope( symbolNode->createSymbolScope() );
1196 highlighted << QStringLiteral(
"symbol_label" ) << QStringLiteral(
"symbol_id" ) << QStringLiteral(
"symbol_count" );
1209 QgsExpressionBuilderDialog expressiondialog(
nullptr, currentExpression,
nullptr, QStringLiteral(
"generic" ), legendContext );
1210 if ( expressiondialog.exec() )
1213 mItemTreeView->layerTreeModel()->refreshLayerLegend( layerNode );
1216 mLegend->beginCommand( tr(
"Update Legend" ) );
1218 mLegend->adjustBoxSize();
1219 mLegend->endCommand();
1222void QgsLayoutLegendWidget::mUpdateAllPushButton_clicked()
1227void QgsLayoutLegendWidget::mAddGroupToolButton_clicked()
1231 mLegend->beginCommand( tr(
"Add Legend Group" ) );
1232 mLegend->model()->rootGroup()->addGroup( tr(
"Group" ) );
1233 mLegend->updateLegend();
1235 mLegend->endCommand();
1239void QgsLayoutLegendWidget::mFilterLegendByAtlasCheckBox_toggled(
bool toggled )
1244 mLegend->setLegendFilterOutAtlas( toggled );
1250void QgsLayoutLegendWidget::updateLegend()
1254 mLegend->beginCommand( tr(
"Update Legend" ) );
1257 mLegend->setAutoUpdateModel(
true );
1258 mLegend->setAutoUpdateModel(
false );
1260 mLegend->endCommand();
1264void QgsLayoutLegendWidget::setReportTypeString(
const QString &
string )
1266 mFilterLegendByAtlasCheckBox->setText( tr(
"Only show items inside current %1 feature" ).arg(
string ) );
1267 mFilterLegendByAtlasCheckBox->setToolTip( tr(
"Filter out legend elements that lie outside the current %1 feature." ).arg(
string ) );
1276bool QgsLayoutLegendWidget::setNewItem(
QgsLayoutItem *item )
1286 mLegend = qobject_cast< QgsLayoutItemLegend * >( item );
1287 mItemPropertiesWidget->setItem( mLegend );
1289 if ( mMapFilteringWidget )
1290 mMapFilteringWidget->setItem( mLegend );
1294 mItemTreeView->setModel( mLegend->model() );
1303void QgsLayoutLegendWidget::blockAllSignals(
bool b )
1305 mTitleLineEdit->blockSignals( b );
1306 mTitleAlignCombo->blockSignals( b );
1307 mItemTreeView->blockSignals( b );
1308 mCheckBoxAutoUpdate->blockSignals( b );
1309 mMapComboBox->blockSignals( b );
1310 mFilterByMapCheckBox->blockSignals( b );
1311 mColumnCountSpinBox->blockSignals( b );
1312 mSplitLayerCheckBox->blockSignals( b );
1313 mEqualColumnWidthCheckBox->blockSignals( b );
1314 mSymbolWidthSpinBox->blockSignals( b );
1315 mSymbolHeightSpinBox->blockSignals( b );
1316 mMaxSymbolSizeSpinBox->blockSignals( b );
1317 mMinSymbolSizeSpinBox->blockSignals( b );
1318 mGroupSpaceSpinBox->blockSignals( b );
1319 mGroupIndentSpinBox->blockSignals( b );
1320 mSubgroupIndentSpinBox->blockSignals( b );
1321 mSpaceBelowGroupHeadingSpinBox->blockSignals( b );
1322 mGroupSideSpinBox->blockSignals( b );
1323 mSpaceBelowSubgroupHeadingSpinBox->blockSignals( b );
1324 mSubgroupSideSpinBox->blockSignals( b );
1325 mLayerSpaceSpinBox->blockSignals( b );
1326 mSymbolSpaceSpinBox->blockSignals( b );
1327 mSymbolSideSpaceSpinBox->blockSignals( b );
1328 mIconLabelSpaceSpinBox->blockSignals( b );
1329 mBoxSpaceSpinBox->blockSignals( b );
1330 mColumnSpaceSpinBox->blockSignals( b );
1331 mRasterStrokeGroupBox->blockSignals( b );
1332 mRasterStrokeColorButton->blockSignals( b );
1333 mRasterStrokeWidthSpinBox->blockSignals( b );
1334 mWmsLegendWidthSpinBox->blockSignals( b );
1335 mWmsLegendHeightSpinBox->blockSignals( b );
1336 mCheckboxResizeContents->blockSignals( b );
1337 mTitleSpaceBottomSpinBox->blockSignals( b );
1338 mFilterLegendByAtlasCheckBox->blockSignals( b );
1339 mTitleFontButton->blockSignals( b );
1340 mGroupFontButton->blockSignals( b );
1341 mLayerFontButton->blockSignals( b );
1342 mItemFontButton->blockSignals( b );
1343 mWrapCharLineEdit->blockSignals( b );
1346void QgsLayoutLegendWidget::selectedChanged(
const QModelIndex ¤t,
const QModelIndex &previous )
1349 Q_UNUSED( previous )
1351 mLayerExpressionButton->setEnabled(
false );
1353 if ( mLegend && mLegend->autoUpdateModel() )
1364 mLayerExpressionButton->setEnabled(
true );
1368 mCountToolButton->setChecked(
false );
1369 mCountToolButton->setEnabled(
false );
1372 mExpressionFilterButton->blockSignals(
true );
1373 mExpressionFilterButton->setChecked(
false );
1374 mExpressionFilterButton->setEnabled(
false );
1375 mExpressionFilterButton->blockSignals(
false );
1386 mCountToolButton->setChecked( currentNode->
customProperty( QStringLiteral(
"showFeatureCount" ), 0 ).toInt() );
1387 mCountToolButton->setEnabled(
true );
1388 mLayerExpressionButton->setEnabled(
true );
1392 mExpressionFilterButton->blockSignals(
true );
1393 mExpressionFilterButton->setExpressionText( expr );
1394 mExpressionFilterButton->setVectorLayer( vl );
1395 mExpressionFilterButton->setEnabled(
true );
1396 mExpressionFilterButton->setChecked( exprEnabled );
1397 mExpressionFilterButton->blockSignals(
false );
1400void QgsLayoutLegendWidget::setCurrentNodeStyleFromAction()
1402 QAction *a = qobject_cast<QAction *>( sender() );
1403 if ( !a || !mItemTreeView->currentNode() )
1410void QgsLayoutLegendWidget::setLegendMapViewData()
1412 if ( mLegend->linkedMap() )
1416 measurementConverter.
setDpi( dpi );
1419 double mapUnitsPerPixelX = mLegend->linkedMap()->extent().width() / mapWidth;
1420 double mapUnitsPerPixelY = mLegend->linkedMap()->extent().height() / mapHeight;
1421 mLegend->model()->setLegendMapViewData( ( mapUnitsPerPixelX > mapUnitsPerPixelY ? mapUnitsPerPixelX : mapUnitsPerPixelY ), dpi, mLegend->linkedMap()->scale() );
1425void QgsLayoutLegendWidget::updateFilterLegendByAtlasButton()
1429 mFilterLegendByAtlasCheckBox->setEnabled( atlas->enabled() && mLegend->layout()->reportContext().layer() && mLegend->layout()->reportContext().layer()->geometryType() ==
Qgis::GeometryType::Polygon );
1433void QgsLayoutLegendWidget::mItemTreeView_doubleClicked(
const QModelIndex &idx )
1435 if ( !mLegend || !idx.isValid() )
1440 if ( mLegend->autoUpdateModel() )
1446 int originalIndex = -1;
1449 originalIndex = _originalLegendNodeIndex( legendNode );
1453 QgsLayoutLegendNodeWidget *widget =
new QgsLayoutLegendNodeWidget( mLegend, currentNode, legendNode, originalIndex );
1454 openPanel( widget );
1462QgsLayoutLegendMenuProvider::QgsLayoutLegendMenuProvider(
QgsLayerTreeView *view, QgsLayoutLegendWidget *w )
1467QMenu *QgsLayoutLegendMenuProvider::createContextMenu()
1469 if ( !mView->currentNode() )
1472 if ( mWidget->legend()->autoUpdateModel() )
1475 QMenu *menu =
new QMenu();
1479 menu->addAction( QObject::tr(
"Reset to Defaults" ), mWidget, &QgsLayoutLegendWidget::resetLayerNodeToDefaults );
1480 menu->addSeparator();
1485 QActionGroup *styleGroup =
new QActionGroup{ mWidget };
1486 styleGroup->setExclusive(
true );
1488 QList<QgsLegendStyle::Style> lst;
1492 QAction *action = menu->addAction(
QgsLegendStyle::styleLabel( style ), mWidget, &QgsLayoutLegendWidget::setCurrentNodeStyleFromAction );
1493 action->setActionGroup( styleGroup );
1494 action->setCheckable(
true );
1495 action->setChecked( currentStyle == style );
1496 action->setData(
static_cast< int >( style ) );
1511 , mOriginalLegendNodeIndex( originalLegendNodeIndex )
1514 setPanelTitle( tr(
"Legend Item Properties" ) );
1523 QString currentLabel;
1526 currentLabel = mLegendNode->data( Qt::EditRole ).toString();
1527 mColumnBreakBeforeCheckBox->setChecked( mLegendNode->columnBreak() );
1531 currentLabel = mLayer->name();
1532 QVariant v = mLayer->customProperty( QStringLiteral(
"legend/title-label" ) );
1534 currentLabel = v.toString();
1535 mColumnBreakBeforeCheckBox->setChecked( mLayer->customProperty( QStringLiteral(
"legend/column-break" ) ).toInt() );
1537 mColumnSplitBehaviorComboBox->setCurrentIndex( mColumnSplitBehaviorComboBox->findData( mLayer->legendSplitBehavior() ) );
1542 mColumnBreakBeforeCheckBox->setChecked( mNode->customProperty( QStringLiteral(
"legend/column-break" ) ).toInt() );
1545 mWidthSpinBox->setClearValue( 0, tr(
"Default" ) );
1546 mHeightSpinBox->setClearValue( 0, tr(
"Default" ) );
1547 mWidthSpinBox->setVisible( mLegendNode || mLayer );
1548 mHeightSpinBox->setVisible( mLegendNode || mLayer );
1549 mPatchGroup->setVisible( mLegendNode || mLayer );
1550 mPatchWidthLabel->setVisible( mLegendNode || mLayer );
1551 mPatchHeightLabel->setVisible( mLegendNode || mLayer );
1552 mCustomSymbolCheckBox->setVisible( mLegendNode || mLegend->model()->legendNodeEmbeddedInParent( mLayer ) );
1553 mColumnSplitLabel->setVisible( mLayer && !mLegendNode );
1554 mColumnSplitBehaviorComboBox->setVisible( mLayer && !mLegendNode );
1557 mWidthSpinBox->setValue( mLegendNode->userPatchSize().width() );
1558 mHeightSpinBox->setValue( mLegendNode->userPatchSize().height() );
1562 mWidthSpinBox->setValue( mLayer->patchSize().width() );
1563 mHeightSpinBox->setValue( mLayer->patchSize().height() );
1566 mCustomSymbolCheckBox->setChecked(
false );
1571 patchShape = symbolLegendNode->patchShape();
1573 std::unique_ptr< QgsSymbol > customSymbol( symbolLegendNode->customSymbol() ? symbolLegendNode->customSymbol()->clone() : nullptr );
1574 mCustomSymbolCheckBox->setChecked( customSymbol.get() );
1577 mPatchShapeButton->setPreviewSymbol( customSymbol->clone() );
1579 mCustomSymbolButton->setSymbol( customSymbol.release() );
1581 else if ( symbolLegendNode->symbol() )
1583 mPatchShapeButton->setPreviewSymbol( symbolLegendNode->symbol()->clone() );
1584 mCustomSymbolButton->setSymbolType( symbolLegendNode->symbol()->type() );
1585 mCustomSymbolButton->setSymbol( symbolLegendNode->symbol()->clone() );
1588 else if ( !mLegendNode && mLayer )
1590 patchShape = mLayer->patchShape();
1593 if (
QgsSymbol *customSymbol = symbolLegendNode->customSymbol() )
1595 mCustomSymbolCheckBox->setChecked(
true );
1596 mPatchShapeButton->setPreviewSymbol( customSymbol->clone() );
1598 mCustomSymbolButton->setSymbol( customSymbol->clone() );
1602 mPatchShapeButton->setPreviewSymbol( symbolLegendNode->symbol()->clone() );
1603 mCustomSymbolButton->setSymbolType( symbolLegendNode->symbol()->type() );
1604 mCustomSymbolButton->setSymbol( symbolLegendNode->symbol()->clone() );
1611 switch ( qobject_cast< QgsVectorLayer * >( mLayer->layer() )->geometryType() )
1626 mPatchShapeLabel->hide();
1627 mPatchShapeButton->hide();
1630 if ( !patchShape.
isNull() )
1631 mPatchShapeButton->setShape( patchShape );
1636 if ( symbolLegendNode->symbol() )
1638 mPatchShapeButton->setSymbolType( symbolLegendNode->symbol()->type() );
1642 mPatchShapeLabel->hide();
1643 mPatchShapeButton->hide();
1648 mPatchShapeLabel->hide();
1649 mPatchShapeButton->hide();
1654 mLabelGroup->hide();
1655 mColorRampLegendWidget->setSettings( colorRampNode->settings() );
1659 mColorRampLegendWidget->hide();
1672 mCustomSymbolCheckBox->hide();
1681 mLabelEdit->setPlainText( currentLabel );
1682 connect( mLabelEdit, &QPlainTextEdit::textChanged,
this, &QgsLayoutLegendNodeWidget::labelChanged );
1684 connect( mInsertExpressionButton, &QPushButton::clicked,
this, &QgsLayoutLegendNodeWidget::insertExpression );
1686 connect( mWidthSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendNodeWidget::sizeChanged );
1687 connect( mHeightSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendNodeWidget::sizeChanged );
1689 connect( mCustomSymbolCheckBox, &QGroupBox::toggled,
this, &QgsLayoutLegendNodeWidget::customSymbolChanged );
1692 connect( mColumnBreakBeforeCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendNodeWidget::columnBreakToggled );
1694 connect( mColumnSplitBehaviorComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsLayoutLegendNodeWidget::columnSplitChanged );
1698 connectChildPanel( mColorRampLegendWidget );
1701void QgsLayoutLegendNodeWidget::setDockMode(
bool dockMode )
1703 mColorRampLegendWidget->setDockMode( dockMode );
1707void QgsLayoutLegendNodeWidget::labelChanged()
1711 const QString label = mLabelEdit->toPlainText();
1716 else if ( mLegendNode )
1719 mLegend->model()->refreshLayerLegend( mLayer );
1723 mLayer->setCustomProperty( QStringLiteral(
"legend/title-label" ), label );
1727 embeddedNode->setUserLabel( QString() );
1730 mLegend->adjustBoxSize();
1731 mLegend->invalidateCache();
1733 mLegend->endCommand();
1736void QgsLayoutLegendNodeWidget::patchChanged()
1738 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1744 mLegend->model()->refreshLayerLegend( mLayer );
1748 mLayer->setPatchShape( shape );
1749 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1754 mLegend->model()->refreshLayerLegend( mLayer );
1757 mLegend->adjustBoxSize();
1759 mLegend->endCommand();
1762void QgsLayoutLegendNodeWidget::insertExpression()
1770 QgsVectorLayer *layer = mLegend->layout() ? mLegend->layout()->reportContext().layer() :
nullptr;
1774 if ( mLayer && mLayer->layer() )
1780 << QStringLiteral(
"legend_column_count" )
1781 << QStringLiteral(
"legend_split_layers" )
1782 << QStringLiteral(
"legend_wrap_string" )
1783 << QStringLiteral(
"legend_filter_by_map" )
1784 << QStringLiteral(
"legend_filter_out_atlas" ) );
1788 exprDlg.setWindowTitle( tr(
"Insert Expression" ) );
1789 if ( exprDlg.exec() == QDialog::Accepted )
1791 expression = exprDlg.expressionText();
1792 if ( !expression.isEmpty() )
1794 mLegend->beginCommand( tr(
"Insert expression" ) );
1795 mLabelEdit->insertPlainText(
"[%" + expression.trimmed() +
"%]" );
1796 mLegend->endCommand();
1801void QgsLayoutLegendNodeWidget::sizeChanged(
double )
1803 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1804 const QSizeF size = QSizeF( mWidthSpinBox->value(), mHeightSpinBox->value() );
1809 mLegend->model()->refreshLayerLegend( mLayer );
1813 mLayer->setPatchSize( size );
1814 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1819 mLegend->model()->refreshLayerLegend( mLayer );
1822 mLegend->adjustBoxSize();
1824 mLegend->endCommand();
1827void QgsLayoutLegendNodeWidget::customSymbolChanged()
1829 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1831 if ( mCustomSymbolCheckBox->isChecked() )
1836 mLegend->model()->refreshLayerLegend( mLayer );
1840 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1845 mLegend->model()->refreshLayerLegend( mLayer );
1853 mLegend->model()->refreshLayerLegend( mLayer );
1857 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1862 mLegend->model()->refreshLayerLegend( mLayer );
1866 mLegend->adjustBoxSize();
1868 mLegend->endCommand();
1871void QgsLayoutLegendNodeWidget::colorRampLegendChanged()
1873 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1877 mLegend->model()->refreshLayerLegend( mLayer );
1879 mLegend->adjustBoxSize();
1881 mLegend->endCommand();
1884void QgsLayoutLegendNodeWidget::columnBreakToggled(
bool checked )
1886 mLegend->beginCommand( tr(
"Edit Legend Columns" ) );
1891 mLegend->model()->refreshLayerLegend( mLayer );
1895 mLayer->setCustomProperty( QStringLiteral(
"legend/column-break" ), QString( checked ?
'1' :
'0' ) );
1899 mNode->setCustomProperty( QStringLiteral(
"legend/column-break" ), QString( checked ?
'1' :
'0' ) );
1902 mLegend->adjustBoxSize();
1904 mLegend->endCommand();
1907void QgsLayoutLegendNodeWidget::columnSplitChanged()
1909 mLegend->beginCommand( tr(
"Edit Legend Columns" ) );
1911 if ( mLayer && !mLegendNode )
1916 mLegend->adjustBoxSize();
1918 mLegend->endCommand();
1925QgsLayoutLegendMapFilteringWidget::QgsLayoutLegendMapFilteringWidget(
QgsLayoutItemLegend *legend )
1927 , mLegendItem( legend )
1930 setPanelTitle( tr(
"Legend Filtering" ) );
1932 setNewItem( legend );
1935bool QgsLayoutLegendMapFilteringWidget::setNewItem(
QgsLayoutItem *item )
1945 mLegendItem = qobject_cast< QgsLayoutItemLegend * >( item );
1952 updateGuiElements();
1957void QgsLayoutLegendMapFilteringWidget::updateGuiElements()
1959 if ( mBlockUpdates )
1962 mBlockUpdates =
true;
1964 if ( mFilterMapItemsListView->model() )
1966 QAbstractItemModel *oldModel = mFilterMapItemsListView->model();
1967 mFilterMapItemsListView->setModel(
nullptr );
1968 oldModel->deleteLater();
1971 QgsLayoutLegendMapFilteringModel *model =
new QgsLayoutLegendMapFilteringModel( mLegendItem, mLegendItem->layout()->itemsModel(), mFilterMapItemsListView );
1972 mFilterMapItemsListView->setModel( model );
1974 mBlockUpdates =
false;
1982 : QSortFilterProxyModel( parent )
1983 , mLayoutModel( layoutModel )
1984 , mLegendItem( legend )
1986 setSourceModel( layoutModel );
1989int QgsLayoutLegendMapFilteringModel::columnCount(
const QModelIndex & )
const
1994QVariant QgsLayoutLegendMapFilteringModel::data(
const QModelIndex &i,
int role )
const
1999 if ( i.column() != 0 )
2004 QgsLayoutItemMap *mapItem = qobject_cast< QgsLayoutItemMap * >( mLayoutModel->itemFromIndex( mapToSource( i ) ) );
2012 case Qt::CheckStateRole:
2013 switch ( i.column() )
2018 return Qt::Unchecked;
2020 return mLegendItem->filterByMapItems().contains( mapItem ) ? Qt::Checked : Qt::Unchecked;
2028 return mLayoutModel->data( sourceIndex, role );
2032bool QgsLayoutLegendMapFilteringModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
2036 if ( !index.isValid() )
2039 QgsLayoutItemMap *mapItem = qobject_cast< QgsLayoutItemMap * >( mLayoutModel->itemFromIndex( mapToSource( index ) ) );
2040 if ( !mapItem || !mLegendItem )
2045 mLegendItem->layout()->undoStack()->beginCommand( mLegendItem, tr(
"Change Legend Linked Maps" ) );
2047 QList< QgsLayoutItemMap * > linkedMaps = mLegendItem->filterByMapItems();
2048 if ( value.toBool() )
2050 if ( !linkedMaps.contains( mapItem ) )
2052 linkedMaps.append( mapItem );
2053 mLegendItem->setFilterByMapItems( linkedMaps );
2058 linkedMaps.removeAll( mapItem );
2059 mLegendItem->setFilterByMapItems( linkedMaps );
2061 emit dataChanged( index, index, QVector<int>() << role );
2063 mLegendItem->layout()->undoStack()->endCommand();
2064 mLegendItem->invalidateCache();
2069Qt::ItemFlags QgsLayoutLegendMapFilteringModel::flags(
const QModelIndex &index )
const
2071 Qt::ItemFlags flags = QSortFilterProxyModel::flags( index );
2073 if ( ! index.isValid() )
2078 QgsLayoutItemMap *mapItem = qobject_cast< QgsLayoutItemMap * >( mLayoutModel->itemFromIndex( mapToSource( index ) ) );
2079 const bool isMainLinkedMapItem = mLegendItem ? ( mLegendItem->linkedMap() == mapItem ) : false;
2085 if ( !isMainLinkedMapItem )
2087 flags |= Qt::ItemIsEnabled;
2091 flags &= ~Qt::ItemIsEnabled;
2094 switch ( index.column() )
2097 if ( !isMainLinkedMapItem )
2098 return flags | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
2100 return flags | Qt::ItemIsSelectable;
2103 return flags | Qt::ItemIsSelectable;
2107bool QgsLayoutLegendMapFilteringModel::filterAcceptsRow(
int source_row,
const QModelIndex &source_parent )
const
2109 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 (since QGIS 3.18)
@ 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)
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.
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.
Q_GUI_EXPORT int qt_defaultDpiX()