47#include <QInputDialog>
64 int unfilteredNodeIndex = _unfilteredLegendNodeIndex( legendNode );
66 return ( unfilteredNodeIndex >= 0 && unfilteredNodeIndex < order.count() ? order[unfilteredNodeIndex] : -1 );
73 , mMapCanvas( mapCanvas )
78 connect( mWrapCharLineEdit, &QLineEdit::textChanged,
this, &QgsLayoutLegendWidget::mWrapCharLineEdit_textChanged );
79 connect( mTitleLineEdit, &QLineEdit::textChanged,
this, &QgsLayoutLegendWidget::mTitleLineEdit_textChanged );
84 connect( mColumnCountSpinBox,
static_cast < void ( QSpinBox::* )(
int )
> ( &QSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mColumnCountSpinBox_valueChanged );
85 connect( mSplitLayerCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mSplitLayerCheckBox_toggled );
86 connect( mEqualColumnWidthCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mEqualColumnWidthCheckBox_toggled );
87 connect( mSymbolWidthSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mSymbolWidthSpinBox_valueChanged );
88 connect( mSymbolHeightSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mSymbolHeightSpinBox_valueChanged );
89 connect( mMaxSymbolSizeSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mMaxSymbolSizeSpinBox_valueChanged );
90 connect( mMinSymbolSizeSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mMinSymbolSizeSpinBox_valueChanged );
91 connect( mWmsLegendWidthSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mWmsLegendWidthSpinBox_valueChanged );
92 connect( mWmsLegendHeightSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mWmsLegendHeightSpinBox_valueChanged );
93 connect( mTitleSpaceBottomSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mTitleSpaceBottomSpinBox_valueChanged );
94 connect( mGroupSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mGroupSpaceSpinBox_valueChanged );
95 connect( mGroupIndentSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mGroupIndentSpinBox_valueChanged );
96 connect( mSubgroupIndentSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mSubgroupIndentSpinBox_valueChanged );
97 connect( mSpaceBelowGroupHeadingSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceBelowGroupHeadingChanged );
98 connect( mGroupSideSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceGroupSideChanged );
99 connect( mLayerSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mLayerSpaceSpinBox_valueChanged );
100 connect( mSpaceBelowSubgroupHeadingSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceBelowSubGroupHeadingChanged );
101 connect( mSubgroupSideSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceSubGroupSideChanged );
102 connect( mSymbolSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mSymbolSpaceSpinBox_valueChanged );
103 connect( mSymbolSideSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceSymbolSideChanged );
104 connect( mIconLabelSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mIconLabelSpaceSpinBox_valueChanged );
105 connect( mBoxSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mBoxSpaceSpinBox_valueChanged );
106 connect( mColumnSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mColumnSpaceSpinBox_valueChanged );
107 connect( mCheckBoxAutoUpdate, &QCheckBox::stateChanged,
this, [ = ](
int state ) { mCheckBoxAutoUpdate_stateChanged( state ); } );
108 connect( mCheckboxResizeContents, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mCheckboxResizeContents_toggled );
109 connect( mRasterStrokeGroupBox, &QgsCollapsibleGroupBoxBasic::toggled,
this, &QgsLayoutLegendWidget::mRasterStrokeGroupBox_toggled );
110 connect( mRasterStrokeWidthSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mRasterStrokeWidthSpinBox_valueChanged );
111 connect( mRasterStrokeColorButton, &
QgsColorButton::colorChanged,
this, &QgsLayoutLegendWidget::mRasterStrokeColorButton_colorChanged );
112 connect( mMoveDownToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mMoveDownToolButton_clicked );
113 connect( mMoveUpToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mMoveUpToolButton_clicked );
114 connect( mRemoveToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mRemoveToolButton_clicked );
115 connect( mAddToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mAddToolButton_clicked );
116 connect( mEditPushButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mEditPushButton_clicked );
117 connect( mCountToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mCountToolButton_clicked );
118 connect( mExpressionFilterButton, &QgsLegendFilterButton::toggled,
this, &QgsLayoutLegendWidget::mExpressionFilterButton_toggled );
119 connect( mLayerExpressionButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mLayerExpressionButton_clicked );
120 connect( mFilterByMapCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mFilterByMapCheckBox_toggled );
121 connect( mUpdateAllPushButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mUpdateAllPushButton_clicked );
122 connect( mAddGroupToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mAddGroupToolButton_clicked );
123 connect( mFilterLegendByAtlasCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mFilterLegendByAtlasCheckBox_toggled );
124 connect( mItemTreeView, &QgsLayerTreeView::doubleClicked,
this, &QgsLayoutLegendWidget::mItemTreeView_doubleClicked );
126 connect( mFilterByMapCheckBox, &QCheckBox::toggled, mButtonLinkedMaps, &QWidget::setEnabled );
127 mButtonLinkedMaps->setEnabled(
false );
128 connect( mButtonLinkedMaps, &QToolButton::clicked,
this, [ = ]
130 mMapFilteringWidget =
new QgsLayoutLegendMapFilteringWidget( mLegend );
131 openPanel( mMapFilteringWidget );
134 setPanelTitle( tr(
"Legend Properties" ) );
141 mTitleAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
142 mGroupAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
143 mSubgroupAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
144 mItemAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
146 mArrangementCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignRight );
148 mArrangementCombo->customizeAlignmentDisplay( Qt::AlignLeft, tr(
"Symbols on Left" ),
QgsApplication::getThemeIcon( QStringLiteral(
"/mIconArrangeSymbolsLeft.svg" ) ) );
149 mArrangementCombo->customizeAlignmentDisplay( Qt::AlignRight, tr(
"Symbols on Right" ),
QgsApplication::getThemeIcon( QStringLiteral(
"/mIconArrangeSymbolsRight.svg" ) ) );
151 mSpaceBelowGroupHeadingSpinBox->setClearValue( 0 );
152 mGroupSideSpinBox->setClearValue( 0 );
153 mSpaceBelowSubgroupHeadingSpinBox->setClearValue( 0 );
154 mSubgroupSideSpinBox->setClearValue( 0 );
155 mSymbolSideSpaceSpinBox->setClearValue( 0 );
176 mRasterStrokeColorButton->setColorDialogTitle( tr(
"Select Stroke Color" ) );
177 mRasterStrokeColorButton->setAllowOpacity(
true );
178 mRasterStrokeColorButton->setContext( QStringLiteral(
"composer " ) );
180 mMapComboBox->setCurrentLayout( legend->
layout() );
186 mainLayout->addWidget( mItemPropertiesWidget );
188 mItemTreeView->setHeaderHidden(
true );
190 mItemTreeView->setModel( legend->
model() );
191 mItemTreeView->setMenuProvider(
new QgsLayoutLegendMenuProvider( mItemTreeView,
this ) );
192 setLegendMapViewData();
198 connect( layoutAtlas(), &
QgsLayoutAtlas::toggled,
this, &QgsLayoutLegendWidget::updateFilterLegendByAtlasButton );
202 mTitleFontButton->registerExpressionContextGenerator(
this );
203 mGroupFontButton->registerExpressionContextGenerator(
this );
204 mLayerFontButton->registerExpressionContextGenerator(
this );
205 mItemFontButton->registerExpressionContextGenerator(
this );
206 mExpressionFilterButton->registerExpressionContextGenerator(
this );
208 mTitleFontButton->setLayer( coverageLayer() );
209 mGroupFontButton->setLayer( coverageLayer() );
210 mLayerFontButton->setLayer( coverageLayer() );
211 mItemFontButton->setLayer( coverageLayer() );
212 if ( mLegend->layout() )
225 connect( mItemTreeView->selectionModel(), &QItemSelectionModel::currentChanged,
226 this, &QgsLayoutLegendWidget::selectedChanged );
235 if ( mItemPropertiesWidget )
236 mItemPropertiesWidget->setMasterLayout( masterLayout );
242 mTitleFontButton->setMessageBar( iface->
messageBar() );
243 mGroupFontButton->setMessageBar( iface->
messageBar() );
244 mLayerFontButton->setMessageBar( iface->
messageBar() );
245 mItemFontButton->setMessageBar( iface->
messageBar() );
248void QgsLayoutLegendWidget::setGuiElements()
255 blockAllSignals(
true );
256 mTitleLineEdit->setText( mLegend->title() );
257 whileBlocking( mTitleAlignCombo )->setCurrentAlignment( mLegend->titleAlignment() );
261 whileBlocking( mArrangementCombo )->setCurrentAlignment( mLegend->symbolAlignment() );
262 mFilterByMapCheckBox->setChecked( mLegend->legendFilterByMapEnabled() );
263 mButtonLinkedMaps->setEnabled( mLegend->legendFilterByMapEnabled() );
264 mColumnCountSpinBox->setValue( mLegend->columnCount() );
265 mSplitLayerCheckBox->setChecked( mLegend->splitLayer() );
266 mEqualColumnWidthCheckBox->setChecked( mLegend->equalColumnWidth() );
267 mSymbolWidthSpinBox->setValue( mLegend->symbolWidth() );
268 mSymbolHeightSpinBox->setValue( mLegend->symbolHeight() );
269 mMaxSymbolSizeSpinBox->setValue( mLegend->maximumSymbolSize() );
270 mMinSymbolSizeSpinBox->setValue( mLegend->minimumSymbolSize() );
271 mWmsLegendWidthSpinBox->setValue( mLegend->wmsLegendWidth() );
272 mWmsLegendHeightSpinBox->setValue( mLegend->wmsLegendHeight() );
286 mBoxSpaceSpinBox->setValue( mLegend->boxSpace() );
287 mColumnSpaceSpinBox->setValue( mLegend->columnSpace() );
289 mRasterStrokeGroupBox->setChecked( mLegend->drawRasterStroke() );
290 mRasterStrokeWidthSpinBox->setValue( mLegend->rasterStrokeWidth() );
291 mRasterStrokeColorButton->setColor( mLegend->rasterStrokeColor() );
293 mCheckBoxAutoUpdate->setChecked( mLegend->autoUpdateModel() );
295 mCheckboxResizeContents->setChecked( mLegend->resizeToContents() );
296 mFilterLegendByAtlasCheckBox->setChecked( mLegend->legendFilterOutAtlas() );
297 mWrapCharLineEdit->setText( mLegend->wrapString() );
300 mMapComboBox->setItem( map );
306 blockAllSignals(
false );
308 mCheckBoxAutoUpdate_stateChanged( mLegend->autoUpdateModel() ? Qt::Checked : Qt::Unchecked, false );
309 updateDataDefinedButton( mLegendTitleDDBtn );
310 updateDataDefinedButton( mColumnsDDBtn );
313void QgsLayoutLegendWidget::mWrapCharLineEdit_textChanged(
const QString &text )
317 mLegend->beginCommand( tr(
"Change Legend Wrap" ) );
318 mLegend->setWrapString( text );
319 mLegend->adjustBoxSize();
321 mLegend->endCommand();
325void QgsLayoutLegendWidget::mTitleLineEdit_textChanged(
const QString &text )
330 mLegend->setTitle( text );
331 mLegend->adjustBoxSize();
333 mLegend->endCommand();
337void QgsLayoutLegendWidget::titleAlignmentChanged()
341 Qt::AlignmentFlag alignment =
static_cast< Qt::AlignmentFlag
>(
static_cast< int >( mTitleAlignCombo->currentAlignment() & Qt::AlignHorizontal_Mask ) );
342 mLegend->beginCommand( tr(
"Change Title Alignment" ) );
343 mLegend->setTitleAlignment( alignment );
345 mLegend->endCommand();
349void QgsLayoutLegendWidget::groupAlignmentChanged()
353 mLegend->beginCommand( tr(
"Change Group Alignment" ) );
356 mLegend->endCommand();
360void QgsLayoutLegendWidget::subgroupAlignmentChanged()
364 mLegend->beginCommand( tr(
"Change Subgroup Alignment" ) );
367 mLegend->endCommand();
371void QgsLayoutLegendWidget::itemAlignmentChanged()
375 mLegend->beginCommand( tr(
"Change Item Alignment" ) );
378 mLegend->endCommand();
382void QgsLayoutLegendWidget::arrangementChanged()
386 Qt::AlignmentFlag alignment =
static_cast< Qt::AlignmentFlag
>(
static_cast< int >( mArrangementCombo->currentAlignment() & Qt::AlignHorizontal_Mask ) );
387 mLegend->beginCommand( tr(
"Change Legend Arrangement" ) );
388 mLegend->setSymbolAlignment( alignment );
390 mLegend->endCommand();
394void QgsLayoutLegendWidget::mColumnCountSpinBox_valueChanged(
int c )
399 mLegend->setColumnCount(
c );
400 mLegend->adjustBoxSize();
402 mLegend->endCommand();
404 mSplitLayerCheckBox->setEnabled(
c > 1 );
405 mEqualColumnWidthCheckBox->setEnabled(
c > 1 );
408void QgsLayoutLegendWidget::mSplitLayerCheckBox_toggled(
bool checked )
412 mLegend->beginCommand( tr(
"Split Legend Layers" ) );
413 mLegend->setSplitLayer( checked );
414 mLegend->adjustBoxSize();
416 mLegend->endCommand();
420void QgsLayoutLegendWidget::mEqualColumnWidthCheckBox_toggled(
bool checked )
424 mLegend->beginCommand( tr(
"Legend Column Width" ) );
425 mLegend->setEqualColumnWidth( checked );
426 mLegend->adjustBoxSize();
428 mLegend->endCommand();
432void QgsLayoutLegendWidget::mSymbolWidthSpinBox_valueChanged(
double d )
437 mLegend->setSymbolWidth( d );
438 mLegend->adjustBoxSize();
440 mLegend->endCommand();
444void QgsLayoutLegendWidget::mMaxSymbolSizeSpinBox_valueChanged(
double d )
449 mLegend->setMaximumSymbolSize( d );
450 mLegend->adjustBoxSize();
452 mLegend->endCommand();
456void QgsLayoutLegendWidget::mMinSymbolSizeSpinBox_valueChanged(
double d )
461 mLegend->setMinimumSymbolSize( d );
462 mLegend->adjustBoxSize();
464 mLegend->endCommand();
468void QgsLayoutLegendWidget::mSymbolHeightSpinBox_valueChanged(
double d )
473 mLegend->setSymbolHeight( d );
474 mLegend->adjustBoxSize();
476 mLegend->endCommand();
480void QgsLayoutLegendWidget::mWmsLegendWidthSpinBox_valueChanged(
double d )
485 mLegend->setWmsLegendWidth( d );
486 mLegend->adjustBoxSize();
488 mLegend->endCommand();
492void QgsLayoutLegendWidget::mWmsLegendHeightSpinBox_valueChanged(
double d )
497 mLegend->setWmsLegendHeight( d );
498 mLegend->adjustBoxSize();
500 mLegend->endCommand();
504void QgsLayoutLegendWidget::mTitleSpaceBottomSpinBox_valueChanged(
double d )
510 mLegend->adjustBoxSize();
512 mLegend->endCommand();
516void QgsLayoutLegendWidget::mGroupSpaceSpinBox_valueChanged(
double d )
522 mLegend->adjustBoxSize();
524 mLegend->endCommand();
528void QgsLayoutLegendWidget::mGroupIndentSpinBox_valueChanged(
double d )
534 mLegend->adjustBoxSize();
536 mLegend->endCommand();
540void QgsLayoutLegendWidget::mSubgroupIndentSpinBox_valueChanged(
double d )
546 mLegend->adjustBoxSize();
548 mLegend->endCommand();
552void QgsLayoutLegendWidget::spaceBelowGroupHeadingChanged(
double space )
558 mLegend->adjustBoxSize();
560 mLegend->endCommand();
564void QgsLayoutLegendWidget::spaceGroupSideChanged(
double space )
570 mLegend->adjustBoxSize();
572 mLegend->endCommand();
576void QgsLayoutLegendWidget::spaceSubGroupSideChanged(
double space )
582 mLegend->adjustBoxSize();
584 mLegend->endCommand();
588void QgsLayoutLegendWidget::spaceSymbolSideChanged(
double space )
594 mLegend->adjustBoxSize();
596 mLegend->endCommand();
600void QgsLayoutLegendWidget::mLayerSpaceSpinBox_valueChanged(
double d )
606 mLegend->adjustBoxSize();
608 mLegend->endCommand();
612void QgsLayoutLegendWidget::mSymbolSpaceSpinBox_valueChanged(
double d )
620 mLegend->adjustBoxSize();
622 mLegend->endCommand();
626void QgsLayoutLegendWidget::mIconLabelSpaceSpinBox_valueChanged(
double d )
632 mLegend->adjustBoxSize();
634 mLegend->endCommand();
638void QgsLayoutLegendWidget::titleFontChanged()
644 mLegend->adjustBoxSize();
646 mLegend->endCommand();
650void QgsLayoutLegendWidget::groupFontChanged()
656 mLegend->adjustBoxSize();
658 mLegend->endCommand();
662void QgsLayoutLegendWidget::layerFontChanged()
668 mLegend->adjustBoxSize();
670 mLegend->endCommand();
674void QgsLayoutLegendWidget::itemFontChanged()
680 mLegend->adjustBoxSize();
682 mLegend->endCommand();
686void QgsLayoutLegendWidget::spaceBelowSubGroupHeadingChanged(
double space )
692 mLegend->adjustBoxSize();
694 mLegend->endCommand();
698void QgsLayoutLegendWidget::mBoxSpaceSpinBox_valueChanged(
double d )
703 mLegend->setBoxSpace( d );
704 mLegend->adjustBoxSize();
706 mLegend->endCommand();
710void QgsLayoutLegendWidget::mColumnSpaceSpinBox_valueChanged(
double d )
715 mLegend->setColumnSpace( d );
716 mLegend->adjustBoxSize();
718 mLegend->endCommand();
722static void _moveLegendNode(
QgsLayerTreeLayer *nodeLayer,
int legendNodeIndex,
int offset )
726 if ( legendNodeIndex < 0 || legendNodeIndex >= order.count() )
728 if ( legendNodeIndex + offset < 0 || legendNodeIndex + offset >= order.count() )
731 int id = order.takeAt( legendNodeIndex );
732 order.insert( legendNodeIndex + offset,
id );
738void QgsLayoutLegendWidget::mMoveDownToolButton_clicked()
745 const QModelIndex index = mItemTreeView->selectionModel()->currentIndex();
746 const QModelIndex sourceIndex = mItemTreeView->proxyModel()->mapToSource( index );
747 const QModelIndex parentIndex = sourceIndex.parent();
748 if ( !sourceIndex.isValid() || sourceIndex.row() == mItemTreeView->layerTreeModel()->rowCount( parentIndex ) - 1 )
753 if ( !node && !legendNode )
756 mLegend->beginCommand( tr(
"Moved Legend Item Down" ) );
770 mItemTreeView->setCurrentIndex( mItemTreeView->proxyModel()->mapFromSource( mItemTreeView->layerTreeModel()->index( sourceIndex.row() + 1, 0, parentIndex ) ) );
773 mLegend->endCommand();
776void QgsLayoutLegendWidget::mMoveUpToolButton_clicked()
783 const QModelIndex index = mItemTreeView->selectionModel()->currentIndex();
784 const QModelIndex sourceIndex = mItemTreeView->proxyModel()->mapToSource( index );
785 const QModelIndex parentIndex = sourceIndex.parent();
786 if ( !sourceIndex.isValid() || sourceIndex.row() == 0 )
791 if ( !node && !legendNode )
794 mLegend->beginCommand( tr(
"Move Legend Item Up" ) );
808 mItemTreeView->setCurrentIndex( mItemTreeView->proxyModel()->mapFromSource( mItemTreeView->layerTreeModel()->index( sourceIndex.row() - 1, 0, parentIndex ) ) );
811 mLegend->endCommand();
814void QgsLayoutLegendWidget::mCheckBoxAutoUpdate_stateChanged(
int state,
bool userTriggered )
818 mLegend->beginCommand( tr(
"Change Auto Update" ) );
820 mLegend->setAutoUpdateModel( state == Qt::Checked );
822 mLegend->endCommand();
826 QList<QWidget *> widgets;
827 widgets << mMoveDownToolButton << mMoveUpToolButton << mRemoveToolButton << mAddToolButton
828 << mEditPushButton << mCountToolButton << mUpdateAllPushButton << mAddGroupToolButton
829 << mExpressionFilterButton;
830 for ( QWidget *w : std::as_const( widgets ) )
831 w->setEnabled( state != Qt::Checked );
833 if ( state == Qt::Unchecked )
836 selectedChanged( QModelIndex(), QModelIndex() );
840void QgsLayoutLegendWidget::composerMapChanged(
QgsLayoutItem *item )
856 mLegend->beginCommand( tr(
"Change Legend Map" ) );
857 mLegend->setLinkedMap( map );
859 mLegend->endCommand();
861 setLegendMapViewData();
865void QgsLayoutLegendWidget::mCheckboxResizeContents_toggled(
bool checked )
872 mLegend->beginCommand( tr(
"Resize Legend to Contents" ) );
873 mLegend->setResizeToContents( checked );
875 mLegend->adjustBoxSize();
877 mLegend->endCommand();
880void QgsLayoutLegendWidget::mRasterStrokeGroupBox_toggled(
bool state )
887 mLegend->beginCommand( tr(
"Change Legend Borders" ) );
888 mLegend->setDrawRasterStroke( state );
889 mLegend->adjustBoxSize();
891 mLegend->endCommand();
894void QgsLayoutLegendWidget::mRasterStrokeWidthSpinBox_valueChanged(
double d )
902 mLegend->setRasterStrokeWidth( d );
903 mLegend->adjustBoxSize();
905 mLegend->endCommand();
908void QgsLayoutLegendWidget::mRasterStrokeColorButton_colorChanged(
const QColor &newColor )
916 mLegend->setRasterStrokeColor( newColor );
918 mLegend->endCommand();
921void QgsLayoutLegendWidget::mAddToolButton_clicked()
928 QList< QgsMapLayer * > visibleLayers;
929 if ( mLegend->linkedMap() )
931 visibleLayers = mLegend->linkedMap()->layersToRender();
933 if ( visibleLayers.isEmpty() )
936 visibleLayers = mMapCanvas->layers(
true );
940 addDialog.setVisibleLayers( visibleLayers );
941 if ( addDialog.exec() == QDialog::Accepted )
943 const QList<QgsMapLayer *> layers = addDialog.selectedLayers();
944 if ( !layers.empty() )
946 mLegend->beginCommand( tr(
"Add Legend Item(s)" ) );
949 mLegend->model()->rootGroup()->addLayer( layer );
951 mLegend->updateLegend();
953 mLegend->endCommand();
958void QgsLayoutLegendWidget::mRemoveToolButton_clicked()
965 QItemSelectionModel *selectionModel = mItemTreeView->selectionModel();
966 if ( !selectionModel )
971 mLegend->beginCommand( tr(
"Remove Legend Item" ) );
973 QList<QPersistentModelIndex> proxyIndexes;
974 const QModelIndexList viewSelection = selectionModel->selectedIndexes();
975 for (
const QModelIndex &index : viewSelection )
976 proxyIndexes << index;
979 QHash<QgsLayerTreeLayer *, QList<int> > nodesWithRemoval;
980 for (
const QPersistentModelIndex &proxyIndex : std::as_const( proxyIndexes ) )
985 nodesWithRemoval[nodeLayer].append( _unfilteredLegendNodeIndex( legendNode ) );
988 for (
auto it = nodesWithRemoval.constBegin(); it != nodesWithRemoval.constEnd(); ++it )
990 QList<int> toDelete = it.value();
991 std::sort( toDelete.begin(), toDelete.end(), std::greater<int>() );
994 for (
int i : std::as_const( toDelete ) )
996 if ( i >= 0 && i < order.count() )
1001 mItemTreeView->layerTreeModel()->refreshLayerLegend( it.key() );
1005 for (
const QPersistentModelIndex &proxyIndex : std::as_const( proxyIndexes ) )
1007 if ( proxyIndex.isValid() && mItemTreeView->index2node( proxyIndex ) )
1009 const QModelIndex sourceIndex = mItemTreeView->proxyModel()->mapToSource( proxyIndex );
1010 mLegend->model()->removeRow( sourceIndex.row(), sourceIndex.parent() );
1014 mLegend->updateLegend();
1016 mLegend->endCommand();
1019void QgsLayoutLegendWidget::mEditPushButton_clicked()
1026 QModelIndex idx = mItemTreeView->selectionModel()->currentIndex();
1027 mItemTreeView_doubleClicked( idx );
1030void QgsLayoutLegendWidget::resetLayerNodeToDefaults()
1038 QModelIndex currentIndex = mItemTreeView->currentIndex();
1039 if ( !currentIndex.isValid() )
1058 mLegend->beginCommand( tr(
"Update Legend" ) );
1061 for (
const QString &key : constCustomProperties )
1063 if ( key.startsWith( QLatin1String(
"legend/" ) ) )
1070 mItemTreeView->layerTreeModel()->refreshLayerLegend( nodeLayer );
1072 mLegend->updateLegend();
1074 mLegend->endCommand();
1077void QgsLayoutLegendWidget::mCountToolButton_clicked(
bool checked )
1084 const QList< QModelIndex > selectedIndexes = mItemTreeView->selectionModel()->selectedIndexes();
1085 if ( selectedIndexes.empty() )
1088 mLegend->beginCommand( tr(
"Update Legend" ) );
1089 for (
const QModelIndex &index : selectedIndexes )
1095 currentNode->
setCustomProperty( QStringLiteral(
"showFeatureCount" ), checked ? 1 : 0 );
1097 mLegend->updateFilterByMap();
1098 mLegend->adjustBoxSize();
1099 mLegend->endCommand();
1102void QgsLayoutLegendWidget::mFilterByMapCheckBox_toggled(
bool checked )
1104 mLegend->beginCommand( tr(
"Update Legend" ) );
1105 mLegend->setLegendFilterByMapEnabled( checked );
1106 mLegend->adjustBoxSize();
1108 mLegend->endCommand();
1111void QgsLayoutLegendWidget::mExpressionFilterButton_toggled(
bool checked )
1119 QModelIndex currentIndex = mItemTreeView->currentIndex();
1120 if ( !currentIndex.isValid() )
1130 mExpressionFilterButton->expressionText(),
1133 mLegend->beginCommand( tr(
"Update Legend" ) );
1134 mLegend->updateFilterByMap();
1135 mLegend->adjustBoxSize();
1136 mLegend->endCommand();
1139void QgsLayoutLegendWidget::mLayerExpressionButton_clicked()
1146 QModelIndex currentIndex = mItemTreeView->currentIndex();
1147 if ( !currentIndex.isValid() )
1154 QgsLayerTreeLayer *layerNode = qobject_cast<QgsLayerTreeLayer *>( currentNode );
1160 QString currentExpression;
1162 currentExpression = QStringLiteral(
"@symbol_label" );
1172 QStringList highlighted;
1177 if ( !legendSymbols.empty() )
1183 highlighted << QStringLiteral(
"symbol_label" ) << QStringLiteral(
"symbol_id" );
1185 highlighted << QStringLiteral(
"symbol_count" );
1199 QgsExpressionBuilderDialog expressiondialog(
nullptr, currentExpression,
nullptr, QStringLiteral(
"generic" ), legendContext );
1200 if ( expressiondialog.exec() )
1203 mLegend->beginCommand( tr(
"Update Legend" ) );
1205 mLegend->adjustBoxSize();
1206 mLegend->endCommand();
1209void QgsLayoutLegendWidget::mUpdateAllPushButton_clicked()
1214void QgsLayoutLegendWidget::mAddGroupToolButton_clicked()
1218 mLegend->beginCommand( tr(
"Add Legend Group" ) );
1219 mLegend->model()->rootGroup()->addGroup( tr(
"Group" ) );
1220 mLegend->updateLegend();
1222 mLegend->endCommand();
1226void QgsLayoutLegendWidget::mFilterLegendByAtlasCheckBox_toggled(
bool toggled )
1231 mLegend->setLegendFilterOutAtlas( toggled );
1237void QgsLayoutLegendWidget::updateLegend()
1241 mLegend->beginCommand( tr(
"Update Legend" ) );
1244 mLegend->setAutoUpdateModel(
true );
1245 mLegend->setAutoUpdateModel(
false );
1247 mLegend->endCommand();
1251void QgsLayoutLegendWidget::setReportTypeString(
const QString &
string )
1253 mFilterLegendByAtlasCheckBox->setText( tr(
"Only show items inside current %1 feature" ).arg(
string ) );
1254 mFilterLegendByAtlasCheckBox->setToolTip( tr(
"Filter out legend elements that lie outside the current %1 feature." ).arg(
string ) );
1263bool QgsLayoutLegendWidget::setNewItem(
QgsLayoutItem *item )
1273 mLegend = qobject_cast< QgsLayoutItemLegend * >( item );
1274 mItemPropertiesWidget->setItem( mLegend );
1276 if ( mMapFilteringWidget )
1277 mMapFilteringWidget->setItem( mLegend );
1281 mItemTreeView->setModel( mLegend->model() );
1290void QgsLayoutLegendWidget::blockAllSignals(
bool b )
1292 mTitleLineEdit->blockSignals( b );
1293 mTitleAlignCombo->blockSignals( b );
1294 mItemTreeView->blockSignals( b );
1295 mCheckBoxAutoUpdate->blockSignals( b );
1296 mMapComboBox->blockSignals( b );
1297 mFilterByMapCheckBox->blockSignals( b );
1298 mColumnCountSpinBox->blockSignals( b );
1299 mSplitLayerCheckBox->blockSignals( b );
1300 mEqualColumnWidthCheckBox->blockSignals( b );
1301 mSymbolWidthSpinBox->blockSignals( b );
1302 mSymbolHeightSpinBox->blockSignals( b );
1303 mMaxSymbolSizeSpinBox->blockSignals( b );
1304 mMinSymbolSizeSpinBox->blockSignals( b );
1305 mGroupSpaceSpinBox->blockSignals( b );
1306 mGroupIndentSpinBox->blockSignals( b );
1307 mSubgroupIndentSpinBox->blockSignals( b );
1308 mSpaceBelowGroupHeadingSpinBox->blockSignals( b );
1309 mGroupSideSpinBox->blockSignals( b );
1310 mSpaceBelowSubgroupHeadingSpinBox->blockSignals( b );
1311 mSubgroupSideSpinBox->blockSignals( b );
1312 mLayerSpaceSpinBox->blockSignals( b );
1313 mSymbolSpaceSpinBox->blockSignals( b );
1314 mSymbolSideSpaceSpinBox->blockSignals( b );
1315 mIconLabelSpaceSpinBox->blockSignals( b );
1316 mBoxSpaceSpinBox->blockSignals( b );
1317 mColumnSpaceSpinBox->blockSignals( b );
1318 mRasterStrokeGroupBox->blockSignals( b );
1319 mRasterStrokeColorButton->blockSignals( b );
1320 mRasterStrokeWidthSpinBox->blockSignals( b );
1321 mWmsLegendWidthSpinBox->blockSignals( b );
1322 mWmsLegendHeightSpinBox->blockSignals( b );
1323 mCheckboxResizeContents->blockSignals( b );
1324 mTitleSpaceBottomSpinBox->blockSignals( b );
1325 mFilterLegendByAtlasCheckBox->blockSignals( b );
1326 mTitleFontButton->blockSignals( b );
1327 mGroupFontButton->blockSignals( b );
1328 mLayerFontButton->blockSignals( b );
1329 mItemFontButton->blockSignals( b );
1330 mWrapCharLineEdit->blockSignals( b );
1333void QgsLayoutLegendWidget::selectedChanged(
const QModelIndex ¤t,
const QModelIndex &previous )
1336 Q_UNUSED( previous )
1338 mLayerExpressionButton->setEnabled(
false );
1340 if ( mLegend && mLegend->autoUpdateModel() )
1351 mLayerExpressionButton->setEnabled(
true );
1355 mCountToolButton->setChecked(
false );
1356 mCountToolButton->setEnabled(
false );
1359 mExpressionFilterButton->blockSignals(
true );
1360 mExpressionFilterButton->setChecked(
false );
1361 mExpressionFilterButton->setEnabled(
false );
1362 mExpressionFilterButton->blockSignals(
false );
1373 mCountToolButton->setChecked( currentNode->
customProperty( QStringLiteral(
"showFeatureCount" ), 0 ).toInt() );
1374 mCountToolButton->setEnabled(
true );
1375 mLayerExpressionButton->setEnabled(
true );
1379 mExpressionFilterButton->blockSignals(
true );
1380 mExpressionFilterButton->setExpressionText( expr );
1381 mExpressionFilterButton->setVectorLayer( vl );
1382 mExpressionFilterButton->setEnabled(
true );
1383 mExpressionFilterButton->setChecked( exprEnabled );
1384 mExpressionFilterButton->blockSignals(
false );
1387void QgsLayoutLegendWidget::setCurrentNodeStyleFromAction()
1389 QAction *a = qobject_cast<QAction *>( sender() );
1390 if ( !a || !mItemTreeView->currentNode() )
1397void QgsLayoutLegendWidget::setLegendMapViewData()
1399 if ( mLegend->linkedMap() )
1403 measurementConverter.
setDpi( dpi );
1406 double mapUnitsPerPixelX = mLegend->linkedMap()->extent().width() / mapWidth;
1407 double mapUnitsPerPixelY = mLegend->linkedMap()->extent().height() / mapHeight;
1408 mLegend->model()->setLegendMapViewData( ( mapUnitsPerPixelX > mapUnitsPerPixelY ? mapUnitsPerPixelX : mapUnitsPerPixelY ), dpi, mLegend->linkedMap()->scale() );
1412void QgsLayoutLegendWidget::updateFilterLegendByAtlasButton()
1416 mFilterLegendByAtlasCheckBox->setEnabled( atlas->enabled() && mLegend->layout()->reportContext().layer() && mLegend->layout()->reportContext().layer()->geometryType() ==
Qgis::GeometryType::Polygon );
1420void QgsLayoutLegendWidget::mItemTreeView_doubleClicked(
const QModelIndex &idx )
1422 if ( !mLegend || !idx.isValid() )
1427 if ( mLegend->autoUpdateModel() )
1433 int originalIndex = -1;
1436 originalIndex = _originalLegendNodeIndex( legendNode );
1440 QgsLayoutLegendNodeWidget *widget =
new QgsLayoutLegendNodeWidget( mLegend, currentNode, legendNode, originalIndex );
1441 openPanel( widget );
1449QgsLayoutLegendMenuProvider::QgsLayoutLegendMenuProvider(
QgsLayerTreeView *view, QgsLayoutLegendWidget *w )
1454QMenu *QgsLayoutLegendMenuProvider::createContextMenu()
1456 if ( !mView->currentNode() )
1459 if ( mWidget->legend()->autoUpdateModel() )
1462 QMenu *menu =
new QMenu();
1466 menu->addAction( QObject::tr(
"Reset to Defaults" ), mWidget, &QgsLayoutLegendWidget::resetLayerNodeToDefaults );
1467 menu->addSeparator();
1472 QList<QgsLegendStyle::Style> lst;
1476 QAction *action = menu->addAction(
QgsLegendStyle::styleLabel( style ), mWidget, &QgsLayoutLegendWidget::setCurrentNodeStyleFromAction );
1477 action->setCheckable(
true );
1478 action->setChecked( currentStyle == style );
1479 action->setData(
static_cast< int >( style ) );
1494 , mOriginalLegendNodeIndex( originalLegendNodeIndex )
1497 setPanelTitle( tr(
"Legend Item Properties" ) );
1506 QString currentLabel;
1509 currentLabel = mLegendNode->data( Qt::EditRole ).toString();
1510 mColumnBreakBeforeCheckBox->setChecked( mLegendNode->columnBreak() );
1514 currentLabel = mLayer->name();
1515 QVariant v = mLayer->customProperty( QStringLiteral(
"legend/title-label" ) );
1517 currentLabel = v.toString();
1518 mColumnBreakBeforeCheckBox->setChecked( mLayer->customProperty( QStringLiteral(
"legend/column-break" ) ).toInt() );
1520 mColumnSplitBehaviorComboBox->setCurrentIndex( mColumnSplitBehaviorComboBox->findData( mLayer->legendSplitBehavior() ) );
1525 mColumnBreakBeforeCheckBox->setChecked( mNode->customProperty( QStringLiteral(
"legend/column-break" ) ).toInt() );
1528 mWidthSpinBox->setClearValue( 0, tr(
"Default" ) );
1529 mHeightSpinBox->setClearValue( 0, tr(
"Default" ) );
1530 mWidthSpinBox->setVisible( mLegendNode || mLayer );
1531 mHeightSpinBox->setVisible( mLegendNode || mLayer );
1532 mPatchGroup->setVisible( mLegendNode || mLayer );
1533 mPatchWidthLabel->setVisible( mLegendNode || mLayer );
1534 mPatchHeightLabel->setVisible( mLegendNode || mLayer );
1535 mCustomSymbolCheckBox->setVisible( mLegendNode || mLegend->model()->legendNodeEmbeddedInParent( mLayer ) );
1536 mColumnSplitLabel->setVisible( mLayer && !mLegendNode );
1537 mColumnSplitBehaviorComboBox->setVisible( mLayer && !mLegendNode );
1540 mWidthSpinBox->setValue( mLegendNode->userPatchSize().width() );
1541 mHeightSpinBox->setValue( mLegendNode->userPatchSize().height() );
1545 mWidthSpinBox->setValue( mLayer->patchSize().width() );
1546 mHeightSpinBox->setValue( mLayer->patchSize().height() );
1549 mCustomSymbolCheckBox->setChecked(
false );
1554 patchShape = symbolLegendNode->patchShape();
1556 std::unique_ptr< QgsSymbol > customSymbol( symbolLegendNode->customSymbol() ? symbolLegendNode->customSymbol()->clone() : nullptr );
1557 mCustomSymbolCheckBox->setChecked( customSymbol.get() );
1560 mPatchShapeButton->setPreviewSymbol( customSymbol->clone() );
1562 mCustomSymbolButton->setSymbol( customSymbol.release() );
1564 else if ( symbolLegendNode->symbol() )
1566 mPatchShapeButton->setPreviewSymbol( symbolLegendNode->symbol()->clone() );
1567 mCustomSymbolButton->setSymbolType( symbolLegendNode->symbol()->type() );
1568 mCustomSymbolButton->setSymbol( symbolLegendNode->symbol()->clone() );
1571 else if ( !mLegendNode && mLayer )
1573 patchShape = mLayer->patchShape();
1576 if (
QgsSymbol *customSymbol = symbolLegendNode->customSymbol() )
1578 mCustomSymbolCheckBox->setChecked(
true );
1579 mPatchShapeButton->setPreviewSymbol( customSymbol->clone() );
1581 mCustomSymbolButton->setSymbol( customSymbol->clone() );
1585 mPatchShapeButton->setPreviewSymbol( symbolLegendNode->symbol()->clone() );
1586 mCustomSymbolButton->setSymbolType( symbolLegendNode->symbol()->type() );
1587 mCustomSymbolButton->setSymbol( symbolLegendNode->symbol()->clone() );
1594 switch ( qobject_cast< QgsVectorLayer * >( mLayer->layer() )->geometryType() )
1609 mPatchShapeLabel->hide();
1610 mPatchShapeButton->hide();
1613 if ( !patchShape.
isNull() )
1614 mPatchShapeButton->setShape( patchShape );
1619 if ( symbolLegendNode->symbol() )
1621 mPatchShapeButton->setSymbolType( symbolLegendNode->symbol()->type() );
1625 mPatchShapeLabel->hide();
1626 mPatchShapeButton->hide();
1631 mPatchShapeLabel->hide();
1632 mPatchShapeButton->hide();
1637 mLabelGroup->hide();
1638 mColorRampLegendWidget->setSettings( colorRampNode->settings() );
1642 mColorRampLegendWidget->hide();
1655 mCustomSymbolCheckBox->hide();
1664 mLabelEdit->setPlainText( currentLabel );
1665 connect( mLabelEdit, &QPlainTextEdit::textChanged,
this, &QgsLayoutLegendNodeWidget::labelChanged );
1667 connect( mInsertExpressionButton, &QPushButton::clicked,
this, &QgsLayoutLegendNodeWidget::insertExpression );
1669 connect( mWidthSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendNodeWidget::sizeChanged );
1670 connect( mHeightSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendNodeWidget::sizeChanged );
1672 connect( mCustomSymbolCheckBox, &QGroupBox::toggled,
this, &QgsLayoutLegendNodeWidget::customSymbolChanged );
1675 connect( mColumnBreakBeforeCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendNodeWidget::columnBreakToggled );
1677 connect( mColumnSplitBehaviorComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsLayoutLegendNodeWidget::columnSplitChanged );
1681 connectChildPanel( mColorRampLegendWidget );
1684void QgsLayoutLegendNodeWidget::setDockMode(
bool dockMode )
1686 mColorRampLegendWidget->setDockMode( dockMode );
1690void QgsLayoutLegendNodeWidget::labelChanged()
1694 const QString label = mLabelEdit->toPlainText();
1699 else if ( mLegendNode )
1702 mLegend->model()->refreshLayerLegend( mLayer );
1706 mLayer->setCustomProperty( QStringLiteral(
"legend/title-label" ), label );
1710 embeddedNode->setUserLabel( QString() );
1713 mLegend->adjustBoxSize();
1714 mLegend->invalidateCache();
1716 mLegend->endCommand();
1719void QgsLayoutLegendNodeWidget::patchChanged()
1721 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1727 mLegend->model()->refreshLayerLegend( mLayer );
1731 mLayer->setPatchShape( shape );
1732 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1737 mLegend->model()->refreshLayerLegend( mLayer );
1740 mLegend->adjustBoxSize();
1742 mLegend->endCommand();
1745void QgsLayoutLegendNodeWidget::insertExpression()
1750 QString selText = mLabelEdit->textCursor().selectedText();
1753 selText = selText.replace( QChar( 0x2029 ), QChar(
'\n' ) );
1756 if ( selText.startsWith( QLatin1String(
"[%" ) ) && selText.endsWith( QLatin1String(
"%]" ) ) )
1757 selText = selText.mid( 2, selText.size() - 4 );
1760 QgsVectorLayer *layer = mLegend->layout() ? mLegend->layout()->reportContext().layer() :
nullptr;
1764 if ( mLayer && mLayer->layer() )
1770 << QStringLiteral(
"legend_column_count" )
1771 << QStringLiteral(
"legend_split_layers" )
1772 << QStringLiteral(
"legend_wrap_string" )
1773 << QStringLiteral(
"legend_filter_by_map" )
1774 << QStringLiteral(
"legend_filter_out_atlas" ) );
1778 exprDlg.setWindowTitle( tr(
"Insert Expression" ) );
1779 if ( exprDlg.exec() == QDialog::Accepted )
1781 QString expression = exprDlg.expressionText();
1782 if ( !expression.isEmpty() )
1784 mLegend->beginCommand( tr(
"Insert expression" ) );
1785 mLabelEdit->insertPlainText(
"[%" + expression +
"%]" );
1786 mLegend->endCommand();
1791void QgsLayoutLegendNodeWidget::sizeChanged(
double )
1793 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1794 const QSizeF size = QSizeF( mWidthSpinBox->value(), mHeightSpinBox->value() );
1799 mLegend->model()->refreshLayerLegend( mLayer );
1803 mLayer->setPatchSize( size );
1804 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1809 mLegend->model()->refreshLayerLegend( mLayer );
1812 mLegend->adjustBoxSize();
1814 mLegend->endCommand();
1817void QgsLayoutLegendNodeWidget::customSymbolChanged()
1819 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1821 if ( mCustomSymbolCheckBox->isChecked() )
1826 mLegend->model()->refreshLayerLegend( mLayer );
1830 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1835 mLegend->model()->refreshLayerLegend( mLayer );
1843 mLegend->model()->refreshLayerLegend( mLayer );
1847 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1852 mLegend->model()->refreshLayerLegend( mLayer );
1856 mLegend->adjustBoxSize();
1858 mLegend->endCommand();
1861void QgsLayoutLegendNodeWidget::colorRampLegendChanged()
1863 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1867 mLegend->model()->refreshLayerLegend( mLayer );
1869 mLegend->adjustBoxSize();
1871 mLegend->endCommand();
1874void QgsLayoutLegendNodeWidget::columnBreakToggled(
bool checked )
1876 mLegend->beginCommand( tr(
"Edit Legend Columns" ) );
1881 mLegend->model()->refreshLayerLegend( mLayer );
1885 mLayer->setCustomProperty( QStringLiteral(
"legend/column-break" ), QString( checked ?
'1' :
'0' ) );
1889 mNode->setCustomProperty( QStringLiteral(
"legend/column-break" ), QString( checked ?
'1' :
'0' ) );
1892 mLegend->adjustBoxSize();
1894 mLegend->endCommand();
1897void QgsLayoutLegendNodeWidget::columnSplitChanged()
1899 mLegend->beginCommand( tr(
"Edit Legend Columns" ) );
1901 if ( mLayer && !mLegendNode )
1906 mLegend->adjustBoxSize();
1908 mLegend->endCommand();
1915QgsLayoutLegendMapFilteringWidget::QgsLayoutLegendMapFilteringWidget(
QgsLayoutItemLegend *legend )
1917 , mLegendItem( legend )
1920 setPanelTitle( tr(
"Legend Filtering" ) );
1922 setNewItem( legend );
1925bool QgsLayoutLegendMapFilteringWidget::setNewItem(
QgsLayoutItem *item )
1935 mLegendItem = qobject_cast< QgsLayoutItemLegend * >( item );
1942 updateGuiElements();
1947void QgsLayoutLegendMapFilteringWidget::updateGuiElements()
1949 if ( mBlockUpdates )
1952 mBlockUpdates =
true;
1954 if ( mFilterMapItemsListView->model() )
1956 QAbstractItemModel *oldModel = mFilterMapItemsListView->model();
1957 mFilterMapItemsListView->setModel(
nullptr );
1958 oldModel->deleteLater();
1961 QgsLayoutLegendMapFilteringModel *model =
new QgsLayoutLegendMapFilteringModel( mLegendItem, mLegendItem->layout()->itemsModel(), mFilterMapItemsListView );
1962 mFilterMapItemsListView->setModel( model );
1964 mBlockUpdates =
false;
1972 : QSortFilterProxyModel( parent )
1973 , mLayoutModel( layoutModel )
1974 , mLegendItem( legend )
1976 setSourceModel( layoutModel );
1979int QgsLayoutLegendMapFilteringModel::columnCount(
const QModelIndex & )
const
1984QVariant QgsLayoutLegendMapFilteringModel::data(
const QModelIndex &i,
int role )
const
1989 if ( i.column() != 0 )
1994 QgsLayoutItemMap *mapItem = qobject_cast< QgsLayoutItemMap * >( mLayoutModel->itemFromIndex( mapToSource( i ) ) );
2002 case Qt::CheckStateRole:
2003 switch ( i.column() )
2008 return Qt::Unchecked;
2010 return mLegendItem->filterByMapItems().contains( mapItem ) ? Qt::Checked : Qt::Unchecked;
2018 return mLayoutModel->data( sourceIndex, role );
2022bool QgsLayoutLegendMapFilteringModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
2026 if ( !index.isValid() )
2029 QgsLayoutItemMap *mapItem = qobject_cast< QgsLayoutItemMap * >( mLayoutModel->itemFromIndex( mapToSource( index ) ) );
2030 if ( !mapItem || !mLegendItem )
2035 mLegendItem->layout()->undoStack()->beginCommand( mLegendItem, tr(
"Change Legend Linked Maps" ) );
2037 QList< QgsLayoutItemMap * > linkedMaps = mLegendItem->filterByMapItems();
2038 if ( value.toBool() )
2040 if ( !linkedMaps.contains( mapItem ) )
2042 linkedMaps.append( mapItem );
2043 mLegendItem->setFilterByMapItems( linkedMaps );
2048 linkedMaps.removeAll( mapItem );
2049 mLegendItem->setFilterByMapItems( linkedMaps );
2051 emit dataChanged( index, index, QVector<int>() << role );
2053 mLegendItem->layout()->undoStack()->endCommand();
2054 mLegendItem->invalidateCache();
2059Qt::ItemFlags QgsLayoutLegendMapFilteringModel::flags(
const QModelIndex &index )
const
2061 Qt::ItemFlags flags = QSortFilterProxyModel::flags( index );
2063 if ( ! index.isValid() )
2068 QgsLayoutItemMap *mapItem = qobject_cast< QgsLayoutItemMap * >( mLayoutModel->itemFromIndex( mapToSource( index ) ) );
2069 const bool isMainLinkedMapItem = mLegendItem ? ( mLegendItem->linkedMap() == mapItem ) : false;
2075 if ( !isMainLinkedMapItem )
2077 flags |= Qt::ItemIsEnabled;
2081 flags &= ~Qt::ItemIsEnabled;
2084 switch ( index.column() )
2087 if ( !isMainLinkedMapItem )
2088 return flags | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
2090 return flags | Qt::ItemIsSelectable;
2093 return flags | Qt::ItemIsSelectable;
2097bool QgsLayoutLegendMapFilteringModel::filterAcceptsRow(
int source_row,
const QModelIndex &source_parent )
const
2099 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.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context 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.
virtual QgsLegendSymbolList legendSymbolItems() const
Returns a list of symbology items for the legend.
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.
@ NodeTypeRole
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 ...
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)
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...
long long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
QgsFeatureRenderer * renderer()
Returns the feature renderer used for rendering the features in the layer in 2D map views.
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.
QList< QgsLegendSymbolItem > QgsLegendSymbolList
Q_GUI_EXPORT int qt_defaultDpiX()
Single variable definition for use within a QgsExpressionContextScope.