50#include <QInputDialog>
51#include <QActionGroup>
66 int unfilteredNodeIndex = _unfilteredLegendNodeIndex( legendNode );
68 return ( unfilteredNodeIndex >= 0 && unfilteredNodeIndex < order.count() ? order[unfilteredNodeIndex] : -1 );
75 , mMapCanvas( mapCanvas )
80 connect( mWrapCharLineEdit, &QLineEdit::textChanged,
this, &QgsLayoutLegendWidget::mWrapCharLineEdit_textChanged );
81 connect( mTitleLineEdit, &QLineEdit::textChanged,
this, &QgsLayoutLegendWidget::mTitleLineEdit_textChanged );
86 connect( mColumnCountSpinBox,
static_cast < void ( QSpinBox::* )(
int )
> ( &QSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mColumnCountSpinBox_valueChanged );
87 connect( mSplitLayerCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mSplitLayerCheckBox_toggled );
88 connect( mEqualColumnWidthCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mEqualColumnWidthCheckBox_toggled );
89 connect( mSymbolWidthSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mSymbolWidthSpinBox_valueChanged );
90 connect( mSymbolHeightSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mSymbolHeightSpinBox_valueChanged );
91 connect( mMaxSymbolSizeSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mMaxSymbolSizeSpinBox_valueChanged );
92 connect( mMinSymbolSizeSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mMinSymbolSizeSpinBox_valueChanged );
93 connect( mWmsLegendWidthSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mWmsLegendWidthSpinBox_valueChanged );
94 connect( mWmsLegendHeightSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mWmsLegendHeightSpinBox_valueChanged );
95 connect( mTitleSpaceBottomSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mTitleSpaceBottomSpinBox_valueChanged );
96 connect( mGroupSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mGroupSpaceSpinBox_valueChanged );
97 connect( mGroupIndentSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mGroupIndentSpinBox_valueChanged );
98 connect( mSubgroupIndentSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mSubgroupIndentSpinBox_valueChanged );
99 connect( mSpaceBelowGroupHeadingSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceBelowGroupHeadingChanged );
100 connect( mGroupSideSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceGroupSideChanged );
101 connect( mLayerSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mLayerSpaceSpinBox_valueChanged );
102 connect( mSpaceBelowSubgroupHeadingSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceBelowSubGroupHeadingChanged );
103 connect( mSubgroupSideSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceSubGroupSideChanged );
104 connect( mSymbolSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mSymbolSpaceSpinBox_valueChanged );
105 connect( mSymbolSideSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceSymbolSideChanged );
106 connect( mIconLabelSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mIconLabelSpaceSpinBox_valueChanged );
107 connect( mBoxSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mBoxSpaceSpinBox_valueChanged );
108 connect( mColumnSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mColumnSpaceSpinBox_valueChanged );
109 connect( mCheckBoxAutoUpdate, &QCheckBox::stateChanged,
this, [ = ](
int state ) { mCheckBoxAutoUpdate_stateChanged( state ); } );
110 connect( mCheckboxResizeContents, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mCheckboxResizeContents_toggled );
111 connect( mRasterStrokeGroupBox, &QgsCollapsibleGroupBoxBasic::toggled,
this, &QgsLayoutLegendWidget::mRasterStrokeGroupBox_toggled );
112 connect( mRasterStrokeWidthSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mRasterStrokeWidthSpinBox_valueChanged );
113 connect( mRasterStrokeColorButton, &
QgsColorButton::colorChanged,
this, &QgsLayoutLegendWidget::mRasterStrokeColorButton_colorChanged );
114 connect( mExpandAllToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::expandLegendTree );
115 connect( mCollapseAllToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::collapseLegendTree );
116 connect( mMoveDownToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mMoveDownToolButton_clicked );
117 connect( mMoveUpToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mMoveUpToolButton_clicked );
118 connect( mRemoveToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mRemoveToolButton_clicked );
119 connect( mAddToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mAddToolButton_clicked );
120 connect( mEditPushButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mEditPushButton_clicked );
121 connect( mCountToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mCountToolButton_clicked );
122 connect( mExpressionFilterButton, &QgsLegendFilterButton::toggled,
this, &QgsLayoutLegendWidget::mExpressionFilterButton_toggled );
123 connect( mLayerExpressionButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mLayerExpressionButton_clicked );
124 connect( mFilterByMapCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mFilterByMapCheckBox_toggled );
125 connect( mUpdateAllPushButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mUpdateAllPushButton_clicked );
126 connect( mAddGroupToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mAddGroupToolButton_clicked );
127 connect( mFilterLegendByAtlasCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mFilterLegendByAtlasCheckBox_toggled );
128 connect( mItemTreeView, &QgsLayerTreeView::doubleClicked,
this, &QgsLayoutLegendWidget::mItemTreeView_doubleClicked );
130 connect( mFilterByMapCheckBox, &QCheckBox::toggled, mButtonLinkedMaps, &QWidget::setEnabled );
131 mButtonLinkedMaps->setEnabled(
false );
132 connect( mButtonLinkedMaps, &QToolButton::clicked,
this, [ = ]
134 mMapFilteringWidget =
new QgsLayoutLegendMapFilteringWidget( mLegend );
135 openPanel( mMapFilteringWidget );
138 setPanelTitle( tr(
"Legend Properties" ) );
145 mTitleAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
146 mGroupAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
147 mSubgroupAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
148 mItemAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
150 mArrangementCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignRight );
152 mArrangementCombo->customizeAlignmentDisplay( Qt::AlignLeft, tr(
"Symbols on Left" ),
QgsApplication::getThemeIcon( QStringLiteral(
"/mIconArrangeSymbolsLeft.svg" ) ) );
153 mArrangementCombo->customizeAlignmentDisplay( Qt::AlignRight, tr(
"Symbols on Right" ),
QgsApplication::getThemeIcon( QStringLiteral(
"/mIconArrangeSymbolsRight.svg" ) ) );
155 mSpaceBelowGroupHeadingSpinBox->setClearValue( 0 );
156 mGroupSideSpinBox->setClearValue( 0 );
157 mSpaceBelowSubgroupHeadingSpinBox->setClearValue( 0 );
158 mSubgroupSideSpinBox->setClearValue( 0 );
159 mSymbolSideSpaceSpinBox->setClearValue( 0 );
184 mRasterStrokeColorButton->setColorDialogTitle( tr(
"Select Stroke Color" ) );
185 mRasterStrokeColorButton->setAllowOpacity(
true );
186 mRasterStrokeColorButton->setContext( QStringLiteral(
"composer " ) );
188 mMapComboBox->setCurrentLayout( legend->
layout() );
194 mainLayout->addWidget( mItemPropertiesWidget );
196 mItemTreeView->setHeaderHidden(
true );
198 mItemTreeView->setModel( legend->
model() );
199 mItemTreeView->setMenuProvider(
new QgsLayoutLegendMenuProvider( mItemTreeView,
this ) );
200 setLegendMapViewData();
206 connect( layoutAtlas(), &
QgsLayoutAtlas::toggled,
this, &QgsLayoutLegendWidget::updateFilterLegendByAtlasButton );
210 mTitleFontButton->registerExpressionContextGenerator(
this );
211 mGroupFontButton->registerExpressionContextGenerator(
this );
212 mLayerFontButton->registerExpressionContextGenerator(
this );
213 mItemFontButton->registerExpressionContextGenerator(
this );
214 mExpressionFilterButton->registerExpressionContextGenerator(
this );
216 mTitleFontButton->setLayer( coverageLayer() );
217 mGroupFontButton->setLayer( coverageLayer() );
218 mLayerFontButton->setLayer( coverageLayer() );
219 mItemFontButton->setLayer( coverageLayer() );
220 if ( mLegend->layout() )
233 connect( mItemTreeView->selectionModel(), &QItemSelectionModel::currentChanged,
234 this, &QgsLayoutLegendWidget::selectedChanged );
243 if ( mItemPropertiesWidget )
244 mItemPropertiesWidget->setMasterLayout( masterLayout );
250 mTitleFontButton->setMessageBar( iface->
messageBar() );
251 mGroupFontButton->setMessageBar( iface->
messageBar() );
252 mLayerFontButton->setMessageBar( iface->
messageBar() );
253 mItemFontButton->setMessageBar( iface->
messageBar() );
256void QgsLayoutLegendWidget::setGuiElements()
263 blockAllSignals(
true );
264 mTitleLineEdit->setText( mLegend->title() );
265 whileBlocking( mTitleAlignCombo )->setCurrentAlignment( mLegend->titleAlignment() );
269 whileBlocking( mArrangementCombo )->setCurrentAlignment( mLegend->symbolAlignment() );
270 mFilterByMapCheckBox->setChecked( mLegend->legendFilterByMapEnabled() );
271 mButtonLinkedMaps->setEnabled( mLegend->legendFilterByMapEnabled() );
272 mColumnCountSpinBox->setValue( mLegend->columnCount() );
273 mSplitLayerCheckBox->setChecked( mLegend->splitLayer() );
274 mEqualColumnWidthCheckBox->setChecked( mLegend->equalColumnWidth() );
275 mSymbolWidthSpinBox->setValue( mLegend->symbolWidth() );
276 mSymbolHeightSpinBox->setValue( mLegend->symbolHeight() );
277 mMaxSymbolSizeSpinBox->setValue( mLegend->maximumSymbolSize() );
278 mMinSymbolSizeSpinBox->setValue( mLegend->minimumSymbolSize() );
279 mWmsLegendWidthSpinBox->setValue( mLegend->wmsLegendWidth() );
280 mWmsLegendHeightSpinBox->setValue( mLegend->wmsLegendHeight() );
294 mBoxSpaceSpinBox->setValue( mLegend->boxSpace() );
295 mColumnSpaceSpinBox->setValue( mLegend->columnSpace() );
297 mRasterStrokeGroupBox->setChecked( mLegend->drawRasterStroke() );
298 mRasterStrokeWidthSpinBox->setValue( mLegend->rasterStrokeWidth() );
299 mRasterStrokeColorButton->setColor( mLegend->rasterStrokeColor() );
301 mCheckBoxAutoUpdate->setChecked( mLegend->autoUpdateModel() );
303 mCheckboxResizeContents->setChecked( mLegend->resizeToContents() );
304 mFilterLegendByAtlasCheckBox->setChecked( mLegend->legendFilterOutAtlas() );
305 mWrapCharLineEdit->setText( mLegend->wrapString() );
308 mMapComboBox->setItem( map );
314 blockAllSignals(
false );
316 mCheckBoxAutoUpdate_stateChanged( mLegend->autoUpdateModel() ? Qt::Checked : Qt::Unchecked, false );
317 updateDataDefinedButton( mLegendTitleDDBtn );
318 updateDataDefinedButton( mColumnsDDBtn );
321void QgsLayoutLegendWidget::mWrapCharLineEdit_textChanged(
const QString &text )
325 mLegend->beginCommand( tr(
"Change Legend Wrap" ) );
326 mLegend->setWrapString( text );
327 mLegend->adjustBoxSize();
329 mLegend->endCommand();
333void QgsLayoutLegendWidget::mTitleLineEdit_textChanged(
const QString &text )
338 mLegend->setTitle( text );
339 mLegend->adjustBoxSize();
341 mLegend->endCommand();
345void QgsLayoutLegendWidget::titleAlignmentChanged()
349 Qt::AlignmentFlag alignment =
static_cast< Qt::AlignmentFlag
>(
static_cast< int >( mTitleAlignCombo->currentAlignment() & Qt::AlignHorizontal_Mask ) );
350 mLegend->beginCommand( tr(
"Change Title Alignment" ) );
351 mLegend->setTitleAlignment( alignment );
353 mLegend->endCommand();
357void QgsLayoutLegendWidget::groupAlignmentChanged()
361 mLegend->beginCommand( tr(
"Change Group Alignment" ) );
364 mLegend->endCommand();
368void QgsLayoutLegendWidget::subgroupAlignmentChanged()
372 mLegend->beginCommand( tr(
"Change Subgroup Alignment" ) );
375 mLegend->endCommand();
379void QgsLayoutLegendWidget::itemAlignmentChanged()
383 mLegend->beginCommand( tr(
"Change Item Alignment" ) );
386 mLegend->endCommand();
390void QgsLayoutLegendWidget::arrangementChanged()
394 Qt::AlignmentFlag alignment =
static_cast< Qt::AlignmentFlag
>(
static_cast< int >( mArrangementCombo->currentAlignment() & Qt::AlignHorizontal_Mask ) );
395 mLegend->beginCommand( tr(
"Change Legend Arrangement" ) );
396 mLegend->setSymbolAlignment( alignment );
398 mLegend->endCommand();
402void QgsLayoutLegendWidget::mColumnCountSpinBox_valueChanged(
int c )
407 mLegend->setColumnCount(
c );
408 mLegend->adjustBoxSize();
410 mLegend->endCommand();
412 mSplitLayerCheckBox->setEnabled(
c > 1 );
413 mEqualColumnWidthCheckBox->setEnabled(
c > 1 );
416void QgsLayoutLegendWidget::mSplitLayerCheckBox_toggled(
bool checked )
420 mLegend->beginCommand( tr(
"Split Legend Layers" ) );
421 mLegend->setSplitLayer( checked );
422 mLegend->adjustBoxSize();
424 mLegend->endCommand();
428void QgsLayoutLegendWidget::mEqualColumnWidthCheckBox_toggled(
bool checked )
432 mLegend->beginCommand( tr(
"Legend Column Width" ) );
433 mLegend->setEqualColumnWidth( checked );
434 mLegend->adjustBoxSize();
436 mLegend->endCommand();
440void QgsLayoutLegendWidget::mSymbolWidthSpinBox_valueChanged(
double d )
445 mLegend->setSymbolWidth( d );
446 mLegend->adjustBoxSize();
448 mLegend->endCommand();
452void QgsLayoutLegendWidget::mMaxSymbolSizeSpinBox_valueChanged(
double d )
457 mLegend->setMaximumSymbolSize( d );
458 mLegend->adjustBoxSize();
460 mLegend->endCommand();
464void QgsLayoutLegendWidget::mMinSymbolSizeSpinBox_valueChanged(
double d )
469 mLegend->setMinimumSymbolSize( d );
470 mLegend->adjustBoxSize();
472 mLegend->endCommand();
476void QgsLayoutLegendWidget::mSymbolHeightSpinBox_valueChanged(
double d )
481 mLegend->setSymbolHeight( d );
482 mLegend->adjustBoxSize();
484 mLegend->endCommand();
488void QgsLayoutLegendWidget::mWmsLegendWidthSpinBox_valueChanged(
double d )
493 mLegend->setWmsLegendWidth( d );
494 mLegend->adjustBoxSize();
496 mLegend->endCommand();
500void QgsLayoutLegendWidget::mWmsLegendHeightSpinBox_valueChanged(
double d )
505 mLegend->setWmsLegendHeight( d );
506 mLegend->adjustBoxSize();
508 mLegend->endCommand();
512void QgsLayoutLegendWidget::mTitleSpaceBottomSpinBox_valueChanged(
double d )
518 mLegend->adjustBoxSize();
520 mLegend->endCommand();
524void QgsLayoutLegendWidget::mGroupSpaceSpinBox_valueChanged(
double d )
530 mLegend->adjustBoxSize();
532 mLegend->endCommand();
536void QgsLayoutLegendWidget::mGroupIndentSpinBox_valueChanged(
double d )
542 mLegend->adjustBoxSize();
544 mLegend->endCommand();
548void QgsLayoutLegendWidget::mSubgroupIndentSpinBox_valueChanged(
double d )
554 mLegend->adjustBoxSize();
556 mLegend->endCommand();
560void QgsLayoutLegendWidget::spaceBelowGroupHeadingChanged(
double space )
566 mLegend->adjustBoxSize();
568 mLegend->endCommand();
572void QgsLayoutLegendWidget::spaceGroupSideChanged(
double space )
578 mLegend->adjustBoxSize();
580 mLegend->endCommand();
584void QgsLayoutLegendWidget::spaceSubGroupSideChanged(
double space )
590 mLegend->adjustBoxSize();
592 mLegend->endCommand();
596void QgsLayoutLegendWidget::spaceSymbolSideChanged(
double space )
602 mLegend->adjustBoxSize();
604 mLegend->endCommand();
608void QgsLayoutLegendWidget::mLayerSpaceSpinBox_valueChanged(
double d )
614 mLegend->adjustBoxSize();
616 mLegend->endCommand();
620void QgsLayoutLegendWidget::mSymbolSpaceSpinBox_valueChanged(
double d )
628 mLegend->adjustBoxSize();
630 mLegend->endCommand();
634void QgsLayoutLegendWidget::mIconLabelSpaceSpinBox_valueChanged(
double d )
640 mLegend->adjustBoxSize();
642 mLegend->endCommand();
646void QgsLayoutLegendWidget::titleFontChanged()
652 mLegend->adjustBoxSize();
654 mLegend->endCommand();
658void QgsLayoutLegendWidget::groupFontChanged()
664 mLegend->adjustBoxSize();
666 mLegend->endCommand();
670void QgsLayoutLegendWidget::layerFontChanged()
676 mLegend->adjustBoxSize();
678 mLegend->endCommand();
682void QgsLayoutLegendWidget::itemFontChanged()
688 mLegend->adjustBoxSize();
690 mLegend->endCommand();
694void QgsLayoutLegendWidget::spaceBelowSubGroupHeadingChanged(
double space )
700 mLegend->adjustBoxSize();
702 mLegend->endCommand();
706void QgsLayoutLegendWidget::mBoxSpaceSpinBox_valueChanged(
double d )
711 mLegend->setBoxSpace( d );
712 mLegend->adjustBoxSize();
714 mLegend->endCommand();
718void QgsLayoutLegendWidget::mColumnSpaceSpinBox_valueChanged(
double d )
723 mLegend->setColumnSpace( d );
724 mLegend->adjustBoxSize();
726 mLegend->endCommand();
730static void _moveLegendNode(
QgsLayerTreeLayer *nodeLayer,
int legendNodeIndex,
int offset )
734 if ( legendNodeIndex < 0 || legendNodeIndex >= order.count() )
736 if ( legendNodeIndex + offset < 0 || legendNodeIndex + offset >= order.count() )
739 int id = order.takeAt( legendNodeIndex );
740 order.insert( legendNodeIndex + offset,
id );
746void QgsLayoutLegendWidget::mMoveDownToolButton_clicked()
753 const QModelIndex index = mItemTreeView->selectionModel()->currentIndex();
754 const QModelIndex sourceIndex = mItemTreeView->proxyModel()->mapToSource( index );
755 const QModelIndex parentIndex = sourceIndex.parent();
756 if ( !sourceIndex.isValid() || sourceIndex.row() == mItemTreeView->layerTreeModel()->rowCount( parentIndex ) - 1 )
761 if ( !node && !legendNode )
764 mLegend->beginCommand( tr(
"Moved Legend Item Down" ) );
778 mItemTreeView->setCurrentIndex( mItemTreeView->proxyModel()->mapFromSource( mItemTreeView->layerTreeModel()->index( sourceIndex.row() + 1, 0, parentIndex ) ) );
781 mLegend->endCommand();
784void QgsLayoutLegendWidget::mMoveUpToolButton_clicked()
791 const QModelIndex index = mItemTreeView->selectionModel()->currentIndex();
792 const QModelIndex sourceIndex = mItemTreeView->proxyModel()->mapToSource( index );
793 const QModelIndex parentIndex = sourceIndex.parent();
794 if ( !sourceIndex.isValid() || sourceIndex.row() == 0 )
799 if ( !node && !legendNode )
802 mLegend->beginCommand( tr(
"Move Legend Item Up" ) );
816 mItemTreeView->setCurrentIndex( mItemTreeView->proxyModel()->mapFromSource( mItemTreeView->layerTreeModel()->index( sourceIndex.row() - 1, 0, parentIndex ) ) );
819 mLegend->endCommand();
822void QgsLayoutLegendWidget::expandLegendTree()
824 mItemTreeView -> expandAll();
827void QgsLayoutLegendWidget::collapseLegendTree()
829 mItemTreeView -> collapseAll();
832void QgsLayoutLegendWidget::mCheckBoxAutoUpdate_stateChanged(
int state,
bool userTriggered )
836 mLegend->beginCommand( tr(
"Change Auto Update" ) );
838 mLegend->setAutoUpdateModel( state == Qt::Checked );
840 mLegend->endCommand();
844 QList<QWidget *> widgets;
845 widgets << mMoveDownToolButton << mMoveUpToolButton << mRemoveToolButton << mAddToolButton
846 << mEditPushButton << mCountToolButton << mUpdateAllPushButton << mAddGroupToolButton
847 << mExpressionFilterButton << mCollapseAllToolButton << mExpandAllToolButton;
848 for ( QWidget *w : std::as_const( widgets ) )
849 w->setEnabled( state != Qt::Checked );
851 if ( state == Qt::Unchecked )
854 selectedChanged( QModelIndex(), QModelIndex() );
855 mItemTreeView->proxyModel()->setShowPrivateLayers(
true );
859 mItemTreeView->proxyModel()->setShowPrivateLayers(
false );
863void QgsLayoutLegendWidget::composerMapChanged(
QgsLayoutItem *item )
879 mLegend->beginCommand( tr(
"Change Legend Map" ) );
880 mLegend->setLinkedMap( map );
882 mLegend->endCommand();
884 setLegendMapViewData();
888void QgsLayoutLegendWidget::mCheckboxResizeContents_toggled(
bool checked )
895 mLegend->beginCommand( tr(
"Resize Legend to Contents" ) );
896 mLegend->setResizeToContents( checked );
898 mLegend->adjustBoxSize();
900 mLegend->endCommand();
903void QgsLayoutLegendWidget::mRasterStrokeGroupBox_toggled(
bool state )
910 mLegend->beginCommand( tr(
"Change Legend Borders" ) );
911 mLegend->setDrawRasterStroke( state );
912 mLegend->adjustBoxSize();
914 mLegend->endCommand();
917void QgsLayoutLegendWidget::mRasterStrokeWidthSpinBox_valueChanged(
double d )
925 mLegend->setRasterStrokeWidth( d );
926 mLegend->adjustBoxSize();
928 mLegend->endCommand();
931void QgsLayoutLegendWidget::mRasterStrokeColorButton_colorChanged(
const QColor &newColor )
939 mLegend->setRasterStrokeColor( newColor );
941 mLegend->endCommand();
944void QgsLayoutLegendWidget::mAddToolButton_clicked()
951 QList< QgsMapLayer * > visibleLayers;
952 if ( mLegend->linkedMap() )
954 visibleLayers = mLegend->linkedMap()->layersToRender();
956 if ( visibleLayers.isEmpty() )
959 visibleLayers = mMapCanvas->layers(
true );
963 addDialog.setVisibleLayers( visibleLayers );
964 if ( addDialog.exec() == QDialog::Accepted )
966 const QList<QgsMapLayer *> layers = addDialog.selectedLayers();
967 if ( !layers.empty() )
969 mLegend->beginCommand( tr(
"Add Legend Item(s)" ) );
972 mLegend->model()->rootGroup()->addLayer( layer );
974 mLegend->updateLegend();
976 mLegend->endCommand();
981void QgsLayoutLegendWidget::mRemoveToolButton_clicked()
988 QItemSelectionModel *selectionModel = mItemTreeView->selectionModel();
989 if ( !selectionModel )
994 mLegend->beginCommand( tr(
"Remove Legend Item" ) );
996 QList<QPersistentModelIndex> proxyIndexes;
997 const QModelIndexList viewSelection = selectionModel->selectedIndexes();
998 for (
const QModelIndex &index : viewSelection )
999 proxyIndexes << index;
1002 QHash<QgsLayerTreeLayer *, QList<int> > nodesWithRemoval;
1003 for (
const QPersistentModelIndex &proxyIndex : std::as_const( proxyIndexes ) )
1008 nodesWithRemoval[nodeLayer].append( _unfilteredLegendNodeIndex( legendNode ) );
1011 for (
auto it = nodesWithRemoval.constBegin(); it != nodesWithRemoval.constEnd(); ++it )
1013 QList<int> toDelete = it.value();
1014 std::sort( toDelete.begin(), toDelete.end(), std::greater<int>() );
1017 for (
int i : std::as_const( toDelete ) )
1019 if ( i >= 0 && i < order.count() )
1020 order.removeAt( i );
1024 mItemTreeView->layerTreeModel()->refreshLayerLegend( it.key() );
1028 for (
const QPersistentModelIndex &proxyIndex : std::as_const( proxyIndexes ) )
1030 if ( proxyIndex.isValid() && mItemTreeView->index2node( proxyIndex ) )
1032 const QModelIndex sourceIndex = mItemTreeView->proxyModel()->mapToSource( proxyIndex );
1033 mLegend->model()->removeRow( sourceIndex.row(), sourceIndex.parent() );
1037 mLegend->updateLegend();
1039 mLegend->endCommand();
1042void QgsLayoutLegendWidget::mEditPushButton_clicked()
1049 QModelIndex idx = mItemTreeView->selectionModel()->currentIndex();
1050 mItemTreeView_doubleClicked( idx );
1053void QgsLayoutLegendWidget::resetLayerNodeToDefaults()
1061 QModelIndex currentIndex = mItemTreeView->currentIndex();
1062 if ( !currentIndex.isValid() )
1081 mLegend->beginCommand( tr(
"Update Legend" ) );
1084 for (
const QString &key : constCustomProperties )
1086 if ( key.startsWith( QLatin1String(
"legend/" ) ) )
1093 mItemTreeView->layerTreeModel()->refreshLayerLegend( nodeLayer );
1095 mLegend->updateLegend();
1097 mLegend->endCommand();
1100void QgsLayoutLegendWidget::mCountToolButton_clicked(
bool checked )
1107 const QList< QModelIndex > selectedIndexes = mItemTreeView->selectionModel()->selectedIndexes();
1108 if ( selectedIndexes.empty() )
1111 mLegend->beginCommand( tr(
"Update Legend" ) );
1112 for (
const QModelIndex &index : selectedIndexes )
1118 currentNode->
setCustomProperty( QStringLiteral(
"showFeatureCount" ), checked ? 1 : 0 );
1120 mLegend->updateFilterByMap();
1121 mLegend->adjustBoxSize();
1122 mLegend->endCommand();
1125void QgsLayoutLegendWidget::mFilterByMapCheckBox_toggled(
bool checked )
1127 mLegend->beginCommand( tr(
"Update Legend" ) );
1128 mLegend->setLegendFilterByMapEnabled( checked );
1129 mLegend->adjustBoxSize();
1131 mLegend->endCommand();
1134void QgsLayoutLegendWidget::mExpressionFilterButton_toggled(
bool checked )
1142 QModelIndex currentIndex = mItemTreeView->currentIndex();
1143 if ( !currentIndex.isValid() )
1153 mExpressionFilterButton->expressionText(),
1156 mLegend->beginCommand( tr(
"Update Legend" ) );
1157 mLegend->updateFilterByMap();
1158 mLegend->adjustBoxSize();
1159 mLegend->endCommand();
1162void QgsLayoutLegendWidget::mLayerExpressionButton_clicked()
1169 QModelIndex currentIndex = mItemTreeView->currentIndex();
1170 if ( !currentIndex.isValid() )
1177 QgsLayerTreeLayer *layerNode = qobject_cast<QgsLayerTreeLayer *>( currentNode );
1183 QString currentExpression;
1185 currentExpression = QStringLiteral(
"@symbol_label" );
1191 QStringList highlighted;
1194 const QList<QgsLayerTreeModelLegendNode *> legendNodes = model->layerLegendNodes( layerNode,
false );
1195 if ( !legendNodes.isEmpty() )
1197 if (
QgsSymbolLegendNode *symbolNode = qobject_cast<QgsSymbolLegendNode *>( legendNodes.first() ) )
1199 legendContext.
appendScope( symbolNode->createSymbolScope() );
1200 highlighted << QStringLiteral(
"symbol_label" ) << QStringLiteral(
"symbol_id" ) << QStringLiteral(
"symbol_count" );
1213 QgsExpressionBuilderDialog expressiondialog(
nullptr, currentExpression,
nullptr, QStringLiteral(
"generic" ), legendContext );
1214 if ( expressiondialog.exec() )
1217 mItemTreeView->layerTreeModel()->refreshLayerLegend( layerNode );
1220 mLegend->beginCommand( tr(
"Update Legend" ) );
1222 mLegend->adjustBoxSize();
1223 mLegend->endCommand();
1226void QgsLayoutLegendWidget::mUpdateAllPushButton_clicked()
1231void QgsLayoutLegendWidget::mAddGroupToolButton_clicked()
1235 mLegend->beginCommand( tr(
"Add Legend Group" ) );
1236 mLegend->model()->rootGroup()->addGroup( tr(
"Group" ) );
1237 mLegend->updateLegend();
1239 mLegend->endCommand();
1243void QgsLayoutLegendWidget::mFilterLegendByAtlasCheckBox_toggled(
bool toggled )
1248 mLegend->setLegendFilterOutAtlas( toggled );
1254void QgsLayoutLegendWidget::updateLegend()
1258 mLegend->beginCommand( tr(
"Update Legend" ) );
1261 mLegend->setAutoUpdateModel(
true );
1262 mLegend->setAutoUpdateModel(
false );
1264 mLegend->endCommand();
1268void QgsLayoutLegendWidget::setReportTypeString(
const QString &
string )
1270 mFilterLegendByAtlasCheckBox->setText( tr(
"Only show items inside current %1 feature" ).arg(
string ) );
1271 mFilterLegendByAtlasCheckBox->setToolTip( tr(
"Filter out legend elements that lie outside the current %1 feature." ).arg(
string ) );
1280bool QgsLayoutLegendWidget::setNewItem(
QgsLayoutItem *item )
1290 mLegend = qobject_cast< QgsLayoutItemLegend * >( item );
1291 mItemPropertiesWidget->setItem( mLegend );
1293 if ( mMapFilteringWidget )
1294 mMapFilteringWidget->setItem( mLegend );
1298 mItemTreeView->setModel( mLegend->model() );
1307void QgsLayoutLegendWidget::blockAllSignals(
bool b )
1309 mTitleLineEdit->blockSignals( b );
1310 mTitleAlignCombo->blockSignals( b );
1311 mItemTreeView->blockSignals( b );
1312 mCheckBoxAutoUpdate->blockSignals( b );
1313 mMapComboBox->blockSignals( b );
1314 mFilterByMapCheckBox->blockSignals( b );
1315 mColumnCountSpinBox->blockSignals( b );
1316 mSplitLayerCheckBox->blockSignals( b );
1317 mEqualColumnWidthCheckBox->blockSignals( b );
1318 mSymbolWidthSpinBox->blockSignals( b );
1319 mSymbolHeightSpinBox->blockSignals( b );
1320 mMaxSymbolSizeSpinBox->blockSignals( b );
1321 mMinSymbolSizeSpinBox->blockSignals( b );
1322 mGroupSpaceSpinBox->blockSignals( b );
1323 mGroupIndentSpinBox->blockSignals( b );
1324 mSubgroupIndentSpinBox->blockSignals( b );
1325 mSpaceBelowGroupHeadingSpinBox->blockSignals( b );
1326 mGroupSideSpinBox->blockSignals( b );
1327 mSpaceBelowSubgroupHeadingSpinBox->blockSignals( b );
1328 mSubgroupSideSpinBox->blockSignals( b );
1329 mLayerSpaceSpinBox->blockSignals( b );
1330 mSymbolSpaceSpinBox->blockSignals( b );
1331 mSymbolSideSpaceSpinBox->blockSignals( b );
1332 mIconLabelSpaceSpinBox->blockSignals( b );
1333 mBoxSpaceSpinBox->blockSignals( b );
1334 mColumnSpaceSpinBox->blockSignals( b );
1335 mRasterStrokeGroupBox->blockSignals( b );
1336 mRasterStrokeColorButton->blockSignals( b );
1337 mRasterStrokeWidthSpinBox->blockSignals( b );
1338 mWmsLegendWidthSpinBox->blockSignals( b );
1339 mWmsLegendHeightSpinBox->blockSignals( b );
1340 mCheckboxResizeContents->blockSignals( b );
1341 mTitleSpaceBottomSpinBox->blockSignals( b );
1342 mFilterLegendByAtlasCheckBox->blockSignals( b );
1343 mTitleFontButton->blockSignals( b );
1344 mGroupFontButton->blockSignals( b );
1345 mLayerFontButton->blockSignals( b );
1346 mItemFontButton->blockSignals( b );
1347 mWrapCharLineEdit->blockSignals( b );
1350void QgsLayoutLegendWidget::selectedChanged(
const QModelIndex ¤t,
const QModelIndex &previous )
1353 Q_UNUSED( previous )
1355 mLayerExpressionButton->setEnabled(
false );
1357 if ( mLegend && mLegend->autoUpdateModel() )
1368 mLayerExpressionButton->setEnabled(
true );
1372 mCountToolButton->setChecked(
false );
1373 mCountToolButton->setEnabled(
false );
1376 mExpressionFilterButton->blockSignals(
true );
1377 mExpressionFilterButton->setChecked(
false );
1378 mExpressionFilterButton->setEnabled(
false );
1379 mExpressionFilterButton->blockSignals(
false );
1390 mCountToolButton->setChecked( currentNode->
customProperty( QStringLiteral(
"showFeatureCount" ), 0 ).toInt() );
1391 mCountToolButton->setEnabled(
true );
1392 mLayerExpressionButton->setEnabled(
true );
1396 mExpressionFilterButton->blockSignals(
true );
1397 mExpressionFilterButton->setExpressionText( expr );
1398 mExpressionFilterButton->setVectorLayer( vl );
1399 mExpressionFilterButton->setEnabled(
true );
1400 mExpressionFilterButton->setChecked( exprEnabled );
1401 mExpressionFilterButton->blockSignals(
false );
1404void QgsLayoutLegendWidget::setCurrentNodeStyleFromAction()
1406 QAction *a = qobject_cast<QAction *>( sender() );
1407 if ( !a || !mItemTreeView->currentNode() )
1414void QgsLayoutLegendWidget::setLegendMapViewData()
1416 if ( mLegend->linkedMap() )
1420 measurementConverter.
setDpi( dpi );
1423 double mapUnitsPerPixelX = mLegend->linkedMap()->extent().width() / mapWidth;
1424 double mapUnitsPerPixelY = mLegend->linkedMap()->extent().height() / mapHeight;
1425 mLegend->model()->setLegendMapViewData( ( mapUnitsPerPixelX > mapUnitsPerPixelY ? mapUnitsPerPixelX : mapUnitsPerPixelY ), dpi, mLegend->linkedMap()->scale() );
1429void QgsLayoutLegendWidget::updateFilterLegendByAtlasButton()
1433 mFilterLegendByAtlasCheckBox->setEnabled( atlas->enabled() && mLegend->layout()->reportContext().layer() && mLegend->layout()->reportContext().layer()->geometryType() ==
Qgis::GeometryType::Polygon );
1437void QgsLayoutLegendWidget::mItemTreeView_doubleClicked(
const QModelIndex &idx )
1439 if ( !mLegend || !idx.isValid() )
1444 if ( mLegend->autoUpdateModel() )
1450 int originalIndex = -1;
1453 originalIndex = _originalLegendNodeIndex( legendNode );
1457 QgsLayoutLegendNodeWidget *widget =
new QgsLayoutLegendNodeWidget( mLegend, currentNode, legendNode, originalIndex );
1458 openPanel( widget );
1466QgsLayoutLegendMenuProvider::QgsLayoutLegendMenuProvider(
QgsLayerTreeView *view, QgsLayoutLegendWidget *w )
1471QMenu *QgsLayoutLegendMenuProvider::createContextMenu()
1473 if ( !mView->currentNode() )
1476 if ( mWidget->legend()->autoUpdateModel() )
1479 QMenu *menu =
new QMenu();
1483 menu->addAction( QObject::tr(
"Reset to Defaults" ), mWidget, &QgsLayoutLegendWidget::resetLayerNodeToDefaults );
1484 menu->addSeparator();
1489 QActionGroup *styleGroup =
new QActionGroup{ mWidget };
1490 styleGroup->setExclusive(
true );
1492 QList<QgsLegendStyle::Style> lst;
1496 QAction *action = menu->addAction(
QgsLegendStyle::styleLabel( style ), mWidget, &QgsLayoutLegendWidget::setCurrentNodeStyleFromAction );
1497 action->setActionGroup( styleGroup );
1498 action->setCheckable(
true );
1499 action->setChecked( currentStyle == style );
1500 action->setData(
static_cast< int >( style ) );
1515 , mOriginalLegendNodeIndex( originalLegendNodeIndex )
1518 setPanelTitle( tr(
"Legend Item Properties" ) );
1527 QString currentLabel;
1530 currentLabel = mLegendNode->data( Qt::EditRole ).toString();
1531 mColumnBreakBeforeCheckBox->setChecked( mLegendNode->columnBreak() );
1535 currentLabel = mLayer->name();
1536 QVariant v = mLayer->customProperty( QStringLiteral(
"legend/title-label" ) );
1538 currentLabel = v.toString();
1539 mColumnBreakBeforeCheckBox->setChecked( mLayer->customProperty( QStringLiteral(
"legend/column-break" ) ).toInt() );
1541 mColumnSplitBehaviorComboBox->setCurrentIndex( mColumnSplitBehaviorComboBox->findData( mLayer->legendSplitBehavior() ) );
1546 mColumnBreakBeforeCheckBox->setChecked( mNode->customProperty( QStringLiteral(
"legend/column-break" ) ).toInt() );
1549 mWidthSpinBox->setClearValue( 0, tr(
"Default" ) );
1550 mHeightSpinBox->setClearValue( 0, tr(
"Default" ) );
1551 mWidthSpinBox->setVisible( mLegendNode || mLayer );
1552 mHeightSpinBox->setVisible( mLegendNode || mLayer );
1553 mPatchGroup->setVisible( mLegendNode || mLayer );
1554 mPatchWidthLabel->setVisible( mLegendNode || mLayer );
1555 mPatchHeightLabel->setVisible( mLegendNode || mLayer );
1556 mCustomSymbolCheckBox->setVisible( mLegendNode || mLegend->model()->legendNodeEmbeddedInParent( mLayer ) );
1557 mColumnSplitLabel->setVisible( mLayer && !mLegendNode );
1558 mColumnSplitBehaviorComboBox->setVisible( mLayer && !mLegendNode );
1561 mWidthSpinBox->setValue( mLegendNode->userPatchSize().width() );
1562 mHeightSpinBox->setValue( mLegendNode->userPatchSize().height() );
1566 mWidthSpinBox->setValue( mLayer->patchSize().width() );
1567 mHeightSpinBox->setValue( mLayer->patchSize().height() );
1570 mCustomSymbolCheckBox->setChecked(
false );
1575 patchShape = symbolLegendNode->patchShape();
1577 std::unique_ptr< QgsSymbol > customSymbol( symbolLegendNode->customSymbol() ? symbolLegendNode->customSymbol()->clone() : nullptr );
1578 mCustomSymbolCheckBox->setChecked( customSymbol.get() );
1581 mPatchShapeButton->setPreviewSymbol( customSymbol->clone() );
1583 mCustomSymbolButton->setSymbol( customSymbol.release() );
1585 else if ( symbolLegendNode->symbol() )
1587 mPatchShapeButton->setPreviewSymbol( symbolLegendNode->symbol()->clone() );
1588 mCustomSymbolButton->setSymbolType( symbolLegendNode->symbol()->type() );
1589 mCustomSymbolButton->setSymbol( symbolLegendNode->symbol()->clone() );
1592 else if ( !mLegendNode && mLayer )
1594 patchShape = mLayer->patchShape();
1597 if (
QgsSymbol *customSymbol = symbolLegendNode->customSymbol() )
1599 mCustomSymbolCheckBox->setChecked(
true );
1600 mPatchShapeButton->setPreviewSymbol( customSymbol->clone() );
1602 mCustomSymbolButton->setSymbol( customSymbol->clone() );
1606 mPatchShapeButton->setPreviewSymbol( symbolLegendNode->symbol()->clone() );
1607 mCustomSymbolButton->setSymbolType( symbolLegendNode->symbol()->type() );
1608 mCustomSymbolButton->setSymbol( symbolLegendNode->symbol()->clone() );
1615 switch ( qobject_cast< QgsVectorLayer * >( mLayer->layer() )->geometryType() )
1630 mPatchShapeLabel->hide();
1631 mPatchShapeButton->hide();
1634 if ( !patchShape.
isNull() )
1635 mPatchShapeButton->setShape( patchShape );
1640 if ( symbolLegendNode->symbol() )
1642 mPatchShapeButton->setSymbolType( symbolLegendNode->symbol()->type() );
1646 mPatchShapeLabel->hide();
1647 mPatchShapeButton->hide();
1652 mPatchShapeLabel->hide();
1653 mPatchShapeButton->hide();
1658 mLabelGroup->hide();
1659 mColorRampLegendWidget->setSettings( colorRampNode->settings() );
1663 mColorRampLegendWidget->hide();
1676 mCustomSymbolCheckBox->hide();
1685 mLabelEdit->setPlainText( currentLabel );
1686 connect( mLabelEdit, &QPlainTextEdit::textChanged,
this, &QgsLayoutLegendNodeWidget::labelChanged );
1688 connect( mInsertExpressionButton, &QPushButton::clicked,
this, &QgsLayoutLegendNodeWidget::insertExpression );
1690 connect( mWidthSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendNodeWidget::sizeChanged );
1691 connect( mHeightSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendNodeWidget::sizeChanged );
1693 connect( mCustomSymbolCheckBox, &QGroupBox::toggled,
this, &QgsLayoutLegendNodeWidget::customSymbolChanged );
1696 connect( mColumnBreakBeforeCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendNodeWidget::columnBreakToggled );
1698 connect( mColumnSplitBehaviorComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsLayoutLegendNodeWidget::columnSplitChanged );
1702 connectChildPanel( mColorRampLegendWidget );
1705void QgsLayoutLegendNodeWidget::setDockMode(
bool dockMode )
1707 mColorRampLegendWidget->setDockMode( dockMode );
1711void QgsLayoutLegendNodeWidget::labelChanged()
1715 const QString label = mLabelEdit->toPlainText();
1720 else if ( mLegendNode )
1723 mLegend->model()->refreshLayerLegend( mLayer );
1727 mLayer->setCustomProperty( QStringLiteral(
"legend/title-label" ), label );
1731 embeddedNode->setUserLabel( QString() );
1734 mLegend->adjustBoxSize();
1735 mLegend->invalidateCache();
1737 mLegend->endCommand();
1740void QgsLayoutLegendNodeWidget::patchChanged()
1742 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1748 mLegend->model()->refreshLayerLegend( mLayer );
1752 mLayer->setPatchShape( shape );
1753 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1758 mLegend->model()->refreshLayerLegend( mLayer );
1761 mLegend->adjustBoxSize();
1763 mLegend->endCommand();
1766void QgsLayoutLegendNodeWidget::insertExpression()
1774 QgsVectorLayer *layer = mLegend->layout() ? mLegend->layout()->reportContext().layer() :
nullptr;
1778 if ( mLayer && mLayer->layer() )
1784 << QStringLiteral(
"legend_column_count" )
1785 << QStringLiteral(
"legend_split_layers" )
1786 << QStringLiteral(
"legend_wrap_string" )
1787 << QStringLiteral(
"legend_filter_by_map" )
1788 << QStringLiteral(
"legend_filter_out_atlas" ) );
1792 exprDlg.setWindowTitle( tr(
"Insert Expression" ) );
1793 if ( exprDlg.exec() == QDialog::Accepted )
1795 expression = exprDlg.expressionText();
1796 if ( !expression.isEmpty() )
1798 mLegend->beginCommand( tr(
"Insert expression" ) );
1799 mLabelEdit->insertPlainText(
"[%" + expression.trimmed() +
"%]" );
1800 mLegend->endCommand();
1805void QgsLayoutLegendNodeWidget::sizeChanged(
double )
1807 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1808 const QSizeF size = QSizeF( mWidthSpinBox->value(), mHeightSpinBox->value() );
1813 mLegend->model()->refreshLayerLegend( mLayer );
1817 mLayer->setPatchSize( size );
1818 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1823 mLegend->model()->refreshLayerLegend( mLayer );
1826 mLegend->adjustBoxSize();
1828 mLegend->endCommand();
1831void QgsLayoutLegendNodeWidget::customSymbolChanged()
1833 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1835 if ( mCustomSymbolCheckBox->isChecked() )
1840 mLegend->model()->refreshLayerLegend( mLayer );
1844 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1849 mLegend->model()->refreshLayerLegend( mLayer );
1857 mLegend->model()->refreshLayerLegend( mLayer );
1861 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1866 mLegend->model()->refreshLayerLegend( mLayer );
1870 mLegend->adjustBoxSize();
1872 mLegend->endCommand();
1875void QgsLayoutLegendNodeWidget::colorRampLegendChanged()
1877 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1881 mLegend->model()->refreshLayerLegend( mLayer );
1883 mLegend->adjustBoxSize();
1885 mLegend->endCommand();
1888void QgsLayoutLegendNodeWidget::columnBreakToggled(
bool checked )
1890 mLegend->beginCommand( tr(
"Edit Legend Columns" ) );
1895 mLegend->model()->refreshLayerLegend( mLayer );
1899 mLayer->setCustomProperty( QStringLiteral(
"legend/column-break" ), QString( checked ?
'1' :
'0' ) );
1903 mNode->setCustomProperty( QStringLiteral(
"legend/column-break" ), QString( checked ?
'1' :
'0' ) );
1906 mLegend->adjustBoxSize();
1908 mLegend->endCommand();
1911void QgsLayoutLegendNodeWidget::columnSplitChanged()
1913 mLegend->beginCommand( tr(
"Edit Legend Columns" ) );
1915 if ( mLayer && !mLegendNode )
1920 mLegend->adjustBoxSize();
1922 mLegend->endCommand();
1929QgsLayoutLegendMapFilteringWidget::QgsLayoutLegendMapFilteringWidget(
QgsLayoutItemLegend *legend )
1931 , mLegendItem( legend )
1934 setPanelTitle( tr(
"Legend Filtering" ) );
1936 setNewItem( legend );
1939bool QgsLayoutLegendMapFilteringWidget::setNewItem(
QgsLayoutItem *item )
1949 mLegendItem = qobject_cast< QgsLayoutItemLegend * >( item );
1956 updateGuiElements();
1961void QgsLayoutLegendMapFilteringWidget::updateGuiElements()
1963 if ( mBlockUpdates )
1966 mBlockUpdates =
true;
1968 if ( mFilterMapItemsListView->model() )
1970 QAbstractItemModel *oldModel = mFilterMapItemsListView->model();
1971 mFilterMapItemsListView->setModel(
nullptr );
1972 oldModel->deleteLater();
1975 QgsLayoutLegendMapFilteringModel *model =
new QgsLayoutLegendMapFilteringModel( mLegendItem, mLegendItem->layout()->itemsModel(), mFilterMapItemsListView );
1976 mFilterMapItemsListView->setModel( model );
1978 mBlockUpdates =
false;
1986 : QSortFilterProxyModel( parent )
1987 , mLayoutModel( layoutModel )
1988 , mLegendItem( legend )
1990 setSourceModel( layoutModel );
1993int QgsLayoutLegendMapFilteringModel::columnCount(
const QModelIndex & )
const
1998QVariant QgsLayoutLegendMapFilteringModel::data(
const QModelIndex &i,
int role )
const
2003 if ( i.column() != 0 )
2008 QgsLayoutItemMap *mapItem = qobject_cast< QgsLayoutItemMap * >( mLayoutModel->itemFromIndex( mapToSource( i ) ) );
2016 case Qt::CheckStateRole:
2017 switch ( i.column() )
2022 return Qt::Unchecked;
2024 return mLegendItem->filterByMapItems().contains( mapItem ) ? Qt::Checked : Qt::Unchecked;
2032 return mLayoutModel->data( sourceIndex, role );
2036bool QgsLayoutLegendMapFilteringModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
2040 if ( !index.isValid() )
2043 QgsLayoutItemMap *mapItem = qobject_cast< QgsLayoutItemMap * >( mLayoutModel->itemFromIndex( mapToSource( index ) ) );
2044 if ( !mapItem || !mLegendItem )
2049 mLegendItem->layout()->undoStack()->beginCommand( mLegendItem, tr(
"Change Legend Linked Maps" ) );
2051 QList< QgsLayoutItemMap * > linkedMaps = mLegendItem->filterByMapItems();
2052 if ( value.toBool() )
2054 if ( !linkedMaps.contains( mapItem ) )
2056 linkedMaps.append( mapItem );
2057 mLegendItem->setFilterByMapItems( linkedMaps );
2062 linkedMaps.removeAll( mapItem );
2063 mLegendItem->setFilterByMapItems( linkedMaps );
2065 emit dataChanged( index, index, QVector<int>() << role );
2067 mLegendItem->layout()->undoStack()->endCommand();
2068 mLegendItem->invalidateCache();
2073Qt::ItemFlags QgsLayoutLegendMapFilteringModel::flags(
const QModelIndex &index )
const
2075 Qt::ItemFlags flags = QSortFilterProxyModel::flags( index );
2077 if ( ! index.isValid() )
2082 QgsLayoutItemMap *mapItem = qobject_cast< QgsLayoutItemMap * >( mLayoutModel->itemFromIndex( mapToSource( index ) ) );
2083 const bool isMainLinkedMapItem = mLegendItem ? ( mLegendItem->linkedMap() == mapItem ) : false;
2089 if ( !isMainLinkedMapItem )
2091 flags |= Qt::ItemIsEnabled;
2095 flags &= ~Qt::ItemIsEnabled;
2098 switch ( index.column() )
2101 if ( !isMainLinkedMapItem )
2102 return flags | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
2104 return flags | Qt::ItemIsSelectable;
2107 return flags | Qt::ItemIsSelectable;
2111bool QgsLayoutLegendMapFilteringModel::filterAcceptsRow(
int source_row,
const QModelIndex &source_parent )
const
2113 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.