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( mMoveDownToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mMoveDownToolButton_clicked );
114 connect( mMoveUpToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mMoveUpToolButton_clicked );
115 connect( mRemoveToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mRemoveToolButton_clicked );
116 connect( mAddToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mAddToolButton_clicked );
117 connect( mEditPushButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mEditPushButton_clicked );
118 connect( mCountToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mCountToolButton_clicked );
119 connect( mExpressionFilterButton, &QgsLegendFilterButton::toggled,
this, &QgsLayoutLegendWidget::mExpressionFilterButton_toggled );
120 connect( mLayerExpressionButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mLayerExpressionButton_clicked );
121 connect( mFilterByMapCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mFilterByMapCheckBox_toggled );
122 connect( mUpdateAllPushButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mUpdateAllPushButton_clicked );
123 connect( mAddGroupToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mAddGroupToolButton_clicked );
124 connect( mFilterLegendByAtlasCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mFilterLegendByAtlasCheckBox_toggled );
125 connect( mItemTreeView, &QgsLayerTreeView::doubleClicked,
this, &QgsLayoutLegendWidget::mItemTreeView_doubleClicked );
127 connect( mFilterByMapCheckBox, &QCheckBox::toggled, mButtonLinkedMaps, &QWidget::setEnabled );
128 mButtonLinkedMaps->setEnabled(
false );
129 connect( mButtonLinkedMaps, &QToolButton::clicked,
this, [ = ]
131 mMapFilteringWidget =
new QgsLayoutLegendMapFilteringWidget( mLegend );
132 openPanel( mMapFilteringWidget );
135 setPanelTitle( tr(
"Legend Properties" ) );
142 mTitleAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
143 mGroupAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
144 mSubgroupAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
145 mItemAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
147 mArrangementCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignRight );
149 mArrangementCombo->customizeAlignmentDisplay( Qt::AlignLeft, tr(
"Symbols on Left" ),
QgsApplication::getThemeIcon( QStringLiteral(
"/mIconArrangeSymbolsLeft.svg" ) ) );
150 mArrangementCombo->customizeAlignmentDisplay( Qt::AlignRight, tr(
"Symbols on Right" ),
QgsApplication::getThemeIcon( QStringLiteral(
"/mIconArrangeSymbolsRight.svg" ) ) );
152 mSpaceBelowGroupHeadingSpinBox->setClearValue( 0 );
153 mGroupSideSpinBox->setClearValue( 0 );
154 mSpaceBelowSubgroupHeadingSpinBox->setClearValue( 0 );
155 mSubgroupSideSpinBox->setClearValue( 0 );
156 mSymbolSideSpaceSpinBox->setClearValue( 0 );
177 mRasterStrokeColorButton->setColorDialogTitle( tr(
"Select Stroke Color" ) );
178 mRasterStrokeColorButton->setAllowOpacity(
true );
179 mRasterStrokeColorButton->setContext( QStringLiteral(
"composer " ) );
181 mMapComboBox->setCurrentLayout( legend->
layout() );
187 mainLayout->addWidget( mItemPropertiesWidget );
189 mItemTreeView->setHeaderHidden(
true );
191 mItemTreeView->setModel( legend->
model() );
192 mItemTreeView->setMenuProvider(
new QgsLayoutLegendMenuProvider( mItemTreeView,
this ) );
193 setLegendMapViewData();
199 connect( layoutAtlas(), &
QgsLayoutAtlas::toggled,
this, &QgsLayoutLegendWidget::updateFilterLegendByAtlasButton );
203 mTitleFontButton->registerExpressionContextGenerator(
this );
204 mGroupFontButton->registerExpressionContextGenerator(
this );
205 mLayerFontButton->registerExpressionContextGenerator(
this );
206 mItemFontButton->registerExpressionContextGenerator(
this );
207 mExpressionFilterButton->registerExpressionContextGenerator(
this );
209 mTitleFontButton->setLayer( coverageLayer() );
210 mGroupFontButton->setLayer( coverageLayer() );
211 mLayerFontButton->setLayer( coverageLayer() );
212 mItemFontButton->setLayer( coverageLayer() );
213 if ( mLegend->layout() )
226 connect( mItemTreeView->selectionModel(), &QItemSelectionModel::currentChanged,
227 this, &QgsLayoutLegendWidget::selectedChanged );
236 if ( mItemPropertiesWidget )
237 mItemPropertiesWidget->setMasterLayout( masterLayout );
243 mTitleFontButton->setMessageBar( iface->
messageBar() );
244 mGroupFontButton->setMessageBar( iface->
messageBar() );
245 mLayerFontButton->setMessageBar( iface->
messageBar() );
246 mItemFontButton->setMessageBar( iface->
messageBar() );
249void QgsLayoutLegendWidget::setGuiElements()
256 blockAllSignals(
true );
257 mTitleLineEdit->setText( mLegend->title() );
258 whileBlocking( mTitleAlignCombo )->setCurrentAlignment( mLegend->titleAlignment() );
262 whileBlocking( mArrangementCombo )->setCurrentAlignment( mLegend->symbolAlignment() );
263 mFilterByMapCheckBox->setChecked( mLegend->legendFilterByMapEnabled() );
264 mButtonLinkedMaps->setEnabled( mLegend->legendFilterByMapEnabled() );
265 mColumnCountSpinBox->setValue( mLegend->columnCount() );
266 mSplitLayerCheckBox->setChecked( mLegend->splitLayer() );
267 mEqualColumnWidthCheckBox->setChecked( mLegend->equalColumnWidth() );
268 mSymbolWidthSpinBox->setValue( mLegend->symbolWidth() );
269 mSymbolHeightSpinBox->setValue( mLegend->symbolHeight() );
270 mMaxSymbolSizeSpinBox->setValue( mLegend->maximumSymbolSize() );
271 mMinSymbolSizeSpinBox->setValue( mLegend->minimumSymbolSize() );
272 mWmsLegendWidthSpinBox->setValue( mLegend->wmsLegendWidth() );
273 mWmsLegendHeightSpinBox->setValue( mLegend->wmsLegendHeight() );
287 mBoxSpaceSpinBox->setValue( mLegend->boxSpace() );
288 mColumnSpaceSpinBox->setValue( mLegend->columnSpace() );
290 mRasterStrokeGroupBox->setChecked( mLegend->drawRasterStroke() );
291 mRasterStrokeWidthSpinBox->setValue( mLegend->rasterStrokeWidth() );
292 mRasterStrokeColorButton->setColor( mLegend->rasterStrokeColor() );
294 mCheckBoxAutoUpdate->setChecked( mLegend->autoUpdateModel() );
296 mCheckboxResizeContents->setChecked( mLegend->resizeToContents() );
297 mFilterLegendByAtlasCheckBox->setChecked( mLegend->legendFilterOutAtlas() );
298 mWrapCharLineEdit->setText( mLegend->wrapString() );
301 mMapComboBox->setItem( map );
307 blockAllSignals(
false );
309 mCheckBoxAutoUpdate_stateChanged( mLegend->autoUpdateModel() ? Qt::Checked : Qt::Unchecked, false );
310 updateDataDefinedButton( mLegendTitleDDBtn );
311 updateDataDefinedButton( mColumnsDDBtn );
314void QgsLayoutLegendWidget::mWrapCharLineEdit_textChanged(
const QString &text )
318 mLegend->beginCommand( tr(
"Change Legend Wrap" ) );
319 mLegend->setWrapString( text );
320 mLegend->adjustBoxSize();
322 mLegend->endCommand();
326void QgsLayoutLegendWidget::mTitleLineEdit_textChanged(
const QString &text )
331 mLegend->setTitle( text );
332 mLegend->adjustBoxSize();
334 mLegend->endCommand();
338void QgsLayoutLegendWidget::titleAlignmentChanged()
342 Qt::AlignmentFlag alignment =
static_cast< Qt::AlignmentFlag
>(
static_cast< int >( mTitleAlignCombo->currentAlignment() & Qt::AlignHorizontal_Mask ) );
343 mLegend->beginCommand( tr(
"Change Title Alignment" ) );
344 mLegend->setTitleAlignment( alignment );
346 mLegend->endCommand();
350void QgsLayoutLegendWidget::groupAlignmentChanged()
354 mLegend->beginCommand( tr(
"Change Group Alignment" ) );
357 mLegend->endCommand();
361void QgsLayoutLegendWidget::subgroupAlignmentChanged()
365 mLegend->beginCommand( tr(
"Change Subgroup Alignment" ) );
368 mLegend->endCommand();
372void QgsLayoutLegendWidget::itemAlignmentChanged()
376 mLegend->beginCommand( tr(
"Change Item Alignment" ) );
379 mLegend->endCommand();
383void QgsLayoutLegendWidget::arrangementChanged()
387 Qt::AlignmentFlag alignment =
static_cast< Qt::AlignmentFlag
>(
static_cast< int >( mArrangementCombo->currentAlignment() & Qt::AlignHorizontal_Mask ) );
388 mLegend->beginCommand( tr(
"Change Legend Arrangement" ) );
389 mLegend->setSymbolAlignment( alignment );
391 mLegend->endCommand();
395void QgsLayoutLegendWidget::mColumnCountSpinBox_valueChanged(
int c )
400 mLegend->setColumnCount(
c );
401 mLegend->adjustBoxSize();
403 mLegend->endCommand();
405 mSplitLayerCheckBox->setEnabled(
c > 1 );
406 mEqualColumnWidthCheckBox->setEnabled(
c > 1 );
409void QgsLayoutLegendWidget::mSplitLayerCheckBox_toggled(
bool checked )
413 mLegend->beginCommand( tr(
"Split Legend Layers" ) );
414 mLegend->setSplitLayer( checked );
415 mLegend->adjustBoxSize();
417 mLegend->endCommand();
421void QgsLayoutLegendWidget::mEqualColumnWidthCheckBox_toggled(
bool checked )
425 mLegend->beginCommand( tr(
"Legend Column Width" ) );
426 mLegend->setEqualColumnWidth( checked );
427 mLegend->adjustBoxSize();
429 mLegend->endCommand();
433void QgsLayoutLegendWidget::mSymbolWidthSpinBox_valueChanged(
double d )
438 mLegend->setSymbolWidth( d );
439 mLegend->adjustBoxSize();
441 mLegend->endCommand();
445void QgsLayoutLegendWidget::mMaxSymbolSizeSpinBox_valueChanged(
double d )
450 mLegend->setMaximumSymbolSize( d );
451 mLegend->adjustBoxSize();
453 mLegend->endCommand();
457void QgsLayoutLegendWidget::mMinSymbolSizeSpinBox_valueChanged(
double d )
462 mLegend->setMinimumSymbolSize( d );
463 mLegend->adjustBoxSize();
465 mLegend->endCommand();
469void QgsLayoutLegendWidget::mSymbolHeightSpinBox_valueChanged(
double d )
474 mLegend->setSymbolHeight( d );
475 mLegend->adjustBoxSize();
477 mLegend->endCommand();
481void QgsLayoutLegendWidget::mWmsLegendWidthSpinBox_valueChanged(
double d )
486 mLegend->setWmsLegendWidth( d );
487 mLegend->adjustBoxSize();
489 mLegend->endCommand();
493void QgsLayoutLegendWidget::mWmsLegendHeightSpinBox_valueChanged(
double d )
498 mLegend->setWmsLegendHeight( d );
499 mLegend->adjustBoxSize();
501 mLegend->endCommand();
505void QgsLayoutLegendWidget::mTitleSpaceBottomSpinBox_valueChanged(
double d )
511 mLegend->adjustBoxSize();
513 mLegend->endCommand();
517void QgsLayoutLegendWidget::mGroupSpaceSpinBox_valueChanged(
double d )
523 mLegend->adjustBoxSize();
525 mLegend->endCommand();
529void QgsLayoutLegendWidget::mGroupIndentSpinBox_valueChanged(
double d )
535 mLegend->adjustBoxSize();
537 mLegend->endCommand();
541void QgsLayoutLegendWidget::mSubgroupIndentSpinBox_valueChanged(
double d )
547 mLegend->adjustBoxSize();
549 mLegend->endCommand();
553void QgsLayoutLegendWidget::spaceBelowGroupHeadingChanged(
double space )
559 mLegend->adjustBoxSize();
561 mLegend->endCommand();
565void QgsLayoutLegendWidget::spaceGroupSideChanged(
double space )
571 mLegend->adjustBoxSize();
573 mLegend->endCommand();
577void QgsLayoutLegendWidget::spaceSubGroupSideChanged(
double space )
583 mLegend->adjustBoxSize();
585 mLegend->endCommand();
589void QgsLayoutLegendWidget::spaceSymbolSideChanged(
double space )
595 mLegend->adjustBoxSize();
597 mLegend->endCommand();
601void QgsLayoutLegendWidget::mLayerSpaceSpinBox_valueChanged(
double d )
607 mLegend->adjustBoxSize();
609 mLegend->endCommand();
613void QgsLayoutLegendWidget::mSymbolSpaceSpinBox_valueChanged(
double d )
621 mLegend->adjustBoxSize();
623 mLegend->endCommand();
627void QgsLayoutLegendWidget::mIconLabelSpaceSpinBox_valueChanged(
double d )
633 mLegend->adjustBoxSize();
635 mLegend->endCommand();
639void QgsLayoutLegendWidget::titleFontChanged()
645 mLegend->adjustBoxSize();
647 mLegend->endCommand();
651void QgsLayoutLegendWidget::groupFontChanged()
657 mLegend->adjustBoxSize();
659 mLegend->endCommand();
663void QgsLayoutLegendWidget::layerFontChanged()
669 mLegend->adjustBoxSize();
671 mLegend->endCommand();
675void QgsLayoutLegendWidget::itemFontChanged()
681 mLegend->adjustBoxSize();
683 mLegend->endCommand();
687void QgsLayoutLegendWidget::spaceBelowSubGroupHeadingChanged(
double space )
693 mLegend->adjustBoxSize();
695 mLegend->endCommand();
699void QgsLayoutLegendWidget::mBoxSpaceSpinBox_valueChanged(
double d )
704 mLegend->setBoxSpace( d );
705 mLegend->adjustBoxSize();
707 mLegend->endCommand();
711void QgsLayoutLegendWidget::mColumnSpaceSpinBox_valueChanged(
double d )
716 mLegend->setColumnSpace( d );
717 mLegend->adjustBoxSize();
719 mLegend->endCommand();
723static void _moveLegendNode(
QgsLayerTreeLayer *nodeLayer,
int legendNodeIndex,
int offset )
727 if ( legendNodeIndex < 0 || legendNodeIndex >= order.count() )
729 if ( legendNodeIndex + offset < 0 || legendNodeIndex + offset >= order.count() )
732 int id = order.takeAt( legendNodeIndex );
733 order.insert( legendNodeIndex + offset,
id );
739void QgsLayoutLegendWidget::mMoveDownToolButton_clicked()
746 const QModelIndex index = mItemTreeView->selectionModel()->currentIndex();
747 const QModelIndex sourceIndex = mItemTreeView->proxyModel()->mapToSource( index );
748 const QModelIndex parentIndex = sourceIndex.parent();
749 if ( !sourceIndex.isValid() || sourceIndex.row() == mItemTreeView->layerTreeModel()->rowCount( parentIndex ) - 1 )
754 if ( !node && !legendNode )
757 mLegend->beginCommand( tr(
"Moved Legend Item Down" ) );
771 mItemTreeView->setCurrentIndex( mItemTreeView->proxyModel()->mapFromSource( mItemTreeView->layerTreeModel()->index( sourceIndex.row() + 1, 0, parentIndex ) ) );
774 mLegend->endCommand();
777void QgsLayoutLegendWidget::mMoveUpToolButton_clicked()
784 const QModelIndex index = mItemTreeView->selectionModel()->currentIndex();
785 const QModelIndex sourceIndex = mItemTreeView->proxyModel()->mapToSource( index );
786 const QModelIndex parentIndex = sourceIndex.parent();
787 if ( !sourceIndex.isValid() || sourceIndex.row() == 0 )
792 if ( !node && !legendNode )
795 mLegend->beginCommand( tr(
"Move Legend Item Up" ) );
809 mItemTreeView->setCurrentIndex( mItemTreeView->proxyModel()->mapFromSource( mItemTreeView->layerTreeModel()->index( sourceIndex.row() - 1, 0, parentIndex ) ) );
812 mLegend->endCommand();
815void QgsLayoutLegendWidget::mCheckBoxAutoUpdate_stateChanged(
int state,
bool userTriggered )
819 mLegend->beginCommand( tr(
"Change Auto Update" ) );
821 mLegend->setAutoUpdateModel( state == Qt::Checked );
823 mLegend->endCommand();
827 QList<QWidget *> widgets;
828 widgets << mMoveDownToolButton << mMoveUpToolButton << mRemoveToolButton << mAddToolButton
829 << mEditPushButton << mCountToolButton << mUpdateAllPushButton << mAddGroupToolButton
830 << mExpressionFilterButton;
831 for ( QWidget *w : std::as_const( widgets ) )
832 w->setEnabled( state != Qt::Checked );
834 if ( state == Qt::Unchecked )
837 selectedChanged( QModelIndex(), QModelIndex() );
841void QgsLayoutLegendWidget::composerMapChanged(
QgsLayoutItem *item )
857 mLegend->beginCommand( tr(
"Change Legend Map" ) );
858 mLegend->setLinkedMap( map );
860 mLegend->endCommand();
862 setLegendMapViewData();
866void QgsLayoutLegendWidget::mCheckboxResizeContents_toggled(
bool checked )
873 mLegend->beginCommand( tr(
"Resize Legend to Contents" ) );
874 mLegend->setResizeToContents( checked );
876 mLegend->adjustBoxSize();
878 mLegend->endCommand();
881void QgsLayoutLegendWidget::mRasterStrokeGroupBox_toggled(
bool state )
888 mLegend->beginCommand( tr(
"Change Legend Borders" ) );
889 mLegend->setDrawRasterStroke( state );
890 mLegend->adjustBoxSize();
892 mLegend->endCommand();
895void QgsLayoutLegendWidget::mRasterStrokeWidthSpinBox_valueChanged(
double d )
903 mLegend->setRasterStrokeWidth( d );
904 mLegend->adjustBoxSize();
906 mLegend->endCommand();
909void QgsLayoutLegendWidget::mRasterStrokeColorButton_colorChanged(
const QColor &newColor )
917 mLegend->setRasterStrokeColor( newColor );
919 mLegend->endCommand();
922void QgsLayoutLegendWidget::mAddToolButton_clicked()
929 QList< QgsMapLayer * > visibleLayers;
930 if ( mLegend->linkedMap() )
932 visibleLayers = mLegend->linkedMap()->layersToRender();
934 if ( visibleLayers.isEmpty() )
937 visibleLayers = mMapCanvas->layers(
true );
941 addDialog.setVisibleLayers( visibleLayers );
942 if ( addDialog.exec() == QDialog::Accepted )
944 const QList<QgsMapLayer *> layers = addDialog.selectedLayers();
945 if ( !layers.empty() )
947 mLegend->beginCommand( tr(
"Add Legend Item(s)" ) );
950 mLegend->model()->rootGroup()->addLayer( layer );
952 mLegend->updateLegend();
954 mLegend->endCommand();
959void QgsLayoutLegendWidget::mRemoveToolButton_clicked()
966 QItemSelectionModel *selectionModel = mItemTreeView->selectionModel();
967 if ( !selectionModel )
972 mLegend->beginCommand( tr(
"Remove Legend Item" ) );
974 QList<QPersistentModelIndex> proxyIndexes;
975 const QModelIndexList viewSelection = selectionModel->selectedIndexes();
976 for (
const QModelIndex &index : viewSelection )
977 proxyIndexes << index;
980 QHash<QgsLayerTreeLayer *, QList<int> > nodesWithRemoval;
981 for (
const QPersistentModelIndex &proxyIndex : std::as_const( proxyIndexes ) )
986 nodesWithRemoval[nodeLayer].append( _unfilteredLegendNodeIndex( legendNode ) );
989 for (
auto it = nodesWithRemoval.constBegin(); it != nodesWithRemoval.constEnd(); ++it )
991 QList<int> toDelete = it.value();
992 std::sort( toDelete.begin(), toDelete.end(), std::greater<int>() );
995 for (
int i : std::as_const( toDelete ) )
997 if ( i >= 0 && i < order.count() )
1002 mItemTreeView->layerTreeModel()->refreshLayerLegend( it.key() );
1006 for (
const QPersistentModelIndex &proxyIndex : std::as_const( proxyIndexes ) )
1008 if ( proxyIndex.isValid() && mItemTreeView->index2node( proxyIndex ) )
1010 const QModelIndex sourceIndex = mItemTreeView->proxyModel()->mapToSource( proxyIndex );
1011 mLegend->model()->removeRow( sourceIndex.row(), sourceIndex.parent() );
1015 mLegend->updateLegend();
1017 mLegend->endCommand();
1020void QgsLayoutLegendWidget::mEditPushButton_clicked()
1027 QModelIndex idx = mItemTreeView->selectionModel()->currentIndex();
1028 mItemTreeView_doubleClicked( idx );
1031void QgsLayoutLegendWidget::resetLayerNodeToDefaults()
1039 QModelIndex currentIndex = mItemTreeView->currentIndex();
1040 if ( !currentIndex.isValid() )
1059 mLegend->beginCommand( tr(
"Update Legend" ) );
1062 for (
const QString &key : constCustomProperties )
1064 if ( key.startsWith( QLatin1String(
"legend/" ) ) )
1071 mItemTreeView->layerTreeModel()->refreshLayerLegend( nodeLayer );
1073 mLegend->updateLegend();
1075 mLegend->endCommand();
1078void QgsLayoutLegendWidget::mCountToolButton_clicked(
bool checked )
1085 const QList< QModelIndex > selectedIndexes = mItemTreeView->selectionModel()->selectedIndexes();
1086 if ( selectedIndexes.empty() )
1089 mLegend->beginCommand( tr(
"Update Legend" ) );
1090 for (
const QModelIndex &index : selectedIndexes )
1096 currentNode->
setCustomProperty( QStringLiteral(
"showFeatureCount" ), checked ? 1 : 0 );
1098 mLegend->updateFilterByMap();
1099 mLegend->adjustBoxSize();
1100 mLegend->endCommand();
1103void QgsLayoutLegendWidget::mFilterByMapCheckBox_toggled(
bool checked )
1105 mLegend->beginCommand( tr(
"Update Legend" ) );
1106 mLegend->setLegendFilterByMapEnabled( checked );
1107 mLegend->adjustBoxSize();
1109 mLegend->endCommand();
1112void QgsLayoutLegendWidget::mExpressionFilterButton_toggled(
bool checked )
1120 QModelIndex currentIndex = mItemTreeView->currentIndex();
1121 if ( !currentIndex.isValid() )
1131 mExpressionFilterButton->expressionText(),
1134 mLegend->beginCommand( tr(
"Update Legend" ) );
1135 mLegend->updateFilterByMap();
1136 mLegend->adjustBoxSize();
1137 mLegend->endCommand();
1140void QgsLayoutLegendWidget::mLayerExpressionButton_clicked()
1147 QModelIndex currentIndex = mItemTreeView->currentIndex();
1148 if ( !currentIndex.isValid() )
1155 QgsLayerTreeLayer *layerNode = qobject_cast<QgsLayerTreeLayer *>( currentNode );
1161 QString currentExpression;
1163 currentExpression = QStringLiteral(
"@symbol_label" );
1173 QStringList highlighted;
1178 if ( !legendSymbols.empty() )
1184 highlighted << QStringLiteral(
"symbol_label" ) << QStringLiteral(
"symbol_id" );
1186 highlighted << QStringLiteral(
"symbol_count" );
1200 QgsExpressionBuilderDialog expressiondialog(
nullptr, currentExpression,
nullptr, QStringLiteral(
"generic" ), legendContext );
1201 if ( expressiondialog.exec() )
1204 mLegend->beginCommand( tr(
"Update Legend" ) );
1206 mLegend->adjustBoxSize();
1207 mLegend->endCommand();
1210void QgsLayoutLegendWidget::mUpdateAllPushButton_clicked()
1215void QgsLayoutLegendWidget::mAddGroupToolButton_clicked()
1219 mLegend->beginCommand( tr(
"Add Legend Group" ) );
1220 mLegend->model()->rootGroup()->addGroup( tr(
"Group" ) );
1221 mLegend->updateLegend();
1223 mLegend->endCommand();
1227void QgsLayoutLegendWidget::mFilterLegendByAtlasCheckBox_toggled(
bool toggled )
1232 mLegend->setLegendFilterOutAtlas( toggled );
1238void QgsLayoutLegendWidget::updateLegend()
1242 mLegend->beginCommand( tr(
"Update Legend" ) );
1245 mLegend->setAutoUpdateModel(
true );
1246 mLegend->setAutoUpdateModel(
false );
1248 mLegend->endCommand();
1252void QgsLayoutLegendWidget::setReportTypeString(
const QString &
string )
1254 mFilterLegendByAtlasCheckBox->setText( tr(
"Only show items inside current %1 feature" ).arg(
string ) );
1255 mFilterLegendByAtlasCheckBox->setToolTip( tr(
"Filter out legend elements that lie outside the current %1 feature." ).arg(
string ) );
1264bool QgsLayoutLegendWidget::setNewItem(
QgsLayoutItem *item )
1274 mLegend = qobject_cast< QgsLayoutItemLegend * >( item );
1275 mItemPropertiesWidget->setItem( mLegend );
1277 if ( mMapFilteringWidget )
1278 mMapFilteringWidget->setItem( mLegend );
1282 mItemTreeView->setModel( mLegend->model() );
1291void QgsLayoutLegendWidget::blockAllSignals(
bool b )
1293 mTitleLineEdit->blockSignals( b );
1294 mTitleAlignCombo->blockSignals( b );
1295 mItemTreeView->blockSignals( b );
1296 mCheckBoxAutoUpdate->blockSignals( b );
1297 mMapComboBox->blockSignals( b );
1298 mFilterByMapCheckBox->blockSignals( b );
1299 mColumnCountSpinBox->blockSignals( b );
1300 mSplitLayerCheckBox->blockSignals( b );
1301 mEqualColumnWidthCheckBox->blockSignals( b );
1302 mSymbolWidthSpinBox->blockSignals( b );
1303 mSymbolHeightSpinBox->blockSignals( b );
1304 mMaxSymbolSizeSpinBox->blockSignals( b );
1305 mMinSymbolSizeSpinBox->blockSignals( b );
1306 mGroupSpaceSpinBox->blockSignals( b );
1307 mGroupIndentSpinBox->blockSignals( b );
1308 mSubgroupIndentSpinBox->blockSignals( b );
1309 mSpaceBelowGroupHeadingSpinBox->blockSignals( b );
1310 mGroupSideSpinBox->blockSignals( b );
1311 mSpaceBelowSubgroupHeadingSpinBox->blockSignals( b );
1312 mSubgroupSideSpinBox->blockSignals( b );
1313 mLayerSpaceSpinBox->blockSignals( b );
1314 mSymbolSpaceSpinBox->blockSignals( b );
1315 mSymbolSideSpaceSpinBox->blockSignals( b );
1316 mIconLabelSpaceSpinBox->blockSignals( b );
1317 mBoxSpaceSpinBox->blockSignals( b );
1318 mColumnSpaceSpinBox->blockSignals( b );
1319 mRasterStrokeGroupBox->blockSignals( b );
1320 mRasterStrokeColorButton->blockSignals( b );
1321 mRasterStrokeWidthSpinBox->blockSignals( b );
1322 mWmsLegendWidthSpinBox->blockSignals( b );
1323 mWmsLegendHeightSpinBox->blockSignals( b );
1324 mCheckboxResizeContents->blockSignals( b );
1325 mTitleSpaceBottomSpinBox->blockSignals( b );
1326 mFilterLegendByAtlasCheckBox->blockSignals( b );
1327 mTitleFontButton->blockSignals( b );
1328 mGroupFontButton->blockSignals( b );
1329 mLayerFontButton->blockSignals( b );
1330 mItemFontButton->blockSignals( b );
1331 mWrapCharLineEdit->blockSignals( b );
1334void QgsLayoutLegendWidget::selectedChanged(
const QModelIndex ¤t,
const QModelIndex &previous )
1337 Q_UNUSED( previous )
1339 mLayerExpressionButton->setEnabled(
false );
1341 if ( mLegend && mLegend->autoUpdateModel() )
1352 mLayerExpressionButton->setEnabled(
true );
1356 mCountToolButton->setChecked(
false );
1357 mCountToolButton->setEnabled(
false );
1360 mExpressionFilterButton->blockSignals(
true );
1361 mExpressionFilterButton->setChecked(
false );
1362 mExpressionFilterButton->setEnabled(
false );
1363 mExpressionFilterButton->blockSignals(
false );
1374 mCountToolButton->setChecked( currentNode->
customProperty( QStringLiteral(
"showFeatureCount" ), 0 ).toInt() );
1375 mCountToolButton->setEnabled(
true );
1376 mLayerExpressionButton->setEnabled(
true );
1380 mExpressionFilterButton->blockSignals(
true );
1381 mExpressionFilterButton->setExpressionText( expr );
1382 mExpressionFilterButton->setVectorLayer( vl );
1383 mExpressionFilterButton->setEnabled(
true );
1384 mExpressionFilterButton->setChecked( exprEnabled );
1385 mExpressionFilterButton->blockSignals(
false );
1388void QgsLayoutLegendWidget::setCurrentNodeStyleFromAction()
1390 QAction *a = qobject_cast<QAction *>( sender() );
1391 if ( !a || !mItemTreeView->currentNode() )
1398void QgsLayoutLegendWidget::setLegendMapViewData()
1400 if ( mLegend->linkedMap() )
1404 measurementConverter.
setDpi( dpi );
1407 double mapUnitsPerPixelX = mLegend->linkedMap()->extent().width() / mapWidth;
1408 double mapUnitsPerPixelY = mLegend->linkedMap()->extent().height() / mapHeight;
1409 mLegend->model()->setLegendMapViewData( ( mapUnitsPerPixelX > mapUnitsPerPixelY ? mapUnitsPerPixelX : mapUnitsPerPixelY ), dpi, mLegend->linkedMap()->scale() );
1413void QgsLayoutLegendWidget::updateFilterLegendByAtlasButton()
1417 mFilterLegendByAtlasCheckBox->setEnabled( atlas->enabled() && mLegend->layout()->reportContext().layer() && mLegend->layout()->reportContext().layer()->geometryType() ==
Qgis::GeometryType::Polygon );
1421void QgsLayoutLegendWidget::mItemTreeView_doubleClicked(
const QModelIndex &idx )
1423 if ( !mLegend || !idx.isValid() )
1428 if ( mLegend->autoUpdateModel() )
1434 int originalIndex = -1;
1437 originalIndex = _originalLegendNodeIndex( legendNode );
1441 QgsLayoutLegendNodeWidget *widget =
new QgsLayoutLegendNodeWidget( mLegend, currentNode, legendNode, originalIndex );
1442 openPanel( widget );
1450QgsLayoutLegendMenuProvider::QgsLayoutLegendMenuProvider(
QgsLayerTreeView *view, QgsLayoutLegendWidget *w )
1455QMenu *QgsLayoutLegendMenuProvider::createContextMenu()
1457 if ( !mView->currentNode() )
1460 if ( mWidget->legend()->autoUpdateModel() )
1463 QMenu *menu =
new QMenu();
1467 menu->addAction( QObject::tr(
"Reset to Defaults" ), mWidget, &QgsLayoutLegendWidget::resetLayerNodeToDefaults );
1468 menu->addSeparator();
1473 QList<QgsLegendStyle::Style> lst;
1477 QAction *action = menu->addAction(
QgsLegendStyle::styleLabel( style ), mWidget, &QgsLayoutLegendWidget::setCurrentNodeStyleFromAction );
1478 action->setCheckable(
true );
1479 action->setChecked( currentStyle == style );
1480 action->setData(
static_cast< int >( style ) );
1495 , mOriginalLegendNodeIndex( originalLegendNodeIndex )
1498 setPanelTitle( tr(
"Legend Item Properties" ) );
1507 QString currentLabel;
1510 currentLabel = mLegendNode->data( Qt::EditRole ).toString();
1511 mColumnBreakBeforeCheckBox->setChecked( mLegendNode->columnBreak() );
1515 currentLabel = mLayer->name();
1516 QVariant v = mLayer->customProperty( QStringLiteral(
"legend/title-label" ) );
1518 currentLabel = v.toString();
1519 mColumnBreakBeforeCheckBox->setChecked( mLayer->customProperty( QStringLiteral(
"legend/column-break" ) ).toInt() );
1521 mColumnSplitBehaviorComboBox->setCurrentIndex( mColumnSplitBehaviorComboBox->findData( mLayer->legendSplitBehavior() ) );
1526 mColumnBreakBeforeCheckBox->setChecked( mNode->customProperty( QStringLiteral(
"legend/column-break" ) ).toInt() );
1529 mWidthSpinBox->setClearValue( 0, tr(
"Default" ) );
1530 mHeightSpinBox->setClearValue( 0, tr(
"Default" ) );
1531 mWidthSpinBox->setVisible( mLegendNode || mLayer );
1532 mHeightSpinBox->setVisible( mLegendNode || mLayer );
1533 mPatchGroup->setVisible( mLegendNode || mLayer );
1534 mPatchWidthLabel->setVisible( mLegendNode || mLayer );
1535 mPatchHeightLabel->setVisible( mLegendNode || mLayer );
1536 mCustomSymbolCheckBox->setVisible( mLegendNode || mLegend->model()->legendNodeEmbeddedInParent( mLayer ) );
1537 mColumnSplitLabel->setVisible( mLayer && !mLegendNode );
1538 mColumnSplitBehaviorComboBox->setVisible( mLayer && !mLegendNode );
1541 mWidthSpinBox->setValue( mLegendNode->userPatchSize().width() );
1542 mHeightSpinBox->setValue( mLegendNode->userPatchSize().height() );
1546 mWidthSpinBox->setValue( mLayer->patchSize().width() );
1547 mHeightSpinBox->setValue( mLayer->patchSize().height() );
1550 mCustomSymbolCheckBox->setChecked(
false );
1555 patchShape = symbolLegendNode->patchShape();
1557 std::unique_ptr< QgsSymbol > customSymbol( symbolLegendNode->customSymbol() ? symbolLegendNode->customSymbol()->clone() : nullptr );
1558 mCustomSymbolCheckBox->setChecked( customSymbol.get() );
1561 mPatchShapeButton->setPreviewSymbol( customSymbol->clone() );
1563 mCustomSymbolButton->setSymbol( customSymbol.release() );
1565 else if ( symbolLegendNode->symbol() )
1567 mPatchShapeButton->setPreviewSymbol( symbolLegendNode->symbol()->clone() );
1568 mCustomSymbolButton->setSymbolType( symbolLegendNode->symbol()->type() );
1569 mCustomSymbolButton->setSymbol( symbolLegendNode->symbol()->clone() );
1572 else if ( !mLegendNode && mLayer )
1574 patchShape = mLayer->patchShape();
1577 if (
QgsSymbol *customSymbol = symbolLegendNode->customSymbol() )
1579 mCustomSymbolCheckBox->setChecked(
true );
1580 mPatchShapeButton->setPreviewSymbol( customSymbol->clone() );
1582 mCustomSymbolButton->setSymbol( customSymbol->clone() );
1586 mPatchShapeButton->setPreviewSymbol( symbolLegendNode->symbol()->clone() );
1587 mCustomSymbolButton->setSymbolType( symbolLegendNode->symbol()->type() );
1588 mCustomSymbolButton->setSymbol( symbolLegendNode->symbol()->clone() );
1595 switch ( qobject_cast< QgsVectorLayer * >( mLayer->layer() )->geometryType() )
1610 mPatchShapeLabel->hide();
1611 mPatchShapeButton->hide();
1614 if ( !patchShape.
isNull() )
1615 mPatchShapeButton->setShape( patchShape );
1620 if ( symbolLegendNode->symbol() )
1622 mPatchShapeButton->setSymbolType( symbolLegendNode->symbol()->type() );
1626 mPatchShapeLabel->hide();
1627 mPatchShapeButton->hide();
1632 mPatchShapeLabel->hide();
1633 mPatchShapeButton->hide();
1638 mLabelGroup->hide();
1639 mColorRampLegendWidget->setSettings( colorRampNode->settings() );
1643 mColorRampLegendWidget->hide();
1656 mCustomSymbolCheckBox->hide();
1665 mLabelEdit->setPlainText( currentLabel );
1666 connect( mLabelEdit, &QPlainTextEdit::textChanged,
this, &QgsLayoutLegendNodeWidget::labelChanged );
1668 connect( mInsertExpressionButton, &QPushButton::clicked,
this, &QgsLayoutLegendNodeWidget::insertExpression );
1670 connect( mWidthSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendNodeWidget::sizeChanged );
1671 connect( mHeightSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendNodeWidget::sizeChanged );
1673 connect( mCustomSymbolCheckBox, &QGroupBox::toggled,
this, &QgsLayoutLegendNodeWidget::customSymbolChanged );
1676 connect( mColumnBreakBeforeCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendNodeWidget::columnBreakToggled );
1678 connect( mColumnSplitBehaviorComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsLayoutLegendNodeWidget::columnSplitChanged );
1682 connectChildPanel( mColorRampLegendWidget );
1685void QgsLayoutLegendNodeWidget::setDockMode(
bool dockMode )
1687 mColorRampLegendWidget->setDockMode( dockMode );
1691void QgsLayoutLegendNodeWidget::labelChanged()
1695 const QString label = mLabelEdit->toPlainText();
1700 else if ( mLegendNode )
1703 mLegend->model()->refreshLayerLegend( mLayer );
1707 mLayer->setCustomProperty( QStringLiteral(
"legend/title-label" ), label );
1711 embeddedNode->setUserLabel( QString() );
1714 mLegend->adjustBoxSize();
1715 mLegend->invalidateCache();
1717 mLegend->endCommand();
1720void QgsLayoutLegendNodeWidget::patchChanged()
1722 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1728 mLegend->model()->refreshLayerLegend( mLayer );
1732 mLayer->setPatchShape( shape );
1733 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1738 mLegend->model()->refreshLayerLegend( mLayer );
1741 mLegend->adjustBoxSize();
1743 mLegend->endCommand();
1746void QgsLayoutLegendNodeWidget::insertExpression()
1754 QgsVectorLayer *layer = mLegend->layout() ? mLegend->layout()->reportContext().layer() :
nullptr;
1758 if ( mLayer && mLayer->layer() )
1764 << QStringLiteral(
"legend_column_count" )
1765 << QStringLiteral(
"legend_split_layers" )
1766 << QStringLiteral(
"legend_wrap_string" )
1767 << QStringLiteral(
"legend_filter_by_map" )
1768 << QStringLiteral(
"legend_filter_out_atlas" ) );
1772 exprDlg.setWindowTitle( tr(
"Insert Expression" ) );
1773 if ( exprDlg.exec() == QDialog::Accepted )
1775 expression = exprDlg.expressionText();
1776 if ( !expression.isEmpty() )
1778 mLegend->beginCommand( tr(
"Insert expression" ) );
1779 mLabelEdit->insertPlainText(
"[%" + expression.trimmed() +
"%]" );
1780 mLegend->endCommand();
1785void QgsLayoutLegendNodeWidget::sizeChanged(
double )
1787 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1788 const QSizeF size = QSizeF( mWidthSpinBox->value(), mHeightSpinBox->value() );
1793 mLegend->model()->refreshLayerLegend( mLayer );
1797 mLayer->setPatchSize( size );
1798 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1803 mLegend->model()->refreshLayerLegend( mLayer );
1806 mLegend->adjustBoxSize();
1808 mLegend->endCommand();
1811void QgsLayoutLegendNodeWidget::customSymbolChanged()
1813 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1815 if ( mCustomSymbolCheckBox->isChecked() )
1820 mLegend->model()->refreshLayerLegend( mLayer );
1824 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1829 mLegend->model()->refreshLayerLegend( mLayer );
1837 mLegend->model()->refreshLayerLegend( mLayer );
1841 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1846 mLegend->model()->refreshLayerLegend( mLayer );
1850 mLegend->adjustBoxSize();
1852 mLegend->endCommand();
1855void QgsLayoutLegendNodeWidget::colorRampLegendChanged()
1857 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1861 mLegend->model()->refreshLayerLegend( mLayer );
1863 mLegend->adjustBoxSize();
1865 mLegend->endCommand();
1868void QgsLayoutLegendNodeWidget::columnBreakToggled(
bool checked )
1870 mLegend->beginCommand( tr(
"Edit Legend Columns" ) );
1875 mLegend->model()->refreshLayerLegend( mLayer );
1879 mLayer->setCustomProperty( QStringLiteral(
"legend/column-break" ), QString( checked ?
'1' :
'0' ) );
1883 mNode->setCustomProperty( QStringLiteral(
"legend/column-break" ), QString( checked ?
'1' :
'0' ) );
1886 mLegend->adjustBoxSize();
1888 mLegend->endCommand();
1891void QgsLayoutLegendNodeWidget::columnSplitChanged()
1893 mLegend->beginCommand( tr(
"Edit Legend Columns" ) );
1895 if ( mLayer && !mLegendNode )
1900 mLegend->adjustBoxSize();
1902 mLegend->endCommand();
1909QgsLayoutLegendMapFilteringWidget::QgsLayoutLegendMapFilteringWidget(
QgsLayoutItemLegend *legend )
1911 , mLegendItem( legend )
1914 setPanelTitle( tr(
"Legend Filtering" ) );
1916 setNewItem( legend );
1919bool QgsLayoutLegendMapFilteringWidget::setNewItem(
QgsLayoutItem *item )
1929 mLegendItem = qobject_cast< QgsLayoutItemLegend * >( item );
1936 updateGuiElements();
1941void QgsLayoutLegendMapFilteringWidget::updateGuiElements()
1943 if ( mBlockUpdates )
1946 mBlockUpdates =
true;
1948 if ( mFilterMapItemsListView->model() )
1950 QAbstractItemModel *oldModel = mFilterMapItemsListView->model();
1951 mFilterMapItemsListView->setModel(
nullptr );
1952 oldModel->deleteLater();
1955 QgsLayoutLegendMapFilteringModel *model =
new QgsLayoutLegendMapFilteringModel( mLegendItem, mLegendItem->layout()->itemsModel(), mFilterMapItemsListView );
1956 mFilterMapItemsListView->setModel( model );
1958 mBlockUpdates =
false;
1966 : QSortFilterProxyModel( parent )
1967 , mLayoutModel( layoutModel )
1968 , mLegendItem( legend )
1970 setSourceModel( layoutModel );
1973int QgsLayoutLegendMapFilteringModel::columnCount(
const QModelIndex & )
const
1978QVariant QgsLayoutLegendMapFilteringModel::data(
const QModelIndex &i,
int role )
const
1983 if ( i.column() != 0 )
1988 QgsLayoutItemMap *mapItem = qobject_cast< QgsLayoutItemMap * >( mLayoutModel->itemFromIndex( mapToSource( i ) ) );
1996 case Qt::CheckStateRole:
1997 switch ( i.column() )
2002 return Qt::Unchecked;
2004 return mLegendItem->filterByMapItems().contains( mapItem ) ? Qt::Checked : Qt::Unchecked;
2012 return mLayoutModel->data( sourceIndex, role );
2016bool QgsLayoutLegendMapFilteringModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
2020 if ( !index.isValid() )
2023 QgsLayoutItemMap *mapItem = qobject_cast< QgsLayoutItemMap * >( mLayoutModel->itemFromIndex( mapToSource( index ) ) );
2024 if ( !mapItem || !mLegendItem )
2029 mLegendItem->layout()->undoStack()->beginCommand( mLegendItem, tr(
"Change Legend Linked Maps" ) );
2031 QList< QgsLayoutItemMap * > linkedMaps = mLegendItem->filterByMapItems();
2032 if ( value.toBool() )
2034 if ( !linkedMaps.contains( mapItem ) )
2036 linkedMaps.append( mapItem );
2037 mLegendItem->setFilterByMapItems( linkedMaps );
2042 linkedMaps.removeAll( mapItem );
2043 mLegendItem->setFilterByMapItems( linkedMaps );
2045 emit dataChanged( index, index, QVector<int>() << role );
2047 mLegendItem->layout()->undoStack()->endCommand();
2048 mLegendItem->invalidateCache();
2053Qt::ItemFlags QgsLayoutLegendMapFilteringModel::flags(
const QModelIndex &index )
const
2055 Qt::ItemFlags flags = QSortFilterProxyModel::flags( index );
2057 if ( ! index.isValid() )
2062 QgsLayoutItemMap *mapItem = qobject_cast< QgsLayoutItemMap * >( mLayoutModel->itemFromIndex( mapToSource( index ) ) );
2063 const bool isMainLinkedMapItem = mLegendItem ? ( mLegendItem->linkedMap() == mapItem ) : false;
2069 if ( !isMainLinkedMapItem )
2071 flags |= Qt::ItemIsEnabled;
2075 flags &= ~Qt::ItemIsEnabled;
2078 switch ( index.column() )
2081 if ( !isMainLinkedMapItem )
2082 return flags | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
2084 return flags | Qt::ItemIsSelectable;
2087 return flags | Qt::ItemIsSelectable;
2091bool QgsLayoutLegendMapFilteringModel::filterAcceptsRow(
int source_row,
const QModelIndex &source_parent )
const
2093 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.
static QString findAndSelectActiveExpression(QgsCodeEditor *editor, const QString &pattern=QString())
Find the expression under the cursor in the given editor and select it.
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.
@ 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 ...
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...
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.