48#include <QInputDialog>
65 int unfilteredNodeIndex = _unfilteredLegendNodeIndex(
legendNode );
67 return ( unfilteredNodeIndex >= 0 && unfilteredNodeIndex < order.count() ? order[unfilteredNodeIndex] : -1 );
74 , mMapCanvas( mapCanvas )
79 connect( mWrapCharLineEdit, &QLineEdit::textChanged,
this, &QgsLayoutLegendWidget::mWrapCharLineEdit_textChanged );
80 connect( mTitleLineEdit, &QLineEdit::textChanged,
this, &QgsLayoutLegendWidget::mTitleLineEdit_textChanged );
85 connect( mColumnCountSpinBox,
static_cast < void ( QSpinBox::* )(
int )
> ( &QSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mColumnCountSpinBox_valueChanged );
86 connect( mSplitLayerCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mSplitLayerCheckBox_toggled );
87 connect( mEqualColumnWidthCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mEqualColumnWidthCheckBox_toggled );
88 connect( mSymbolWidthSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mSymbolWidthSpinBox_valueChanged );
89 connect( mSymbolHeightSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mSymbolHeightSpinBox_valueChanged );
90 connect( mMaxSymbolSizeSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mMaxSymbolSizeSpinBox_valueChanged );
91 connect( mMinSymbolSizeSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mMinSymbolSizeSpinBox_valueChanged );
92 connect( mWmsLegendWidthSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mWmsLegendWidthSpinBox_valueChanged );
93 connect( mWmsLegendHeightSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mWmsLegendHeightSpinBox_valueChanged );
94 connect( mTitleSpaceBottomSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mTitleSpaceBottomSpinBox_valueChanged );
95 connect( mGroupSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mGroupSpaceSpinBox_valueChanged );
96 connect( mGroupIndentSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mGroupIndentSpinBox_valueChanged );
97 connect( mSubgroupIndentSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mSubgroupIndentSpinBox_valueChanged );
98 connect( mSpaceBelowGroupHeadingSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceBelowGroupHeadingChanged );
99 connect( mGroupSideSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceGroupSideChanged );
100 connect( mLayerSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mLayerSpaceSpinBox_valueChanged );
101 connect( mSpaceBelowSubgroupHeadingSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceBelowSubGroupHeadingChanged );
102 connect( mSubgroupSideSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceSubGroupSideChanged );
103 connect( mSymbolSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mSymbolSpaceSpinBox_valueChanged );
104 connect( mSymbolSideSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceSymbolSideChanged );
105 connect( mIconLabelSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mIconLabelSpaceSpinBox_valueChanged );
106 connect( mBoxSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mBoxSpaceSpinBox_valueChanged );
107 connect( mColumnSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mColumnSpaceSpinBox_valueChanged );
108 connect( mCheckBoxAutoUpdate, &QCheckBox::stateChanged,
this, [ = ](
int state ) { mCheckBoxAutoUpdate_stateChanged( state ); } );
109 connect( mCheckboxResizeContents, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mCheckboxResizeContents_toggled );
110 connect( mRasterStrokeGroupBox, &QgsCollapsibleGroupBoxBasic::toggled,
this, &QgsLayoutLegendWidget::mRasterStrokeGroupBox_toggled );
111 connect( mRasterStrokeWidthSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mRasterStrokeWidthSpinBox_valueChanged );
112 connect( mRasterStrokeColorButton, &
QgsColorButton::colorChanged,
this, &QgsLayoutLegendWidget::mRasterStrokeColorButton_colorChanged );
113 connect( mExpandAllToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::expandLegendTree );
114 connect( mCollapseAllToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::collapseLegendTree );
115 connect( mMoveDownToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mMoveDownToolButton_clicked );
116 connect( mMoveUpToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mMoveUpToolButton_clicked );
117 connect( mRemoveToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mRemoveToolButton_clicked );
118 connect( mAddToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mAddToolButton_clicked );
119 connect( mEditPushButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mEditPushButton_clicked );
120 connect( mCountToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mCountToolButton_clicked );
121 connect( mExpressionFilterButton, &QgsLegendFilterButton::toggled,
this, &QgsLayoutLegendWidget::mExpressionFilterButton_toggled );
122 connect( mLayerExpressionButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mLayerExpressionButton_clicked );
123 connect( mFilterByMapCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mFilterByMapCheckBox_toggled );
124 connect( mUpdateAllPushButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mUpdateAllPushButton_clicked );
125 connect( mAddGroupToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mAddGroupToolButton_clicked );
126 connect( mFilterLegendByAtlasCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mFilterLegendByAtlasCheckBox_toggled );
127 connect( mItemTreeView, &QgsLayerTreeView::doubleClicked,
this, &QgsLayoutLegendWidget::mItemTreeView_doubleClicked );
129 connect( mFilterByMapCheckBox, &QCheckBox::toggled, mButtonLinkedMaps, &QWidget::setEnabled );
130 mButtonLinkedMaps->setEnabled(
false );
131 connect( mButtonLinkedMaps, &QToolButton::clicked,
this, [ = ]
133 mMapFilteringWidget =
new QgsLayoutLegendMapFilteringWidget( mLegend );
134 openPanel( mMapFilteringWidget );
137 setPanelTitle( tr(
"Legend Properties" ) );
144 mTitleAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
145 mGroupAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
146 mSubgroupAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
147 mItemAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
149 mArrangementCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignRight );
151 mArrangementCombo->customizeAlignmentDisplay( Qt::AlignLeft, tr(
"Symbols on Left" ),
QgsApplication::getThemeIcon( QStringLiteral(
"/mIconArrangeSymbolsLeft.svg" ) ) );
152 mArrangementCombo->customizeAlignmentDisplay( Qt::AlignRight, tr(
"Symbols on Right" ),
QgsApplication::getThemeIcon( QStringLiteral(
"/mIconArrangeSymbolsRight.svg" ) ) );
154 mSpaceBelowGroupHeadingSpinBox->setClearValue( 0 );
155 mGroupSideSpinBox->setClearValue( 0 );
156 mSpaceBelowSubgroupHeadingSpinBox->setClearValue( 0 );
157 mSubgroupSideSpinBox->setClearValue( 0 );
158 mSymbolSideSpaceSpinBox->setClearValue( 0 );
183 mRasterStrokeColorButton->setColorDialogTitle( tr(
"Select Stroke Color" ) );
184 mRasterStrokeColorButton->setAllowOpacity(
true );
185 mRasterStrokeColorButton->setContext( QStringLiteral(
"composer " ) );
187 mMapComboBox->setCurrentLayout( legend->
layout() );
193 mainLayout->addWidget( mItemPropertiesWidget );
195 mItemTreeView->setHeaderHidden(
true );
197 mItemTreeView->setModel( legend->
model() );
198 mItemTreeView->setMenuProvider(
new QgsLayoutLegendMenuProvider( mItemTreeView,
this ) );
199 setLegendMapViewData();
205 connect( layoutAtlas(), &
QgsLayoutAtlas::toggled,
this, &QgsLayoutLegendWidget::updateFilterLegendByAtlasButton );
209 mTitleFontButton->registerExpressionContextGenerator(
this );
210 mGroupFontButton->registerExpressionContextGenerator(
this );
211 mLayerFontButton->registerExpressionContextGenerator(
this );
212 mItemFontButton->registerExpressionContextGenerator(
this );
213 mExpressionFilterButton->registerExpressionContextGenerator(
this );
215 mTitleFontButton->setLayer( coverageLayer() );
216 mGroupFontButton->setLayer( coverageLayer() );
217 mLayerFontButton->setLayer( coverageLayer() );
218 mItemFontButton->setLayer( coverageLayer() );
219 if ( mLegend->layout() )
232 connect( mItemTreeView->selectionModel(), &QItemSelectionModel::currentChanged,
233 this, &QgsLayoutLegendWidget::selectedChanged );
242 if ( mItemPropertiesWidget )
243 mItemPropertiesWidget->setMasterLayout( masterLayout );
249 mTitleFontButton->setMessageBar( iface->
messageBar() );
250 mGroupFontButton->setMessageBar( iface->
messageBar() );
251 mLayerFontButton->setMessageBar( iface->
messageBar() );
252 mItemFontButton->setMessageBar( iface->
messageBar() );
255void QgsLayoutLegendWidget::setGuiElements()
262 blockAllSignals(
true );
263 mTitleLineEdit->setText( mLegend->title() );
264 whileBlocking( mTitleAlignCombo )->setCurrentAlignment( mLegend->titleAlignment() );
268 whileBlocking( mArrangementCombo )->setCurrentAlignment( mLegend->symbolAlignment() );
269 mFilterByMapCheckBox->setChecked( mLegend->legendFilterByMapEnabled() );
270 mButtonLinkedMaps->setEnabled( mLegend->legendFilterByMapEnabled() );
271 mColumnCountSpinBox->setValue( mLegend->columnCount() );
272 mSplitLayerCheckBox->setChecked( mLegend->splitLayer() );
273 mEqualColumnWidthCheckBox->setChecked( mLegend->equalColumnWidth() );
274 mSymbolWidthSpinBox->setValue( mLegend->symbolWidth() );
275 mSymbolHeightSpinBox->setValue( mLegend->symbolHeight() );
276 mMaxSymbolSizeSpinBox->setValue( mLegend->maximumSymbolSize() );
277 mMinSymbolSizeSpinBox->setValue( mLegend->minimumSymbolSize() );
278 mWmsLegendWidthSpinBox->setValue( mLegend->wmsLegendWidth() );
279 mWmsLegendHeightSpinBox->setValue( mLegend->wmsLegendHeight() );
293 mBoxSpaceSpinBox->setValue( mLegend->boxSpace() );
294 mColumnSpaceSpinBox->setValue( mLegend->columnSpace() );
296 mRasterStrokeGroupBox->setChecked( mLegend->drawRasterStroke() );
297 mRasterStrokeWidthSpinBox->setValue( mLegend->rasterStrokeWidth() );
298 mRasterStrokeColorButton->setColor( mLegend->rasterStrokeColor() );
300 mCheckBoxAutoUpdate->setChecked( mLegend->autoUpdateModel() );
302 mCheckboxResizeContents->setChecked( mLegend->resizeToContents() );
303 mFilterLegendByAtlasCheckBox->setChecked( mLegend->legendFilterOutAtlas() );
304 mWrapCharLineEdit->setText( mLegend->wrapString() );
307 mMapComboBox->setItem( map );
313 blockAllSignals(
false );
315 mCheckBoxAutoUpdate_stateChanged( mLegend->autoUpdateModel() ? Qt::Checked : Qt::Unchecked,
false );
316 updateDataDefinedButton( mLegendTitleDDBtn );
317 updateDataDefinedButton( mColumnsDDBtn );
320void QgsLayoutLegendWidget::mWrapCharLineEdit_textChanged(
const QString &text )
324 mLegend->beginCommand( tr(
"Change Legend Wrap" ) );
325 mLegend->setWrapString( text );
326 mLegend->adjustBoxSize();
328 mLegend->endCommand();
332void QgsLayoutLegendWidget::mTitleLineEdit_textChanged(
const QString &text )
337 mLegend->setTitle( text );
338 mLegend->adjustBoxSize();
340 mLegend->endCommand();
344void QgsLayoutLegendWidget::titleAlignmentChanged()
348 Qt::AlignmentFlag alignment =
static_cast< Qt::AlignmentFlag
>(
static_cast< int >( mTitleAlignCombo->currentAlignment() & Qt::AlignHorizontal_Mask ) );
349 mLegend->beginCommand( tr(
"Change Title Alignment" ) );
350 mLegend->setTitleAlignment( alignment );
352 mLegend->endCommand();
356void QgsLayoutLegendWidget::groupAlignmentChanged()
360 mLegend->beginCommand( tr(
"Change Group Alignment" ) );
363 mLegend->endCommand();
367void QgsLayoutLegendWidget::subgroupAlignmentChanged()
371 mLegend->beginCommand( tr(
"Change Subgroup Alignment" ) );
374 mLegend->endCommand();
378void QgsLayoutLegendWidget::itemAlignmentChanged()
382 mLegend->beginCommand( tr(
"Change Item Alignment" ) );
385 mLegend->endCommand();
389void QgsLayoutLegendWidget::arrangementChanged()
393 Qt::AlignmentFlag alignment =
static_cast< Qt::AlignmentFlag
>(
static_cast< int >( mArrangementCombo->currentAlignment() & Qt::AlignHorizontal_Mask ) );
394 mLegend->beginCommand( tr(
"Change Legend Arrangement" ) );
395 mLegend->setSymbolAlignment( alignment );
397 mLegend->endCommand();
401void QgsLayoutLegendWidget::mColumnCountSpinBox_valueChanged(
int c )
406 mLegend->setColumnCount(
c );
407 mLegend->adjustBoxSize();
409 mLegend->endCommand();
411 mSplitLayerCheckBox->setEnabled(
c > 1 );
412 mEqualColumnWidthCheckBox->setEnabled(
c > 1 );
415void QgsLayoutLegendWidget::mSplitLayerCheckBox_toggled(
bool checked )
419 mLegend->beginCommand( tr(
"Split Legend Layers" ) );
420 mLegend->setSplitLayer( checked );
421 mLegend->adjustBoxSize();
423 mLegend->endCommand();
427void QgsLayoutLegendWidget::mEqualColumnWidthCheckBox_toggled(
bool checked )
431 mLegend->beginCommand( tr(
"Legend Column Width" ) );
432 mLegend->setEqualColumnWidth( checked );
433 mLegend->adjustBoxSize();
435 mLegend->endCommand();
439void QgsLayoutLegendWidget::mSymbolWidthSpinBox_valueChanged(
double d )
444 mLegend->setSymbolWidth( d );
445 mLegend->adjustBoxSize();
447 mLegend->endCommand();
451void QgsLayoutLegendWidget::mMaxSymbolSizeSpinBox_valueChanged(
double d )
456 mLegend->setMaximumSymbolSize( d );
457 mLegend->adjustBoxSize();
459 mLegend->endCommand();
463void QgsLayoutLegendWidget::mMinSymbolSizeSpinBox_valueChanged(
double d )
468 mLegend->setMinimumSymbolSize( d );
469 mLegend->adjustBoxSize();
471 mLegend->endCommand();
475void QgsLayoutLegendWidget::mSymbolHeightSpinBox_valueChanged(
double d )
480 mLegend->setSymbolHeight( d );
481 mLegend->adjustBoxSize();
483 mLegend->endCommand();
487void QgsLayoutLegendWidget::mWmsLegendWidthSpinBox_valueChanged(
double d )
492 mLegend->setWmsLegendWidth( d );
493 mLegend->adjustBoxSize();
495 mLegend->endCommand();
499void QgsLayoutLegendWidget::mWmsLegendHeightSpinBox_valueChanged(
double d )
504 mLegend->setWmsLegendHeight( d );
505 mLegend->adjustBoxSize();
507 mLegend->endCommand();
511void QgsLayoutLegendWidget::mTitleSpaceBottomSpinBox_valueChanged(
double d )
517 mLegend->adjustBoxSize();
519 mLegend->endCommand();
523void QgsLayoutLegendWidget::mGroupSpaceSpinBox_valueChanged(
double d )
529 mLegend->adjustBoxSize();
531 mLegend->endCommand();
535void QgsLayoutLegendWidget::mGroupIndentSpinBox_valueChanged(
double d )
541 mLegend->adjustBoxSize();
543 mLegend->endCommand();
547void QgsLayoutLegendWidget::mSubgroupIndentSpinBox_valueChanged(
double d )
553 mLegend->adjustBoxSize();
555 mLegend->endCommand();
559void QgsLayoutLegendWidget::spaceBelowGroupHeadingChanged(
double space )
565 mLegend->adjustBoxSize();
567 mLegend->endCommand();
571void QgsLayoutLegendWidget::spaceGroupSideChanged(
double space )
577 mLegend->adjustBoxSize();
579 mLegend->endCommand();
583void QgsLayoutLegendWidget::spaceSubGroupSideChanged(
double space )
589 mLegend->adjustBoxSize();
591 mLegend->endCommand();
595void QgsLayoutLegendWidget::spaceSymbolSideChanged(
double space )
601 mLegend->adjustBoxSize();
603 mLegend->endCommand();
607void QgsLayoutLegendWidget::mLayerSpaceSpinBox_valueChanged(
double d )
613 mLegend->adjustBoxSize();
615 mLegend->endCommand();
619void QgsLayoutLegendWidget::mSymbolSpaceSpinBox_valueChanged(
double d )
627 mLegend->adjustBoxSize();
629 mLegend->endCommand();
633void QgsLayoutLegendWidget::mIconLabelSpaceSpinBox_valueChanged(
double d )
639 mLegend->adjustBoxSize();
641 mLegend->endCommand();
645void QgsLayoutLegendWidget::titleFontChanged()
651 mLegend->adjustBoxSize();
653 mLegend->endCommand();
657void QgsLayoutLegendWidget::groupFontChanged()
663 mLegend->adjustBoxSize();
665 mLegend->endCommand();
669void QgsLayoutLegendWidget::layerFontChanged()
675 mLegend->adjustBoxSize();
677 mLegend->endCommand();
681void QgsLayoutLegendWidget::itemFontChanged()
687 mLegend->adjustBoxSize();
689 mLegend->endCommand();
693void QgsLayoutLegendWidget::spaceBelowSubGroupHeadingChanged(
double space )
699 mLegend->adjustBoxSize();
701 mLegend->endCommand();
705void QgsLayoutLegendWidget::mBoxSpaceSpinBox_valueChanged(
double d )
710 mLegend->setBoxSpace( d );
711 mLegend->adjustBoxSize();
713 mLegend->endCommand();
717void QgsLayoutLegendWidget::mColumnSpaceSpinBox_valueChanged(
double d )
722 mLegend->setColumnSpace( d );
723 mLegend->adjustBoxSize();
725 mLegend->endCommand();
729static void _moveLegendNode(
QgsLayerTreeLayer *nodeLayer,
int legendNodeIndex,
int offset )
733 if ( legendNodeIndex < 0 || legendNodeIndex >= order.count() )
735 if ( legendNodeIndex + offset < 0 || legendNodeIndex + offset >= order.count() )
738 int id = order.takeAt( legendNodeIndex );
739 order.insert( legendNodeIndex + offset,
id );
745void QgsLayoutLegendWidget::mMoveDownToolButton_clicked()
752 const QModelIndex index = mItemTreeView->selectionModel()->currentIndex();
753 const QModelIndex sourceIndex = mItemTreeView->proxyModel()->mapToSource( index );
754 const QModelIndex parentIndex = sourceIndex.parent();
755 if ( !sourceIndex.isValid() || sourceIndex.row() == mItemTreeView->layerTreeModel()->rowCount( parentIndex ) - 1 )
763 mLegend->beginCommand( tr(
"Moved Legend Item Down" ) );
777 mItemTreeView->setCurrentIndex( mItemTreeView->proxyModel()->mapFromSource( mItemTreeView->layerTreeModel()->index( sourceIndex.row() + 1, 0, parentIndex ) ) );
780 mLegend->endCommand();
783void QgsLayoutLegendWidget::mMoveUpToolButton_clicked()
790 const QModelIndex index = mItemTreeView->selectionModel()->currentIndex();
791 const QModelIndex sourceIndex = mItemTreeView->proxyModel()->mapToSource( index );
792 const QModelIndex parentIndex = sourceIndex.parent();
793 if ( !sourceIndex.isValid() || sourceIndex.row() == 0 )
801 mLegend->beginCommand( tr(
"Move Legend Item Up" ) );
815 mItemTreeView->setCurrentIndex( mItemTreeView->proxyModel()->mapFromSource( mItemTreeView->layerTreeModel()->index( sourceIndex.row() - 1, 0, parentIndex ) ) );
818 mLegend->endCommand();
821void QgsLayoutLegendWidget::expandLegendTree()
823 mItemTreeView -> expandAll();
826void QgsLayoutLegendWidget::collapseLegendTree()
828 mItemTreeView -> collapseAll();
831void QgsLayoutLegendWidget::mCheckBoxAutoUpdate_stateChanged(
int state,
bool userTriggered )
835 mLegend->beginCommand( tr(
"Change Auto Update" ) );
837 mLegend->setAutoUpdateModel( state == Qt::Checked );
839 mLegend->endCommand();
843 QList<QWidget *> widgets;
844 widgets << mMoveDownToolButton << mMoveUpToolButton << mRemoveToolButton << mAddToolButton
845 << mEditPushButton << mCountToolButton << mUpdateAllPushButton << mAddGroupToolButton
846 << mExpressionFilterButton << mCollapseAllToolButton << mExpandAllToolButton;
847 for ( QWidget *w : std::as_const( widgets ) )
848 w->setEnabled( state != Qt::Checked );
850 if ( state == Qt::Unchecked )
853 selectedChanged( QModelIndex(), QModelIndex() );
857void QgsLayoutLegendWidget::composerMapChanged(
QgsLayoutItem *item )
873 mLegend->beginCommand( tr(
"Change Legend Map" ) );
874 mLegend->setLinkedMap( map );
876 mLegend->endCommand();
878 setLegendMapViewData();
882void QgsLayoutLegendWidget::mCheckboxResizeContents_toggled(
bool checked )
889 mLegend->beginCommand( tr(
"Resize Legend to Contents" ) );
890 mLegend->setResizeToContents( checked );
892 mLegend->adjustBoxSize();
894 mLegend->endCommand();
897void QgsLayoutLegendWidget::mRasterStrokeGroupBox_toggled(
bool state )
904 mLegend->beginCommand( tr(
"Change Legend Borders" ) );
905 mLegend->setDrawRasterStroke( state );
906 mLegend->adjustBoxSize();
908 mLegend->endCommand();
911void QgsLayoutLegendWidget::mRasterStrokeWidthSpinBox_valueChanged(
double d )
919 mLegend->setRasterStrokeWidth( d );
920 mLegend->adjustBoxSize();
922 mLegend->endCommand();
925void QgsLayoutLegendWidget::mRasterStrokeColorButton_colorChanged(
const QColor &newColor )
933 mLegend->setRasterStrokeColor( newColor );
935 mLegend->endCommand();
938void QgsLayoutLegendWidget::mAddToolButton_clicked()
945 QList< QgsMapLayer * > visibleLayers;
946 if ( mLegend->linkedMap() )
948 visibleLayers = mLegend->linkedMap()->layersToRender();
950 if ( visibleLayers.isEmpty() )
953 visibleLayers = mMapCanvas->layers(
true );
957 addDialog.setVisibleLayers( visibleLayers );
958 if ( addDialog.exec() == QDialog::Accepted )
960 const QList<QgsMapLayer *> layers = addDialog.selectedLayers();
961 if ( !layers.empty() )
963 mLegend->beginCommand( tr(
"Add Legend Item(s)" ) );
966 mLegend->model()->rootGroup()->addLayer( layer );
968 mLegend->updateLegend();
970 mLegend->endCommand();
975void QgsLayoutLegendWidget::mRemoveToolButton_clicked()
982 QItemSelectionModel *selectionModel = mItemTreeView->selectionModel();
983 if ( !selectionModel )
988 mLegend->beginCommand( tr(
"Remove Legend Item" ) );
990 QList<QPersistentModelIndex> proxyIndexes;
991 const QModelIndexList viewSelection = selectionModel->selectedIndexes();
992 for (
const QModelIndex &index : viewSelection )
993 proxyIndexes << index;
996 QHash<QgsLayerTreeLayer *, QList<int> > nodesWithRemoval;
997 for (
const QPersistentModelIndex &proxyIndex : std::as_const( proxyIndexes ) )
1002 nodesWithRemoval[nodeLayer].append( _unfilteredLegendNodeIndex(
legendNode ) );
1005 for (
auto it = nodesWithRemoval.constBegin(); it != nodesWithRemoval.constEnd(); ++it )
1007 QList<int> toDelete = it.value();
1008 std::sort( toDelete.begin(), toDelete.end(), std::greater<int>() );
1011 for (
int i : std::as_const( toDelete ) )
1013 if ( i >= 0 && i < order.count() )
1014 order.removeAt( i );
1018 mItemTreeView->layerTreeModel()->refreshLayerLegend( it.key() );
1022 for (
const QPersistentModelIndex &proxyIndex : std::as_const( proxyIndexes ) )
1024 if ( proxyIndex.isValid() && mItemTreeView->index2node( proxyIndex ) )
1026 const QModelIndex sourceIndex = mItemTreeView->proxyModel()->mapToSource( proxyIndex );
1027 mLegend->model()->removeRow( sourceIndex.row(), sourceIndex.parent() );
1031 mLegend->updateLegend();
1033 mLegend->endCommand();
1036void QgsLayoutLegendWidget::mEditPushButton_clicked()
1043 QModelIndex idx = mItemTreeView->selectionModel()->currentIndex();
1044 mItemTreeView_doubleClicked( idx );
1047void QgsLayoutLegendWidget::resetLayerNodeToDefaults()
1055 QModelIndex currentIndex = mItemTreeView->currentIndex();
1056 if ( !currentIndex.isValid() )
1075 mLegend->beginCommand( tr(
"Update Legend" ) );
1078 for (
const QString &key : constCustomProperties )
1080 if ( key.startsWith( QLatin1String(
"legend/" ) ) )
1087 mItemTreeView->layerTreeModel()->refreshLayerLegend( nodeLayer );
1089 mLegend->updateLegend();
1091 mLegend->endCommand();
1094void QgsLayoutLegendWidget::mCountToolButton_clicked(
bool checked )
1101 const QList< QModelIndex > selectedIndexes = mItemTreeView->selectionModel()->selectedIndexes();
1102 if ( selectedIndexes.empty() )
1105 mLegend->beginCommand( tr(
"Update Legend" ) );
1106 for (
const QModelIndex &index : selectedIndexes )
1112 currentNode->
setCustomProperty( QStringLiteral(
"showFeatureCount" ), checked ? 1 : 0 );
1114 mLegend->updateFilterByMap();
1115 mLegend->adjustBoxSize();
1116 mLegend->endCommand();
1119void QgsLayoutLegendWidget::mFilterByMapCheckBox_toggled(
bool checked )
1121 mLegend->beginCommand( tr(
"Update Legend" ) );
1122 mLegend->setLegendFilterByMapEnabled( checked );
1123 mLegend->adjustBoxSize();
1125 mLegend->endCommand();
1128void QgsLayoutLegendWidget::mExpressionFilterButton_toggled(
bool checked )
1136 QModelIndex currentIndex = mItemTreeView->currentIndex();
1137 if ( !currentIndex.isValid() )
1147 mExpressionFilterButton->expressionText(),
1150 mLegend->beginCommand( tr(
"Update Legend" ) );
1151 mLegend->updateFilterByMap();
1152 mLegend->adjustBoxSize();
1153 mLegend->endCommand();
1156void QgsLayoutLegendWidget::mLayerExpressionButton_clicked()
1163 QModelIndex currentIndex = mItemTreeView->currentIndex();
1164 if ( !currentIndex.isValid() )
1171 QgsLayerTreeLayer *layerNode = qobject_cast<QgsLayerTreeLayer *>( currentNode );
1177 QString currentExpression;
1179 currentExpression = QStringLiteral(
"@symbol_label" );
1185 QStringList highlighted;
1188 const QList<QgsLayerTreeModelLegendNode *> legendNodes = model->layerLegendNodes( layerNode,
false );
1189 if ( !legendNodes.isEmpty() )
1191 if (
QgsSymbolLegendNode *symbolNode = qobject_cast<QgsSymbolLegendNode *>( legendNodes.first() ) )
1193 legendContext.
appendScope( symbolNode->createSymbolScope() );
1194 highlighted << QStringLiteral(
"symbol_label" ) << QStringLiteral(
"symbol_id" ) << QStringLiteral(
"symbol_count" );
1207 QgsExpressionBuilderDialog expressiondialog(
nullptr, currentExpression,
nullptr, QStringLiteral(
"generic" ), legendContext );
1208 if ( expressiondialog.exec() )
1211 mItemTreeView->layerTreeModel()->refreshLayerLegend( layerNode );
1214 mLegend->beginCommand( tr(
"Update Legend" ) );
1216 mLegend->adjustBoxSize();
1217 mLegend->endCommand();
1220void QgsLayoutLegendWidget::mUpdateAllPushButton_clicked()
1225void QgsLayoutLegendWidget::mAddGroupToolButton_clicked()
1229 mLegend->beginCommand( tr(
"Add Legend Group" ) );
1230 mLegend->model()->rootGroup()->addGroup( tr(
"Group" ) );
1231 mLegend->updateLegend();
1233 mLegend->endCommand();
1237void QgsLayoutLegendWidget::mFilterLegendByAtlasCheckBox_toggled(
bool toggled )
1242 mLegend->setLegendFilterOutAtlas( toggled );
1248void QgsLayoutLegendWidget::updateLegend()
1252 mLegend->beginCommand( tr(
"Update Legend" ) );
1255 mLegend->setAutoUpdateModel(
true );
1256 mLegend->setAutoUpdateModel(
false );
1258 mLegend->endCommand();
1262void QgsLayoutLegendWidget::setReportTypeString(
const QString &
string )
1264 mFilterLegendByAtlasCheckBox->setText( tr(
"Only show items inside current %1 feature" ).arg(
string ) );
1265 mFilterLegendByAtlasCheckBox->setToolTip( tr(
"Filter out legend elements that lie outside the current %1 feature." ).arg(
string ) );
1274bool QgsLayoutLegendWidget::setNewItem(
QgsLayoutItem *item )
1284 mLegend = qobject_cast< QgsLayoutItemLegend * >( item );
1285 mItemPropertiesWidget->setItem( mLegend );
1287 if ( mMapFilteringWidget )
1288 mMapFilteringWidget->setItem( mLegend );
1292 mItemTreeView->setModel( mLegend->model() );
1301void QgsLayoutLegendWidget::blockAllSignals(
bool b )
1303 mTitleLineEdit->blockSignals( b );
1304 mTitleAlignCombo->blockSignals( b );
1305 mItemTreeView->blockSignals( b );
1306 mCheckBoxAutoUpdate->blockSignals( b );
1307 mMapComboBox->blockSignals( b );
1308 mFilterByMapCheckBox->blockSignals( b );
1309 mColumnCountSpinBox->blockSignals( b );
1310 mSplitLayerCheckBox->blockSignals( b );
1311 mEqualColumnWidthCheckBox->blockSignals( b );
1312 mSymbolWidthSpinBox->blockSignals( b );
1313 mSymbolHeightSpinBox->blockSignals( b );
1314 mMaxSymbolSizeSpinBox->blockSignals( b );
1315 mMinSymbolSizeSpinBox->blockSignals( b );
1316 mGroupSpaceSpinBox->blockSignals( b );
1317 mGroupIndentSpinBox->blockSignals( b );
1318 mSubgroupIndentSpinBox->blockSignals( b );
1319 mSpaceBelowGroupHeadingSpinBox->blockSignals( b );
1320 mGroupSideSpinBox->blockSignals( b );
1321 mSpaceBelowSubgroupHeadingSpinBox->blockSignals( b );
1322 mSubgroupSideSpinBox->blockSignals( b );
1323 mLayerSpaceSpinBox->blockSignals( b );
1324 mSymbolSpaceSpinBox->blockSignals( b );
1325 mSymbolSideSpaceSpinBox->blockSignals( b );
1326 mIconLabelSpaceSpinBox->blockSignals( b );
1327 mBoxSpaceSpinBox->blockSignals( b );
1328 mColumnSpaceSpinBox->blockSignals( b );
1329 mRasterStrokeGroupBox->blockSignals( b );
1330 mRasterStrokeColorButton->blockSignals( b );
1331 mRasterStrokeWidthSpinBox->blockSignals( b );
1332 mWmsLegendWidthSpinBox->blockSignals( b );
1333 mWmsLegendHeightSpinBox->blockSignals( b );
1334 mCheckboxResizeContents->blockSignals( b );
1335 mTitleSpaceBottomSpinBox->blockSignals( b );
1336 mFilterLegendByAtlasCheckBox->blockSignals( b );
1337 mTitleFontButton->blockSignals( b );
1338 mGroupFontButton->blockSignals( b );
1339 mLayerFontButton->blockSignals( b );
1340 mItemFontButton->blockSignals( b );
1341 mWrapCharLineEdit->blockSignals( b );
1344void QgsLayoutLegendWidget::selectedChanged(
const QModelIndex ¤t,
const QModelIndex &previous )
1347 Q_UNUSED( previous )
1349 mLayerExpressionButton->setEnabled(
false );
1351 if ( mLegend && mLegend->autoUpdateModel() )
1362 mLayerExpressionButton->setEnabled(
true );
1366 mCountToolButton->setChecked(
false );
1367 mCountToolButton->setEnabled(
false );
1370 mExpressionFilterButton->blockSignals(
true );
1371 mExpressionFilterButton->setChecked(
false );
1372 mExpressionFilterButton->setEnabled(
false );
1373 mExpressionFilterButton->blockSignals(
false );
1384 mCountToolButton->setChecked( currentNode->
customProperty( QStringLiteral(
"showFeatureCount" ), 0 ).toInt() );
1385 mCountToolButton->setEnabled(
true );
1386 mLayerExpressionButton->setEnabled(
true );
1390 mExpressionFilterButton->blockSignals(
true );
1391 mExpressionFilterButton->setExpressionText( expr );
1392 mExpressionFilterButton->setVectorLayer( vl );
1393 mExpressionFilterButton->setEnabled(
true );
1394 mExpressionFilterButton->setChecked( exprEnabled );
1395 mExpressionFilterButton->blockSignals(
false );
1398void QgsLayoutLegendWidget::setCurrentNodeStyleFromAction()
1400 QAction *a = qobject_cast<QAction *>( sender() );
1401 if ( !a || !mItemTreeView->currentNode() )
1408void QgsLayoutLegendWidget::setLegendMapViewData()
1410 if ( mLegend->linkedMap() )
1414 measurementConverter.
setDpi( dpi );
1417 double mapUnitsPerPixelX = mLegend->linkedMap()->extent().width() / mapWidth;
1418 double mapUnitsPerPixelY = mLegend->linkedMap()->extent().height() / mapHeight;
1419 mLegend->model()->setLegendMapViewData( ( mapUnitsPerPixelX > mapUnitsPerPixelY ? mapUnitsPerPixelX : mapUnitsPerPixelY ), dpi, mLegend->linkedMap()->scale() );
1423void QgsLayoutLegendWidget::updateFilterLegendByAtlasButton()
1427 mFilterLegendByAtlasCheckBox->setEnabled( atlas->enabled() && mLegend->layout()->reportContext().layer() && mLegend->layout()->reportContext().layer()->geometryType() ==
Qgis::GeometryType::Polygon );
1431void QgsLayoutLegendWidget::mItemTreeView_doubleClicked(
const QModelIndex &idx )
1433 if ( !mLegend || !idx.isValid() )
1438 if ( mLegend->autoUpdateModel() )
1444 int originalIndex = -1;
1447 originalIndex = _originalLegendNodeIndex(
legendNode );
1451 QgsLayoutLegendNodeWidget *widget =
new QgsLayoutLegendNodeWidget( mLegend, currentNode,
legendNode, originalIndex );
1452 openPanel( widget );
1460QgsLayoutLegendMenuProvider::QgsLayoutLegendMenuProvider(
QgsLayerTreeView *view, QgsLayoutLegendWidget *w )
1465QMenu *QgsLayoutLegendMenuProvider::createContextMenu()
1467 if ( !mView->currentNode() )
1470 if ( mWidget->legend()->autoUpdateModel() )
1473 QMenu *menu =
new QMenu();
1477 menu->addAction( QObject::tr(
"Reset to Defaults" ), mWidget, &QgsLayoutLegendWidget::resetLayerNodeToDefaults );
1478 menu->addSeparator();
1483 QList<QgsLegendStyle::Style> lst;
1487 QAction *action = menu->addAction(
QgsLegendStyle::styleLabel( style ), mWidget, &QgsLayoutLegendWidget::setCurrentNodeStyleFromAction );
1488 action->setCheckable(
true );
1489 action->setChecked( currentStyle == style );
1490 action->setData(
static_cast< int >( style ) );
1505 , mOriginalLegendNodeIndex( originalLegendNodeIndex )
1508 setPanelTitle( tr(
"Legend Item Properties" ) );
1517 QString currentLabel;
1520 currentLabel = mLegendNode->data( Qt::EditRole ).toString();
1521 mColumnBreakBeforeCheckBox->setChecked( mLegendNode->columnBreak() );
1525 currentLabel = mLayer->name();
1526 QVariant v = mLayer->customProperty( QStringLiteral(
"legend/title-label" ) );
1528 currentLabel = v.toString();
1529 mColumnBreakBeforeCheckBox->setChecked( mLayer->customProperty( QStringLiteral(
"legend/column-break" ) ).toInt() );
1531 mColumnSplitBehaviorComboBox->setCurrentIndex( mColumnSplitBehaviorComboBox->findData( mLayer->legendSplitBehavior() ) );
1536 mColumnBreakBeforeCheckBox->setChecked( mNode->customProperty( QStringLiteral(
"legend/column-break" ) ).toInt() );
1539 mWidthSpinBox->setClearValue( 0, tr(
"Default" ) );
1540 mHeightSpinBox->setClearValue( 0, tr(
"Default" ) );
1541 mWidthSpinBox->setVisible( mLegendNode || mLayer );
1542 mHeightSpinBox->setVisible( mLegendNode || mLayer );
1543 mPatchGroup->setVisible( mLegendNode || mLayer );
1544 mPatchWidthLabel->setVisible( mLegendNode || mLayer );
1545 mPatchHeightLabel->setVisible( mLegendNode || mLayer );
1546 mCustomSymbolCheckBox->setVisible( mLegendNode || mLegend->model()->legendNodeEmbeddedInParent( mLayer ) );
1547 mColumnSplitLabel->setVisible( mLayer && !mLegendNode );
1548 mColumnSplitBehaviorComboBox->setVisible( mLayer && !mLegendNode );
1551 mWidthSpinBox->setValue( mLegendNode->userPatchSize().width() );
1552 mHeightSpinBox->setValue( mLegendNode->userPatchSize().height() );
1556 mWidthSpinBox->setValue( mLayer->patchSize().width() );
1557 mHeightSpinBox->setValue( mLayer->patchSize().height() );
1560 mCustomSymbolCheckBox->setChecked(
false );
1565 patchShape = symbolLegendNode->patchShape();
1567 std::unique_ptr< QgsSymbol > customSymbol( symbolLegendNode->customSymbol() ? symbolLegendNode->customSymbol()->clone() :
nullptr );
1568 mCustomSymbolCheckBox->setChecked( customSymbol.get() );
1571 mPatchShapeButton->setPreviewSymbol( customSymbol->clone() );
1572 mCustomSymbolButton->setSymbolType( customSymbol->type() );
1573 mCustomSymbolButton->setSymbol( customSymbol.release() );
1575 else if ( symbolLegendNode->symbol() )
1577 mPatchShapeButton->setPreviewSymbol( symbolLegendNode->symbol()->clone() );
1578 mCustomSymbolButton->setSymbolType( symbolLegendNode->symbol()->type() );
1579 mCustomSymbolButton->setSymbol( symbolLegendNode->symbol()->clone() );
1582 else if ( !mLegendNode && mLayer )
1584 patchShape = mLayer->patchShape();
1587 if (
QgsSymbol *customSymbol = symbolLegendNode->customSymbol() )
1589 mCustomSymbolCheckBox->setChecked(
true );
1590 mPatchShapeButton->setPreviewSymbol( customSymbol->clone() );
1592 mCustomSymbolButton->setSymbol( customSymbol->clone() );
1596 mPatchShapeButton->setPreviewSymbol( symbolLegendNode->symbol()->clone() );
1597 mCustomSymbolButton->setSymbolType( symbolLegendNode->symbol()->type() );
1598 mCustomSymbolButton->setSymbol( symbolLegendNode->symbol()->clone() );
1605 switch ( qobject_cast< QgsVectorLayer * >( mLayer->layer() )->geometryType() )
1620 mPatchShapeLabel->hide();
1621 mPatchShapeButton->hide();
1624 if ( !patchShape.
isNull() )
1625 mPatchShapeButton->setShape( patchShape );
1630 if ( symbolLegendNode->symbol() )
1632 mPatchShapeButton->setSymbolType( symbolLegendNode->symbol()->type() );
1636 mPatchShapeLabel->hide();
1637 mPatchShapeButton->hide();
1642 mPatchShapeLabel->hide();
1643 mPatchShapeButton->hide();
1648 mLabelGroup->hide();
1649 mColorRampLegendWidget->setSettings( colorRampNode->settings() );
1653 mColorRampLegendWidget->hide();
1666 mCustomSymbolCheckBox->hide();
1675 mLabelEdit->setPlainText( currentLabel );
1676 connect( mLabelEdit, &QPlainTextEdit::textChanged,
this, &QgsLayoutLegendNodeWidget::labelChanged );
1678 connect( mInsertExpressionButton, &QPushButton::clicked,
this, &QgsLayoutLegendNodeWidget::insertExpression );
1680 connect( mWidthSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendNodeWidget::sizeChanged );
1681 connect( mHeightSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendNodeWidget::sizeChanged );
1683 connect( mCustomSymbolCheckBox, &QGroupBox::toggled,
this, &QgsLayoutLegendNodeWidget::customSymbolChanged );
1686 connect( mColumnBreakBeforeCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendNodeWidget::columnBreakToggled );
1688 connect( mColumnSplitBehaviorComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsLayoutLegendNodeWidget::columnSplitChanged );
1692 connectChildPanel( mColorRampLegendWidget );
1695void QgsLayoutLegendNodeWidget::setDockMode(
bool dockMode )
1697 mColorRampLegendWidget->setDockMode( dockMode );
1701void QgsLayoutLegendNodeWidget::labelChanged()
1705 const QString label = mLabelEdit->toPlainText();
1710 else if ( mLegendNode )
1713 mLegend->model()->refreshLayerLegend( mLayer );
1717 mLayer->setCustomProperty( QStringLiteral(
"legend/title-label" ), label );
1721 embeddedNode->setUserLabel( QString() );
1724 mLegend->adjustBoxSize();
1725 mLegend->invalidateCache();
1727 mLegend->endCommand();
1730void QgsLayoutLegendNodeWidget::patchChanged()
1732 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1738 mLegend->model()->refreshLayerLegend( mLayer );
1742 mLayer->setPatchShape( shape );
1743 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1748 mLegend->model()->refreshLayerLegend( mLayer );
1751 mLegend->adjustBoxSize();
1753 mLegend->endCommand();
1756void QgsLayoutLegendNodeWidget::insertExpression()
1764 QgsVectorLayer *layer = mLegend->layout() ? mLegend->layout()->reportContext().layer() :
nullptr;
1768 if ( mLayer && mLayer->layer() )
1774 << QStringLiteral(
"legend_column_count" )
1775 << QStringLiteral(
"legend_split_layers" )
1776 << QStringLiteral(
"legend_wrap_string" )
1777 << QStringLiteral(
"legend_filter_by_map" )
1778 << QStringLiteral(
"legend_filter_out_atlas" ) );
1782 exprDlg.setWindowTitle( tr(
"Insert Expression" ) );
1783 if ( exprDlg.exec() == QDialog::Accepted )
1785 expression = exprDlg.expressionText();
1786 if ( !expression.isEmpty() )
1788 mLegend->beginCommand( tr(
"Insert expression" ) );
1789 mLabelEdit->insertPlainText(
"[%" + expression.trimmed() +
"%]" );
1790 mLegend->endCommand();
1795void QgsLayoutLegendNodeWidget::sizeChanged(
double )
1797 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1798 const QSizeF size = QSizeF( mWidthSpinBox->value(), mHeightSpinBox->value() );
1803 mLegend->model()->refreshLayerLegend( mLayer );
1807 mLayer->setPatchSize( size );
1808 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1813 mLegend->model()->refreshLayerLegend( mLayer );
1816 mLegend->adjustBoxSize();
1818 mLegend->endCommand();
1821void QgsLayoutLegendNodeWidget::customSymbolChanged()
1823 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1825 if ( mCustomSymbolCheckBox->isChecked() )
1830 mLegend->model()->refreshLayerLegend( mLayer );
1834 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1839 mLegend->model()->refreshLayerLegend( mLayer );
1847 mLegend->model()->refreshLayerLegend( mLayer );
1851 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1856 mLegend->model()->refreshLayerLegend( mLayer );
1860 mLegend->adjustBoxSize();
1862 mLegend->endCommand();
1865void QgsLayoutLegendNodeWidget::colorRampLegendChanged()
1867 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1871 mLegend->model()->refreshLayerLegend( mLayer );
1873 mLegend->adjustBoxSize();
1875 mLegend->endCommand();
1878void QgsLayoutLegendNodeWidget::columnBreakToggled(
bool checked )
1880 mLegend->beginCommand( tr(
"Edit Legend Columns" ) );
1885 mLegend->model()->refreshLayerLegend( mLayer );
1889 mLayer->setCustomProperty( QStringLiteral(
"legend/column-break" ), QString( checked ?
'1' :
'0' ) );
1893 mNode->setCustomProperty( QStringLiteral(
"legend/column-break" ), QString( checked ?
'1' :
'0' ) );
1896 mLegend->adjustBoxSize();
1898 mLegend->endCommand();
1901void QgsLayoutLegendNodeWidget::columnSplitChanged()
1903 mLegend->beginCommand( tr(
"Edit Legend Columns" ) );
1905 if ( mLayer && !mLegendNode )
1910 mLegend->adjustBoxSize();
1912 mLegend->endCommand();
1919QgsLayoutLegendMapFilteringWidget::QgsLayoutLegendMapFilteringWidget(
QgsLayoutItemLegend *legend )
1921 , mLegendItem( legend )
1924 setPanelTitle( tr(
"Legend Filtering" ) );
1926 setNewItem( legend );
1929bool QgsLayoutLegendMapFilteringWidget::setNewItem(
QgsLayoutItem *item )
1939 mLegendItem = qobject_cast< QgsLayoutItemLegend * >( item );
1946 updateGuiElements();
1951void QgsLayoutLegendMapFilteringWidget::updateGuiElements()
1953 if ( mBlockUpdates )
1956 mBlockUpdates =
true;
1958 if ( mFilterMapItemsListView->model() )
1960 QAbstractItemModel *oldModel = mFilterMapItemsListView->model();
1961 mFilterMapItemsListView->setModel(
nullptr );
1962 oldModel->deleteLater();
1965 QgsLayoutLegendMapFilteringModel *model =
new QgsLayoutLegendMapFilteringModel( mLegendItem, mLegendItem->layout()->itemsModel(), mFilterMapItemsListView );
1966 mFilterMapItemsListView->setModel( model );
1968 mBlockUpdates =
false;
1976 : QSortFilterProxyModel( parent )
1977 , mLayoutModel( layoutModel )
1978 , mLegendItem( legend )
1980 setSourceModel( layoutModel );
1983int QgsLayoutLegendMapFilteringModel::columnCount(
const QModelIndex & )
const
1988QVariant QgsLayoutLegendMapFilteringModel::data(
const QModelIndex &i,
int role )
const
1993 if ( i.column() != 0 )
1998 QgsLayoutItemMap *mapItem = qobject_cast< QgsLayoutItemMap * >( mLayoutModel->itemFromIndex( mapToSource( i ) ) );
2006 case Qt::CheckStateRole:
2007 switch ( i.column() )
2012 return Qt::Unchecked;
2014 return mLegendItem->filterByMapItems().contains( mapItem ) ? Qt::Checked : Qt::Unchecked;
2022 return mLayoutModel->data( sourceIndex, role );
2026bool QgsLayoutLegendMapFilteringModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
2030 if ( !index.isValid() )
2033 QgsLayoutItemMap *mapItem = qobject_cast< QgsLayoutItemMap * >( mLayoutModel->itemFromIndex( mapToSource( index ) ) );
2034 if ( !mapItem || !mLegendItem )
2039 mLegendItem->layout()->undoStack()->beginCommand( mLegendItem, tr(
"Change Legend Linked Maps" ) );
2041 QList< QgsLayoutItemMap * > linkedMaps = mLegendItem->filterByMapItems();
2042 if ( value.toBool() )
2044 if ( !linkedMaps.contains( mapItem ) )
2046 linkedMaps.append( mapItem );
2047 mLegendItem->setFilterByMapItems( linkedMaps );
2052 linkedMaps.removeAll( mapItem );
2053 mLegendItem->setFilterByMapItems( linkedMaps );
2055 emit dataChanged( index, index, QVector<int>() << role );
2057 mLegendItem->layout()->undoStack()->endCommand();
2058 mLegendItem->invalidateCache();
2063Qt::ItemFlags QgsLayoutLegendMapFilteringModel::flags(
const QModelIndex &index )
const
2065 Qt::ItemFlags flags = QSortFilterProxyModel::flags( index );
2067 if ( ! index.isValid() )
2072 QgsLayoutItemMap *mapItem = qobject_cast< QgsLayoutItemMap * >( mLayoutModel->itemFromIndex( mapToSource( index ) ) );
2073 const bool isMainLinkedMapItem = mLegendItem ? ( mLegendItem->linkedMap() == mapItem ) :
false;
2079 if ( !isMainLinkedMapItem )
2081 flags |= Qt::ItemIsEnabled;
2085 flags &= ~Qt::ItemIsEnabled;
2088 switch ( index.column() )
2091 if ( !isMainLinkedMapItem )
2092 return flags | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
2094 return flags | Qt::ItemIsSelectable;
2097 return flags | Qt::ItemIsSelectable;
2101bool QgsLayoutLegendMapFilteringModel::filterAcceptsRow(
int source_row,
const QModelIndex &source_parent )
const
2103 QgsLayoutItem *item = mLayoutModel->itemFromIndex( mLayoutModel->index( source_row, 0, source_parent ) );
2104 if ( !item || item->
type() != QgsLayoutItemRegistry::ItemType::LayoutMap )
void changed()
Emitted when the alignment is changed.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
Settings for a color ramp legend node.
A legend node which renders a color ramp.
A generic dialog for building expression strings.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void setFields(const QgsFields &fields)
Convenience function for setting a fields for the scope.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user.
static QString findAndSelectActiveExpression(QgsCodeEditor *editor, const QString &pattern=QString())
Find the expression under the cursor in the given editor and select it.
Container of fields for a vector layer.
Layer tree group node serves as a container for layers and further groups.
void insertChildNode(int index, QgsLayerTreeNode *node)
Insert existing node at specified position.
void setName(const QString &n) override
Sets the group's name.
void removeChildNode(QgsLayerTreeNode *node)
Remove a child node from this group.
QString name() const override
Returns the group's name.
Layer tree node points to a map layer.
void setPatchSize(QSizeF size)
Sets the user (overridden) size for the legend node.
QString labelExpression() const
Returns the expression member of the LayerTreeNode.
LegendNodesSplitBehavior
Legend node column split behavior.
@ AllowSplittingLegendNodesOverMultipleColumns
Allow splitting node's legend nodes across multiple columns.
@ PreventSplittingLegendNodesOverMultipleColumns
Prevent splitting node's legend nodes across multiple columns.
@ UseDefaultLegendSetting
Inherit default legend column splitting setting.
void setLabelExpression(const QString &expression)
set the expression to evaluate
void setPatchShape(const QgsLegendPatchShape &shape)
Sets the symbol patch shape to use when rendering the legend node symbol.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
The QgsLegendRendererItem class is abstract interface for legend items returned from QgsMapLayerLegen...
NodeTypes
Types of legend nodes.
@ SimpleLegend
Simple label with icon legend node type.
@ RasterSymbolLegend
Raster symbol legend node type.
@ ImageLegend
Raster image legend node type.
@ DataDefinedSizeLegend
Marker symbol legend node type.
@ WmsLegend
WMS legend node type.
@ EmbeddedWidget
Embedded widget placeholder node type.
@ ColorRampLegend
Color ramp legend (since QGIS 3.18)
@ SymbolLegend
Vector symbol legend node type.
@ NodeType
Type of node. Added in 3.16.
QgsLayerTreeModel * model() const
Returns pointer to model owning this legend node.
QgsLayerTreeLayer * layerNode() const
Returns pointer to the parent layer node.
QgsLayerTreeModelLegendNode * legendNodeEmbeddedInParent(QgsLayerTreeLayer *nodeLayer) const
Returns legend node that may be embedded in parent (i.e.
QList< QgsLayerTreeModelLegendNode * > layerOriginalLegendNodes(QgsLayerTreeLayer *nodeLayer)
Returns original (unfiltered) list of legend nodes attached to a particular layer node.
This class is a base class for nodes in a layer tree.
void setCustomProperty(const QString &key, const QVariant &value)
Sets a custom property for the node. Properties are stored in a map and saved in project file.
void removeCustomProperty(const QString &key)
Remove a custom property from layer. Properties are stored in a map and saved in project file.
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer. Properties are stored in a map and saved in project file.
QgsLayerTreeNode * parent()
Gets pointer to the parent. If parent is nullptr, the node is a root node.
QStringList customProperties() const
Returns list of keys stored in custom properties.
virtual QgsLayerTreeNode * clone() const =0
Create a copy of the node. Returns new instance.
static void setLegendFilterByExpression(QgsLayerTreeLayer &layer, const QString &expr, bool enabled=true)
Sets the expression filter of a legend layer.
static QString legendFilterByExpression(const QgsLayerTreeLayer &layer, bool *enabled=nullptr)
Returns the expression filter of a legend layer.
The QgsLayerTreeView class extends QTreeView and provides some additional functionality when working ...
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
static bool isLayer(const QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
static bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
static QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group.
Class used to render QgsLayout as an atlas, by iterating over the features from an associated vector ...
void toggled(bool)
Emitted when atlas is enabled or disabled.
A common interface for layout designer dialogs and widgets.
virtual QgsMessageBar * messageBar()=0
Returns the designer's message bar.
void itemChanged(QgsLayoutItem *item)
Emitted whenever the currently selected item changes.
A layout item subclass for map legends.
QgsLegendModel * model()
Returns the legend model.
Layout graphical items for displaying a map.
@ LayoutLegend
Legend item.
Base class for graphical items within a QgsLayout.
@ UndoLegendMinSymbolSize
Legend minimum symbol size.
@ UndoLegendTitleSpaceBottom
Legend title space.
@ UndoLegendIconSymbolSpace
Legend icon symbol space.
@ UndoLegendLayerFont
Legend layer font.
@ UndoLegendBoxSpace
Legend box space.
@ UndoLegendRasterStrokeColor
Legend raster stroke color.
@ UndoLegendTitleFont
Legend title font.
@ UndoLegendItemFont
Legend item font.
@ UndoLegendWmsLegendWidth
Legend WMS width.
@ UndoLegendLayerSpace
Legend layer spacing.
@ UndoLegendColumnSpace
Legend column space.
@ UndoLegendMaxSymbolSize
Legend maximum symbol size.
@ UndoLegendSymbolSpace
Legend symbol spacing.
@ UndoLegendSymbolWidth
Legend symbol width.
@ UndoLegendColumnCount
Legend column count.
@ UndoLegendSymbolHeight
Legend symbol height.
@ UndoLegendGroupSpace
Legend group spacing.
@ UndoLegendSubgroupIndent
Legend subgroup indent.
@ UndoLegendRasterStrokeWidth
Legend raster stroke width.
@ UndoLegendGroupIndent
Legend group indent.
@ UndoLegendText
Legend text.
@ UndoLegendWmsLegendHeight
Legend WMS height.
@ UndoLegendGroupFont
Legend group font.
int type() const override
Returns a unique graphics item type identifier.
A dialog to add new layers to the legend.
This class provides a method of converting QgsLayoutMeasurements from one unit to another.
QgsLayoutMeasurement convert(QgsLayoutMeasurement measurement, Qgis::LayoutUnit targetUnits) const
Converts a measurement from one unit to another.
void setDpi(const double dpi)
Sets the dots per inch (dpi) for the measurement converter.
A model for items attached to a layout.
const QgsLayout * layout() const
Returns the layout the object is attached to.
void changed()
Emitted when the object's properties change.
@ LegendTitle
Legend title.
@ LegendColumnCount
Legend column count.
void layerChanged(QgsVectorLayer *layer)
Emitted when the context's layer is changed.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
QgsLayoutReportContext & reportContext()
Returns a reference to the layout's report context, which stores information relating to the current ...
Item model implementation based on layer tree model for layout legend.
Represents a patch shape for use in map legends.
void setSymbolType(Qgis::SymbolType type)
Sets the symbol type associated with this patch.
bool isNull() const
Returns true if the patch shape is a null QgsLegendPatchShape, which indicates that the default legen...
static void setNodeLegendStyle(QgsLayerTreeNode *node, QgsLegendStyle::Style style)
Sets the style of a node.
static QgsLegendStyle::Style nodeLegendStyle(QgsLayerTreeNode *node, QgsLayerTreeModel *model)
Returns the style for the given node, within the specified model.
static QString styleLabel(Style s)
Returns a translated string representing a style component, for use in UI.
Style
Component of legends which can be styled.
@ Group
Legend group title.
@ Symbol
Symbol icon (excluding label)
@ Subgroup
Legend subgroup title.
@ Hidden
Special style, item is hidden including margins around.
@ SymbolLabel
Symbol label (excluding icon)
Map canvas is a class for displaying all GIS data types on a canvas.
static void setLegendNodeOrder(QgsLayerTreeLayer *nodeLayer, const QList< int > &order)
static void setLegendNodeColorRampSettings(QgsLayerTreeLayer *nodeLayer, int originalIndex, const QgsColorRampLegendNodeSettings *settings)
Sets a custom legend color ramp settings for the legend node belonging to nodeLayer at the specified ...
static void setLegendNodeCustomSymbol(QgsLayerTreeLayer *nodeLayer, int originalIndex, const QgsSymbol *symbol)
Sets a custom legend symbol for the legend node belonging to nodeLayer at the specified originalIndex...
static void setLegendNodeUserLabel(QgsLayerTreeLayer *nodeLayer, int originalIndex, const QString &newLabel)
static void setLegendNodeSymbolSize(QgsLayerTreeLayer *nodeLayer, int originalIndex, QSizeF size)
Sets the legend symbol size for the legend node belonging to nodeLayer at the specified originalIndex...
static void setLegendNodeColumnBreak(QgsLayerTreeLayer *nodeLayer, int originalIndex, bool columnBreakBeforeNode)
Sets whether a forced column break should occur before the node.
static void setLegendNodePatchShape(QgsLayerTreeLayer *nodeLayer, int originalIndex, const QgsLegendPatchShape &shape)
Sets the legend patch shape for the legend node belonging to nodeLayer at the specified originalIndex...
static QList< int > legendNodeOrder(QgsLayerTreeLayer *nodeLayer)
Base class for all map layer types.
Interface for master layout type objects, such as print layouts and reports.
Implementation of legend node interface for displaying preview of vector symbols and their labels and...
Abstract base class for all rendered symbols.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
Represents a vector layer which manages a vector based data sets.
QgsExpressionContextScope * createExpressionContextScope() const FINAL
This method needs to be reimplemented in all classes which implement this interface and return an exp...
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
QgsLayerTreeModelLegendNode * legendNode(const QString &rule, QgsLayerTreeModel &model)
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Q_GUI_EXPORT int qt_defaultDpiX()