47#include <QInputDialog>
64 int unfilteredNodeIndex = _unfilteredLegendNodeIndex(
legendNode );
66 return ( unfilteredNodeIndex >= 0 && unfilteredNodeIndex < order.count() ? order[unfilteredNodeIndex] : -1 );
73 , mMapCanvas( mapCanvas )
78 connect( mWrapCharLineEdit, &QLineEdit::textChanged,
this, &QgsLayoutLegendWidget::mWrapCharLineEdit_textChanged );
79 connect( mTitleLineEdit, &QLineEdit::textChanged,
this, &QgsLayoutLegendWidget::mTitleLineEdit_textChanged );
84 connect( mColumnCountSpinBox,
static_cast < void ( QSpinBox::* )(
int )
> ( &QSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mColumnCountSpinBox_valueChanged );
85 connect( mSplitLayerCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mSplitLayerCheckBox_toggled );
86 connect( mEqualColumnWidthCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mEqualColumnWidthCheckBox_toggled );
87 connect( mSymbolWidthSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mSymbolWidthSpinBox_valueChanged );
88 connect( mSymbolHeightSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mSymbolHeightSpinBox_valueChanged );
89 connect( mMaxSymbolSizeSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mMaxSymbolSizeSpinBox_valueChanged );
90 connect( mMinSymbolSizeSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mMinSymbolSizeSpinBox_valueChanged );
91 connect( mWmsLegendWidthSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mWmsLegendWidthSpinBox_valueChanged );
92 connect( mWmsLegendHeightSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mWmsLegendHeightSpinBox_valueChanged );
93 connect( mTitleSpaceBottomSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mTitleSpaceBottomSpinBox_valueChanged );
94 connect( mGroupSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mGroupSpaceSpinBox_valueChanged );
95 connect( mGroupIndentSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mGroupIndentSpinBox_valueChanged );
96 connect( mSubgroupIndentSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mSubgroupIndentSpinBox_valueChanged );
97 connect( mSpaceBelowGroupHeadingSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceBelowGroupHeadingChanged );
98 connect( mGroupSideSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceGroupSideChanged );
99 connect( mLayerSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mLayerSpaceSpinBox_valueChanged );
100 connect( mSpaceBelowSubgroupHeadingSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceBelowSubGroupHeadingChanged );
101 connect( mSubgroupSideSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceSubGroupSideChanged );
102 connect( mSymbolSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mSymbolSpaceSpinBox_valueChanged );
103 connect( mSymbolSideSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::spaceSymbolSideChanged );
104 connect( mIconLabelSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mIconLabelSpaceSpinBox_valueChanged );
105 connect( mBoxSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mBoxSpaceSpinBox_valueChanged );
106 connect( mColumnSpaceSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mColumnSpaceSpinBox_valueChanged );
107 connect( mCheckBoxAutoUpdate, &QCheckBox::stateChanged,
this, [ = ](
int state ) { mCheckBoxAutoUpdate_stateChanged( state ); } );
108 connect( mCheckboxResizeContents, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mCheckboxResizeContents_toggled );
109 connect( mRasterStrokeGroupBox, &QgsCollapsibleGroupBoxBasic::toggled,
this, &QgsLayoutLegendWidget::mRasterStrokeGroupBox_toggled );
110 connect( mRasterStrokeWidthSpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendWidget::mRasterStrokeWidthSpinBox_valueChanged );
111 connect( mRasterStrokeColorButton, &
QgsColorButton::colorChanged,
this, &QgsLayoutLegendWidget::mRasterStrokeColorButton_colorChanged );
112 connect( mMoveDownToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mMoveDownToolButton_clicked );
113 connect( mMoveUpToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mMoveUpToolButton_clicked );
114 connect( mRemoveToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mRemoveToolButton_clicked );
115 connect( mAddToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mAddToolButton_clicked );
116 connect( mEditPushButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mEditPushButton_clicked );
117 connect( mCountToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mCountToolButton_clicked );
118 connect( mExpressionFilterButton, &QgsLegendFilterButton::toggled,
this, &QgsLayoutLegendWidget::mExpressionFilterButton_toggled );
119 connect( mLayerExpressionButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mLayerExpressionButton_clicked );
120 connect( mFilterByMapCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mFilterByMapCheckBox_toggled );
121 connect( mUpdateAllPushButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mUpdateAllPushButton_clicked );
122 connect( mAddGroupToolButton, &QToolButton::clicked,
this, &QgsLayoutLegendWidget::mAddGroupToolButton_clicked );
123 connect( mFilterLegendByAtlasCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendWidget::mFilterLegendByAtlasCheckBox_toggled );
124 connect( mItemTreeView, &QgsLayerTreeView::doubleClicked,
this, &QgsLayoutLegendWidget::mItemTreeView_doubleClicked );
126 connect( mFilterByMapCheckBox, &QCheckBox::toggled, mButtonLinkedMaps, &QWidget::setEnabled );
127 mButtonLinkedMaps->setEnabled(
false );
128 connect( mButtonLinkedMaps, &QToolButton::clicked,
this, [ = ]
130 mMapFilteringWidget =
new QgsLayoutLegendMapFilteringWidget( mLegend );
131 openPanel( mMapFilteringWidget );
134 setPanelTitle( tr(
"Legend Properties" ) );
141 mTitleAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
142 mGroupAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
143 mSubgroupAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
144 mItemAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
146 mArrangementCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignRight );
148 mArrangementCombo->customizeAlignmentDisplay( Qt::AlignLeft, tr(
"Symbols on Left" ),
QgsApplication::getThemeIcon( QStringLiteral(
"/mIconArrangeSymbolsLeft.svg" ) ) );
149 mArrangementCombo->customizeAlignmentDisplay( Qt::AlignRight, tr(
"Symbols on Right" ),
QgsApplication::getThemeIcon( QStringLiteral(
"/mIconArrangeSymbolsRight.svg" ) ) );
151 mSpaceBelowGroupHeadingSpinBox->setClearValue( 0 );
152 mGroupSideSpinBox->setClearValue( 0 );
153 mSpaceBelowSubgroupHeadingSpinBox->setClearValue( 0 );
154 mSubgroupSideSpinBox->setClearValue( 0 );
155 mSymbolSideSpaceSpinBox->setClearValue( 0 );
176 mRasterStrokeColorButton->setColorDialogTitle( tr(
"Select Stroke Color" ) );
177 mRasterStrokeColorButton->setAllowOpacity(
true );
178 mRasterStrokeColorButton->setContext( QStringLiteral(
"composer " ) );
180 mMapComboBox->setCurrentLayout( legend->
layout() );
186 mainLayout->addWidget( mItemPropertiesWidget );
188 mItemTreeView->setHeaderHidden(
true );
190 mItemTreeView->setModel( legend->
model() );
191 mItemTreeView->setMenuProvider(
new QgsLayoutLegendMenuProvider( mItemTreeView,
this ) );
192 setLegendMapViewData();
198 connect( layoutAtlas(), &
QgsLayoutAtlas::toggled,
this, &QgsLayoutLegendWidget::updateFilterLegendByAtlasButton );
202 mTitleFontButton->registerExpressionContextGenerator(
this );
203 mGroupFontButton->registerExpressionContextGenerator(
this );
204 mLayerFontButton->registerExpressionContextGenerator(
this );
205 mItemFontButton->registerExpressionContextGenerator(
this );
207 mTitleFontButton->setLayer( coverageLayer() );
208 mGroupFontButton->setLayer( coverageLayer() );
209 mLayerFontButton->setLayer( coverageLayer() );
210 mItemFontButton->setLayer( coverageLayer() );
211 if ( mLegend->layout() )
224 connect( mItemTreeView->selectionModel(), &QItemSelectionModel::currentChanged,
225 this, &QgsLayoutLegendWidget::selectedChanged );
234 if ( mItemPropertiesWidget )
235 mItemPropertiesWidget->setMasterLayout( masterLayout );
241 mTitleFontButton->setMessageBar( iface->
messageBar() );
242 mGroupFontButton->setMessageBar( iface->
messageBar() );
243 mLayerFontButton->setMessageBar( iface->
messageBar() );
244 mItemFontButton->setMessageBar( iface->
messageBar() );
247void QgsLayoutLegendWidget::setGuiElements()
254 blockAllSignals(
true );
255 mTitleLineEdit->setText( mLegend->title() );
256 whileBlocking( mTitleAlignCombo )->setCurrentAlignment( mLegend->titleAlignment() );
260 whileBlocking( mArrangementCombo )->setCurrentAlignment( mLegend->symbolAlignment() );
261 mFilterByMapCheckBox->setChecked( mLegend->legendFilterByMapEnabled() );
262 mButtonLinkedMaps->setEnabled( mLegend->legendFilterByMapEnabled() );
263 mColumnCountSpinBox->setValue( mLegend->columnCount() );
264 mSplitLayerCheckBox->setChecked( mLegend->splitLayer() );
265 mEqualColumnWidthCheckBox->setChecked( mLegend->equalColumnWidth() );
266 mSymbolWidthSpinBox->setValue( mLegend->symbolWidth() );
267 mSymbolHeightSpinBox->setValue( mLegend->symbolHeight() );
268 mMaxSymbolSizeSpinBox->setValue( mLegend->maximumSymbolSize() );
269 mMinSymbolSizeSpinBox->setValue( mLegend->minimumSymbolSize() );
270 mWmsLegendWidthSpinBox->setValue( mLegend->wmsLegendWidth() );
271 mWmsLegendHeightSpinBox->setValue( mLegend->wmsLegendHeight() );
285 mBoxSpaceSpinBox->setValue( mLegend->boxSpace() );
286 mColumnSpaceSpinBox->setValue( mLegend->columnSpace() );
288 mRasterStrokeGroupBox->setChecked( mLegend->drawRasterStroke() );
289 mRasterStrokeWidthSpinBox->setValue( mLegend->rasterStrokeWidth() );
290 mRasterStrokeColorButton->setColor( mLegend->rasterStrokeColor() );
292 mCheckBoxAutoUpdate->setChecked( mLegend->autoUpdateModel() );
294 mCheckboxResizeContents->setChecked( mLegend->resizeToContents() );
295 mFilterLegendByAtlasCheckBox->setChecked( mLegend->legendFilterOutAtlas() );
296 mWrapCharLineEdit->setText( mLegend->wrapString() );
299 mMapComboBox->setItem( map );
305 blockAllSignals(
false );
307 mCheckBoxAutoUpdate_stateChanged( mLegend->autoUpdateModel() ? Qt::Checked : Qt::Unchecked,
false );
308 updateDataDefinedButton( mLegendTitleDDBtn );
309 updateDataDefinedButton( mColumnsDDBtn );
312void QgsLayoutLegendWidget::mWrapCharLineEdit_textChanged(
const QString &text )
316 mLegend->beginCommand( tr(
"Change Legend Wrap" ) );
317 mLegend->setWrapString( text );
318 mLegend->adjustBoxSize();
320 mLegend->endCommand();
324void QgsLayoutLegendWidget::mTitleLineEdit_textChanged(
const QString &text )
329 mLegend->setTitle( text );
330 mLegend->adjustBoxSize();
332 mLegend->endCommand();
336void QgsLayoutLegendWidget::titleAlignmentChanged()
340 Qt::AlignmentFlag alignment =
static_cast< Qt::AlignmentFlag
>(
static_cast< int >( mTitleAlignCombo->currentAlignment() & Qt::AlignHorizontal_Mask ) );
341 mLegend->beginCommand( tr(
"Change Title Alignment" ) );
342 mLegend->setTitleAlignment( alignment );
344 mLegend->endCommand();
348void QgsLayoutLegendWidget::groupAlignmentChanged()
352 mLegend->beginCommand( tr(
"Change Group Alignment" ) );
355 mLegend->endCommand();
359void QgsLayoutLegendWidget::subgroupAlignmentChanged()
363 mLegend->beginCommand( tr(
"Change Subgroup Alignment" ) );
366 mLegend->endCommand();
370void QgsLayoutLegendWidget::itemAlignmentChanged()
374 mLegend->beginCommand( tr(
"Change Item Alignment" ) );
377 mLegend->endCommand();
381void QgsLayoutLegendWidget::arrangementChanged()
385 Qt::AlignmentFlag alignment =
static_cast< Qt::AlignmentFlag
>(
static_cast< int >( mArrangementCombo->currentAlignment() & Qt::AlignHorizontal_Mask ) );
386 mLegend->beginCommand( tr(
"Change Legend Arrangement" ) );
387 mLegend->setSymbolAlignment( alignment );
389 mLegend->endCommand();
393void QgsLayoutLegendWidget::mColumnCountSpinBox_valueChanged(
int c )
398 mLegend->setColumnCount(
c );
399 mLegend->adjustBoxSize();
401 mLegend->endCommand();
403 mSplitLayerCheckBox->setEnabled(
c > 1 );
404 mEqualColumnWidthCheckBox->setEnabled(
c > 1 );
407void QgsLayoutLegendWidget::mSplitLayerCheckBox_toggled(
bool checked )
411 mLegend->beginCommand( tr(
"Split Legend Layers" ) );
412 mLegend->setSplitLayer( checked );
413 mLegend->adjustBoxSize();
415 mLegend->endCommand();
419void QgsLayoutLegendWidget::mEqualColumnWidthCheckBox_toggled(
bool checked )
423 mLegend->beginCommand( tr(
"Legend Column Width" ) );
424 mLegend->setEqualColumnWidth( checked );
425 mLegend->adjustBoxSize();
427 mLegend->endCommand();
431void QgsLayoutLegendWidget::mSymbolWidthSpinBox_valueChanged(
double d )
436 mLegend->setSymbolWidth( d );
437 mLegend->adjustBoxSize();
439 mLegend->endCommand();
443void QgsLayoutLegendWidget::mMaxSymbolSizeSpinBox_valueChanged(
double d )
448 mLegend->setMaximumSymbolSize( d );
449 mLegend->adjustBoxSize();
451 mLegend->endCommand();
455void QgsLayoutLegendWidget::mMinSymbolSizeSpinBox_valueChanged(
double d )
460 mLegend->setMinimumSymbolSize( d );
461 mLegend->adjustBoxSize();
463 mLegend->endCommand();
467void QgsLayoutLegendWidget::mSymbolHeightSpinBox_valueChanged(
double d )
472 mLegend->setSymbolHeight( d );
473 mLegend->adjustBoxSize();
475 mLegend->endCommand();
479void QgsLayoutLegendWidget::mWmsLegendWidthSpinBox_valueChanged(
double d )
484 mLegend->setWmsLegendWidth( d );
485 mLegend->adjustBoxSize();
487 mLegend->endCommand();
491void QgsLayoutLegendWidget::mWmsLegendHeightSpinBox_valueChanged(
double d )
496 mLegend->setWmsLegendHeight( d );
497 mLegend->adjustBoxSize();
499 mLegend->endCommand();
503void QgsLayoutLegendWidget::mTitleSpaceBottomSpinBox_valueChanged(
double d )
509 mLegend->adjustBoxSize();
511 mLegend->endCommand();
515void QgsLayoutLegendWidget::mGroupSpaceSpinBox_valueChanged(
double d )
521 mLegend->adjustBoxSize();
523 mLegend->endCommand();
527void QgsLayoutLegendWidget::mGroupIndentSpinBox_valueChanged(
double d )
533 mLegend->adjustBoxSize();
535 mLegend->endCommand();
539void QgsLayoutLegendWidget::mSubgroupIndentSpinBox_valueChanged(
double d )
545 mLegend->adjustBoxSize();
547 mLegend->endCommand();
551void QgsLayoutLegendWidget::spaceBelowGroupHeadingChanged(
double space )
557 mLegend->adjustBoxSize();
559 mLegend->endCommand();
563void QgsLayoutLegendWidget::spaceGroupSideChanged(
double space )
569 mLegend->adjustBoxSize();
571 mLegend->endCommand();
575void QgsLayoutLegendWidget::spaceSubGroupSideChanged(
double space )
581 mLegend->adjustBoxSize();
583 mLegend->endCommand();
587void QgsLayoutLegendWidget::spaceSymbolSideChanged(
double space )
593 mLegend->adjustBoxSize();
595 mLegend->endCommand();
599void QgsLayoutLegendWidget::mLayerSpaceSpinBox_valueChanged(
double d )
605 mLegend->adjustBoxSize();
607 mLegend->endCommand();
611void QgsLayoutLegendWidget::mSymbolSpaceSpinBox_valueChanged(
double d )
619 mLegend->adjustBoxSize();
621 mLegend->endCommand();
625void QgsLayoutLegendWidget::mIconLabelSpaceSpinBox_valueChanged(
double d )
631 mLegend->adjustBoxSize();
633 mLegend->endCommand();
637void QgsLayoutLegendWidget::titleFontChanged()
643 mLegend->adjustBoxSize();
645 mLegend->endCommand();
649void QgsLayoutLegendWidget::groupFontChanged()
655 mLegend->adjustBoxSize();
657 mLegend->endCommand();
661void QgsLayoutLegendWidget::layerFontChanged()
667 mLegend->adjustBoxSize();
669 mLegend->endCommand();
673void QgsLayoutLegendWidget::itemFontChanged()
679 mLegend->adjustBoxSize();
681 mLegend->endCommand();
685void QgsLayoutLegendWidget::spaceBelowSubGroupHeadingChanged(
double space )
691 mLegend->adjustBoxSize();
693 mLegend->endCommand();
697void QgsLayoutLegendWidget::mBoxSpaceSpinBox_valueChanged(
double d )
702 mLegend->setBoxSpace( d );
703 mLegend->adjustBoxSize();
705 mLegend->endCommand();
709void QgsLayoutLegendWidget::mColumnSpaceSpinBox_valueChanged(
double d )
714 mLegend->setColumnSpace( d );
715 mLegend->adjustBoxSize();
717 mLegend->endCommand();
721static void _moveLegendNode(
QgsLayerTreeLayer *nodeLayer,
int legendNodeIndex,
int offset )
725 if ( legendNodeIndex < 0 || legendNodeIndex >= order.count() )
727 if ( legendNodeIndex + offset < 0 || legendNodeIndex + offset >= order.count() )
730 int id = order.takeAt( legendNodeIndex );
731 order.insert( legendNodeIndex + offset,
id );
737void QgsLayoutLegendWidget::mMoveDownToolButton_clicked()
744 const QModelIndex index = mItemTreeView->selectionModel()->currentIndex();
745 const QModelIndex sourceIndex = mItemTreeView->proxyModel()->mapToSource( index );
746 const QModelIndex parentIndex = sourceIndex.parent();
747 if ( !sourceIndex.isValid() || sourceIndex.row() == mItemTreeView->layerTreeModel()->rowCount( parentIndex ) - 1 )
755 mLegend->beginCommand( tr(
"Moved Legend Item Down" ) );
769 mItemTreeView->setCurrentIndex( mItemTreeView->proxyModel()->mapFromSource( mItemTreeView->layerTreeModel()->index( sourceIndex.row() + 1, 0, parentIndex ) ) );
772 mLegend->endCommand();
775void QgsLayoutLegendWidget::mMoveUpToolButton_clicked()
782 const QModelIndex index = mItemTreeView->selectionModel()->currentIndex();
783 const QModelIndex sourceIndex = mItemTreeView->proxyModel()->mapToSource( index );
784 const QModelIndex parentIndex = sourceIndex.parent();
785 if ( !sourceIndex.isValid() || sourceIndex.row() == 0 )
793 mLegend->beginCommand( tr(
"Move Legend Item Up" ) );
807 mItemTreeView->setCurrentIndex( mItemTreeView->proxyModel()->mapFromSource( mItemTreeView->layerTreeModel()->index( sourceIndex.row() - 1, 0, parentIndex ) ) );
810 mLegend->endCommand();
813void QgsLayoutLegendWidget::mCheckBoxAutoUpdate_stateChanged(
int state,
bool userTriggered )
817 mLegend->beginCommand( tr(
"Change Auto Update" ) );
819 mLegend->setAutoUpdateModel( state == Qt::Checked );
821 mLegend->endCommand();
825 QList<QWidget *> widgets;
826 widgets << mMoveDownToolButton << mMoveUpToolButton << mRemoveToolButton << mAddToolButton
827 << mEditPushButton << mCountToolButton << mUpdateAllPushButton << mAddGroupToolButton
828 << mExpressionFilterButton;
829 for ( QWidget *w : std::as_const( widgets ) )
830 w->setEnabled( state != Qt::Checked );
832 if ( state == Qt::Unchecked )
835 selectedChanged( QModelIndex(), QModelIndex() );
839void QgsLayoutLegendWidget::composerMapChanged(
QgsLayoutItem *item )
855 mLegend->beginCommand( tr(
"Change Legend Map" ) );
856 mLegend->setLinkedMap( map );
858 mLegend->endCommand();
860 setLegendMapViewData();
864void QgsLayoutLegendWidget::mCheckboxResizeContents_toggled(
bool checked )
871 mLegend->beginCommand( tr(
"Resize Legend to Contents" ) );
872 mLegend->setResizeToContents( checked );
874 mLegend->adjustBoxSize();
876 mLegend->endCommand();
879void QgsLayoutLegendWidget::mRasterStrokeGroupBox_toggled(
bool state )
886 mLegend->beginCommand( tr(
"Change Legend Borders" ) );
887 mLegend->setDrawRasterStroke( state );
888 mLegend->adjustBoxSize();
890 mLegend->endCommand();
893void QgsLayoutLegendWidget::mRasterStrokeWidthSpinBox_valueChanged(
double d )
901 mLegend->setRasterStrokeWidth( d );
902 mLegend->adjustBoxSize();
904 mLegend->endCommand();
907void QgsLayoutLegendWidget::mRasterStrokeColorButton_colorChanged(
const QColor &newColor )
915 mLegend->setRasterStrokeColor( newColor );
917 mLegend->endCommand();
920void QgsLayoutLegendWidget::mAddToolButton_clicked()
927 QList< QgsMapLayer * > visibleLayers;
928 if ( mLegend->linkedMap() )
930 visibleLayers = mLegend->linkedMap()->layersToRender();
932 if ( visibleLayers.isEmpty() )
935 visibleLayers = mMapCanvas->layers(
true );
939 addDialog.setVisibleLayers( visibleLayers );
940 if ( addDialog.exec() == QDialog::Accepted )
942 const QList<QgsMapLayer *> layers = addDialog.selectedLayers();
943 if ( !layers.empty() )
945 mLegend->beginCommand( tr(
"Add Legend Item(s)" ) );
948 mLegend->model()->rootGroup()->addLayer( layer );
950 mLegend->updateLegend();
952 mLegend->endCommand();
957void QgsLayoutLegendWidget::mRemoveToolButton_clicked()
964 QItemSelectionModel *selectionModel = mItemTreeView->selectionModel();
965 if ( !selectionModel )
970 mLegend->beginCommand( tr(
"Remove Legend Item" ) );
972 QList<QPersistentModelIndex> proxyIndexes;
973 const QModelIndexList viewSelection = selectionModel->selectedIndexes();
974 for (
const QModelIndex &index : viewSelection )
975 proxyIndexes << index;
978 QHash<QgsLayerTreeLayer *, QList<int> > nodesWithRemoval;
979 for (
const QPersistentModelIndex &proxyIndex : std::as_const( proxyIndexes ) )
984 nodesWithRemoval[nodeLayer].append( _unfilteredLegendNodeIndex(
legendNode ) );
987 for (
auto it = nodesWithRemoval.constBegin(); it != nodesWithRemoval.constEnd(); ++it )
989 QList<int> toDelete = it.value();
990 std::sort( toDelete.begin(), toDelete.end(), std::greater<int>() );
993 for (
int i : std::as_const( toDelete ) )
995 if ( i >= 0 && i < order.count() )
1000 mItemTreeView->layerTreeModel()->refreshLayerLegend( it.key() );
1004 for (
const QPersistentModelIndex &proxyIndex : std::as_const( proxyIndexes ) )
1006 if ( proxyIndex.isValid() && mItemTreeView->index2node( proxyIndex ) )
1008 const QModelIndex sourceIndex = mItemTreeView->proxyModel()->mapToSource( proxyIndex );
1009 mLegend->model()->removeRow( sourceIndex.row(), sourceIndex.parent() );
1013 mLegend->updateLegend();
1015 mLegend->endCommand();
1018void QgsLayoutLegendWidget::mEditPushButton_clicked()
1025 QModelIndex idx = mItemTreeView->selectionModel()->currentIndex();
1026 mItemTreeView_doubleClicked( idx );
1029void QgsLayoutLegendWidget::resetLayerNodeToDefaults()
1037 QModelIndex currentIndex = mItemTreeView->currentIndex();
1038 if ( !currentIndex.isValid() )
1057 mLegend->beginCommand( tr(
"Update Legend" ) );
1060 for (
const QString &key : constCustomProperties )
1062 if ( key.startsWith( QLatin1String(
"legend/" ) ) )
1069 mItemTreeView->layerTreeModel()->refreshLayerLegend( nodeLayer );
1071 mLegend->updateLegend();
1073 mLegend->endCommand();
1076void QgsLayoutLegendWidget::mCountToolButton_clicked(
bool checked )
1083 const QList< QModelIndex > selectedIndexes = mItemTreeView->selectionModel()->selectedIndexes();
1084 if ( selectedIndexes.empty() )
1087 mLegend->beginCommand( tr(
"Update Legend" ) );
1088 for (
const QModelIndex &index : selectedIndexes )
1094 currentNode->
setCustomProperty( QStringLiteral(
"showFeatureCount" ), checked ? 1 : 0 );
1096 mLegend->updateFilterByMap();
1097 mLegend->adjustBoxSize();
1098 mLegend->endCommand();
1101void QgsLayoutLegendWidget::mFilterByMapCheckBox_toggled(
bool checked )
1103 mLegend->beginCommand( tr(
"Update Legend" ) );
1104 mLegend->setLegendFilterByMapEnabled( checked );
1105 mLegend->adjustBoxSize();
1107 mLegend->endCommand();
1110void QgsLayoutLegendWidget::mExpressionFilterButton_toggled(
bool checked )
1118 QModelIndex currentIndex = mItemTreeView->currentIndex();
1119 if ( !currentIndex.isValid() )
1129 mExpressionFilterButton->expressionText(),
1132 mLegend->beginCommand( tr(
"Update Legend" ) );
1133 mLegend->updateFilterByMap();
1134 mLegend->adjustBoxSize();
1135 mLegend->endCommand();
1138void QgsLayoutLegendWidget::mLayerExpressionButton_clicked()
1145 QModelIndex currentIndex = mItemTreeView->currentIndex();
1146 if ( !currentIndex.isValid() )
1153 QgsLayerTreeLayer *layerNode = qobject_cast<QgsLayerTreeLayer *>( currentNode );
1159 QString currentExpression;
1161 currentExpression = QStringLiteral(
"@symbol_label" );
1171 QStringList highlighted;
1176 if ( !legendSymbols.empty() )
1182 highlighted << QStringLiteral(
"symbol_label" ) << QStringLiteral(
"symbol_id" );
1184 highlighted << QStringLiteral(
"symbol_count" );
1193 if ( expressiondialog.exec() )
1196 mLegend->beginCommand( tr(
"Update Legend" ) );
1198 mLegend->adjustBoxSize();
1199 mLegend->endCommand();
1202void QgsLayoutLegendWidget::mUpdateAllPushButton_clicked()
1207void QgsLayoutLegendWidget::mAddGroupToolButton_clicked()
1211 mLegend->beginCommand( tr(
"Add Legend Group" ) );
1212 mLegend->model()->rootGroup()->addGroup( tr(
"Group" ) );
1213 mLegend->updateLegend();
1215 mLegend->endCommand();
1219void QgsLayoutLegendWidget::mFilterLegendByAtlasCheckBox_toggled(
bool toggled )
1224 mLegend->setLegendFilterOutAtlas( toggled );
1230void QgsLayoutLegendWidget::updateLegend()
1234 mLegend->beginCommand( tr(
"Update Legend" ) );
1237 mLegend->setAutoUpdateModel(
true );
1238 mLegend->setAutoUpdateModel(
false );
1240 mLegend->endCommand();
1244void QgsLayoutLegendWidget::setReportTypeString(
const QString &
string )
1246 mFilterLegendByAtlasCheckBox->setText( tr(
"Only show items inside current %1 feature" ).arg(
string ) );
1247 mFilterLegendByAtlasCheckBox->setToolTip( tr(
"Filter out legend elements that lie outside the current %1 feature." ).arg(
string ) );
1256bool QgsLayoutLegendWidget::setNewItem(
QgsLayoutItem *item )
1266 mLegend = qobject_cast< QgsLayoutItemLegend * >( item );
1267 mItemPropertiesWidget->setItem( mLegend );
1269 if ( mMapFilteringWidget )
1270 mMapFilteringWidget->setItem( mLegend );
1274 mItemTreeView->setModel( mLegend->model() );
1283void QgsLayoutLegendWidget::blockAllSignals(
bool b )
1285 mTitleLineEdit->blockSignals( b );
1286 mTitleAlignCombo->blockSignals( b );
1287 mItemTreeView->blockSignals( b );
1288 mCheckBoxAutoUpdate->blockSignals( b );
1289 mMapComboBox->blockSignals( b );
1290 mFilterByMapCheckBox->blockSignals( b );
1291 mColumnCountSpinBox->blockSignals( b );
1292 mSplitLayerCheckBox->blockSignals( b );
1293 mEqualColumnWidthCheckBox->blockSignals( b );
1294 mSymbolWidthSpinBox->blockSignals( b );
1295 mSymbolHeightSpinBox->blockSignals( b );
1296 mMaxSymbolSizeSpinBox->blockSignals( b );
1297 mMinSymbolSizeSpinBox->blockSignals( b );
1298 mGroupSpaceSpinBox->blockSignals( b );
1299 mGroupIndentSpinBox->blockSignals( b );
1300 mSubgroupIndentSpinBox->blockSignals( b );
1301 mSpaceBelowGroupHeadingSpinBox->blockSignals( b );
1302 mGroupSideSpinBox->blockSignals( b );
1303 mSpaceBelowSubgroupHeadingSpinBox->blockSignals( b );
1304 mSubgroupSideSpinBox->blockSignals( b );
1305 mLayerSpaceSpinBox->blockSignals( b );
1306 mSymbolSpaceSpinBox->blockSignals( b );
1307 mSymbolSideSpaceSpinBox->blockSignals( b );
1308 mIconLabelSpaceSpinBox->blockSignals( b );
1309 mBoxSpaceSpinBox->blockSignals( b );
1310 mColumnSpaceSpinBox->blockSignals( b );
1311 mRasterStrokeGroupBox->blockSignals( b );
1312 mRasterStrokeColorButton->blockSignals( b );
1313 mRasterStrokeWidthSpinBox->blockSignals( b );
1314 mWmsLegendWidthSpinBox->blockSignals( b );
1315 mWmsLegendHeightSpinBox->blockSignals( b );
1316 mCheckboxResizeContents->blockSignals( b );
1317 mTitleSpaceBottomSpinBox->blockSignals( b );
1318 mFilterLegendByAtlasCheckBox->blockSignals( b );
1319 mTitleFontButton->blockSignals( b );
1320 mGroupFontButton->blockSignals( b );
1321 mLayerFontButton->blockSignals( b );
1322 mItemFontButton->blockSignals( b );
1323 mWrapCharLineEdit->blockSignals( b );
1326void QgsLayoutLegendWidget::selectedChanged(
const QModelIndex ¤t,
const QModelIndex &previous )
1329 Q_UNUSED( previous )
1331 mLayerExpressionButton->setEnabled(
false );
1333 if ( mLegend && mLegend->autoUpdateModel() )
1344 mLayerExpressionButton->setEnabled(
true );
1348 mCountToolButton->setChecked(
false );
1349 mCountToolButton->setEnabled(
false );
1352 mExpressionFilterButton->blockSignals(
true );
1353 mExpressionFilterButton->setChecked(
false );
1354 mExpressionFilterButton->setEnabled(
false );
1355 mExpressionFilterButton->blockSignals(
false );
1366 mCountToolButton->setChecked( currentNode->
customProperty( QStringLiteral(
"showFeatureCount" ), 0 ).toInt() );
1367 mCountToolButton->setEnabled(
true );
1368 mLayerExpressionButton->setEnabled(
true );
1372 mExpressionFilterButton->blockSignals(
true );
1373 mExpressionFilterButton->setExpressionText( expr );
1374 mExpressionFilterButton->setVectorLayer( vl );
1375 mExpressionFilterButton->setEnabled(
true );
1376 mExpressionFilterButton->setChecked( exprEnabled );
1377 mExpressionFilterButton->blockSignals(
false );
1380void QgsLayoutLegendWidget::setCurrentNodeStyleFromAction()
1382 QAction *a = qobject_cast<QAction *>( sender() );
1383 if ( !a || !mItemTreeView->currentNode() )
1390void QgsLayoutLegendWidget::setLegendMapViewData()
1392 if ( mLegend->linkedMap() )
1396 measurementConverter.
setDpi( dpi );
1397 double mapWidth = measurementConverter.
convert( mLegend->linkedMap()->sizeWithUnits(), Qgis::LayoutUnit::Pixels ).width();
1398 double mapHeight = measurementConverter.
convert( mLegend->linkedMap()->sizeWithUnits(), Qgis::LayoutUnit::Pixels ).height();
1399 double mapUnitsPerPixelX = mLegend->linkedMap()->extent().width() / mapWidth;
1400 double mapUnitsPerPixelY = mLegend->linkedMap()->extent().height() / mapHeight;
1401 mLegend->model()->setLegendMapViewData( ( mapUnitsPerPixelX > mapUnitsPerPixelY ? mapUnitsPerPixelX : mapUnitsPerPixelY ), dpi, mLegend->linkedMap()->scale() );
1405void QgsLayoutLegendWidget::updateFilterLegendByAtlasButton()
1409 mFilterLegendByAtlasCheckBox->setEnabled( atlas->enabled() && mLegend->layout()->reportContext().layer() && mLegend->layout()->reportContext().layer()->geometryType() == Qgis::GeometryType::Polygon );
1413void QgsLayoutLegendWidget::mItemTreeView_doubleClicked(
const QModelIndex &idx )
1415 if ( !mLegend || !idx.isValid() )
1420 if ( mLegend->autoUpdateModel() )
1426 int originalIndex = -1;
1429 originalIndex = _originalLegendNodeIndex(
legendNode );
1433 QgsLayoutLegendNodeWidget *widget =
new QgsLayoutLegendNodeWidget( mLegend, currentNode,
legendNode, originalIndex );
1434 openPanel( widget );
1442QgsLayoutLegendMenuProvider::QgsLayoutLegendMenuProvider(
QgsLayerTreeView *view, QgsLayoutLegendWidget *w )
1447QMenu *QgsLayoutLegendMenuProvider::createContextMenu()
1449 if ( !mView->currentNode() )
1452 if ( mWidget->legend()->autoUpdateModel() )
1455 QMenu *menu =
new QMenu();
1459 menu->addAction( QObject::tr(
"Reset to Defaults" ), mWidget, &QgsLayoutLegendWidget::resetLayerNodeToDefaults );
1460 menu->addSeparator();
1465 QList<QgsLegendStyle::Style> lst;
1469 QAction *action = menu->addAction(
QgsLegendStyle::styleLabel( style ), mWidget, &QgsLayoutLegendWidget::setCurrentNodeStyleFromAction );
1470 action->setCheckable(
true );
1471 action->setChecked( currentStyle == style );
1472 action->setData(
static_cast< int >( style ) );
1487 , mOriginalLegendNodeIndex( originalLegendNodeIndex )
1490 setPanelTitle( tr(
"Legend Item Properties" ) );
1499 QString currentLabel;
1502 currentLabel = mLegendNode->data( Qt::EditRole ).toString();
1503 mColumnBreakBeforeCheckBox->setChecked( mLegendNode->columnBreak() );
1507 currentLabel = mLayer->name();
1508 QVariant v = mLayer->customProperty( QStringLiteral(
"legend/title-label" ) );
1510 currentLabel = v.toString();
1511 mColumnBreakBeforeCheckBox->setChecked( mLayer->customProperty( QStringLiteral(
"legend/column-break" ) ).toInt() );
1513 mColumnSplitBehaviorComboBox->setCurrentIndex( mColumnSplitBehaviorComboBox->findData( mLayer->legendSplitBehavior() ) );
1518 mColumnBreakBeforeCheckBox->setChecked( mNode->customProperty( QStringLiteral(
"legend/column-break" ) ).toInt() );
1521 mWidthSpinBox->setClearValue( 0, tr(
"Default" ) );
1522 mHeightSpinBox->setClearValue( 0, tr(
"Default" ) );
1523 mWidthSpinBox->setVisible( mLegendNode || mLayer );
1524 mHeightSpinBox->setVisible( mLegendNode || mLayer );
1525 mPatchGroup->setVisible( mLegendNode || mLayer );
1526 mPatchWidthLabel->setVisible( mLegendNode || mLayer );
1527 mPatchHeightLabel->setVisible( mLegendNode || mLayer );
1528 mCustomSymbolCheckBox->setVisible( mLegendNode || mLegend->model()->legendNodeEmbeddedInParent( mLayer ) );
1529 mColumnSplitLabel->setVisible( mLayer && !mLegendNode );
1530 mColumnSplitBehaviorComboBox->setVisible( mLayer && !mLegendNode );
1533 mWidthSpinBox->setValue( mLegendNode->userPatchSize().width() );
1534 mHeightSpinBox->setValue( mLegendNode->userPatchSize().height() );
1538 mWidthSpinBox->setValue( mLayer->patchSize().width() );
1539 mHeightSpinBox->setValue( mLayer->patchSize().height() );
1542 mCustomSymbolCheckBox->setChecked(
false );
1547 patchShape = symbolLegendNode->patchShape();
1549 std::unique_ptr< QgsSymbol > customSymbol( symbolLegendNode->customSymbol() ? symbolLegendNode->customSymbol()->clone() :
nullptr );
1550 mCustomSymbolCheckBox->setChecked( customSymbol.get() );
1553 mPatchShapeButton->setPreviewSymbol( customSymbol->clone() );
1554 mCustomSymbolButton->setSymbolType( customSymbol->type() );
1555 mCustomSymbolButton->setSymbol( customSymbol.release() );
1557 else if ( symbolLegendNode->symbol() )
1559 mPatchShapeButton->setPreviewSymbol( symbolLegendNode->symbol()->clone() );
1560 mCustomSymbolButton->setSymbolType( symbolLegendNode->symbol()->type() );
1561 mCustomSymbolButton->setSymbol( symbolLegendNode->symbol()->clone() );
1564 else if ( !mLegendNode && mLayer )
1566 patchShape = mLayer->patchShape();
1569 if (
QgsSymbol *customSymbol = symbolLegendNode->customSymbol() )
1571 mCustomSymbolCheckBox->setChecked(
true );
1572 mPatchShapeButton->setPreviewSymbol( customSymbol->clone() );
1574 mCustomSymbolButton->setSymbol( customSymbol->clone() );
1578 mPatchShapeButton->setPreviewSymbol( symbolLegendNode->symbol()->clone() );
1579 mCustomSymbolButton->setSymbolType( symbolLegendNode->symbol()->type() );
1580 mCustomSymbolButton->setSymbol( symbolLegendNode->symbol()->clone() );
1585 if ( mLayer && mLayer->layer() && mLayer->layer()->type() == Qgis::LayerType::Vector )
1587 switch ( qobject_cast< QgsVectorLayer * >( mLayer->layer() )->geometryType() )
1589 case Qgis::GeometryType::Polygon:
1593 case Qgis::GeometryType::Line:
1597 case Qgis::GeometryType::Point:
1602 mPatchShapeLabel->hide();
1603 mPatchShapeButton->hide();
1606 if ( !patchShape.
isNull() )
1607 mPatchShapeButton->setShape( patchShape );
1612 if ( symbolLegendNode->symbol() )
1614 mPatchShapeButton->setSymbolType( symbolLegendNode->symbol()->type() );
1618 mPatchShapeLabel->hide();
1619 mPatchShapeButton->hide();
1624 mPatchShapeLabel->hide();
1625 mPatchShapeButton->hide();
1630 mLabelGroup->hide();
1631 mColorRampLegendWidget->setSettings( colorRampNode->settings() );
1635 mColorRampLegendWidget->hide();
1648 mCustomSymbolCheckBox->hide();
1657 mLabelEdit->setPlainText( currentLabel );
1658 connect( mLabelEdit, &QPlainTextEdit::textChanged,
this, &QgsLayoutLegendNodeWidget::labelChanged );
1660 connect( mInsertExpressionButton, &QPushButton::clicked,
this, &QgsLayoutLegendNodeWidget::insertExpression );
1662 connect( mWidthSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendNodeWidget::sizeChanged );
1663 connect( mHeightSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsLayoutLegendNodeWidget::sizeChanged );
1665 connect( mCustomSymbolCheckBox, &QGroupBox::toggled,
this, &QgsLayoutLegendNodeWidget::customSymbolChanged );
1668 connect( mColumnBreakBeforeCheckBox, &QCheckBox::toggled,
this, &QgsLayoutLegendNodeWidget::columnBreakToggled );
1670 connect( mColumnSplitBehaviorComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsLayoutLegendNodeWidget::columnSplitChanged );
1674 connectChildPanel( mColorRampLegendWidget );
1677void QgsLayoutLegendNodeWidget::setDockMode(
bool dockMode )
1679 mColorRampLegendWidget->setDockMode( dockMode );
1683void QgsLayoutLegendNodeWidget::labelChanged()
1687 const QString label = mLabelEdit->toPlainText();
1692 else if ( mLegendNode )
1695 mLegend->model()->refreshLayerLegend( mLayer );
1699 mLayer->setCustomProperty( QStringLiteral(
"legend/title-label" ), label );
1703 embeddedNode->setUserLabel( QString() );
1706 mLegend->adjustBoxSize();
1707 mLegend->invalidateCache();
1709 mLegend->endCommand();
1712void QgsLayoutLegendNodeWidget::patchChanged()
1714 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1720 mLegend->model()->refreshLayerLegend( mLayer );
1724 mLayer->setPatchShape( shape );
1725 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1730 mLegend->model()->refreshLayerLegend( mLayer );
1733 mLegend->adjustBoxSize();
1735 mLegend->endCommand();
1738void QgsLayoutLegendNodeWidget::insertExpression()
1743 QString selText = mLabelEdit->textCursor().selectedText();
1746 selText = selText.replace( QChar( 0x2029 ), QChar(
'\n' ) );
1749 if ( selText.startsWith( QLatin1String(
"[%" ) ) && selText.endsWith( QLatin1String(
"%]" ) ) )
1750 selText = selText.mid( 2, selText.size() - 4 );
1753 QgsVectorLayer *layer = mLegend->layout() ? mLegend->layout()->reportContext().layer() :
nullptr;
1757 if ( mLayer && mLayer->layer() )
1763 << QStringLiteral(
"legend_column_count" )
1764 << QStringLiteral(
"legend_split_layers" )
1765 << QStringLiteral(
"legend_wrap_string" )
1766 << QStringLiteral(
"legend_filter_by_map" )
1767 << QStringLiteral(
"legend_filter_out_atlas" ) );
1771 exprDlg.setWindowTitle( tr(
"Insert Expression" ) );
1772 if ( exprDlg.exec() == QDialog::Accepted )
1774 QString expression = exprDlg.expressionText();
1775 if ( !expression.isEmpty() )
1777 mLegend->beginCommand( tr(
"Insert expression" ) );
1778 mLabelEdit->insertPlainText(
"[%" + expression +
"%]" );
1779 mLegend->endCommand();
1784void QgsLayoutLegendNodeWidget::sizeChanged(
double )
1786 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1787 const QSizeF size = QSizeF( mWidthSpinBox->value(), mHeightSpinBox->value() );
1792 mLegend->model()->refreshLayerLegend( mLayer );
1796 mLayer->setPatchSize( size );
1797 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1802 mLegend->model()->refreshLayerLegend( mLayer );
1805 mLegend->adjustBoxSize();
1807 mLegend->endCommand();
1810void QgsLayoutLegendNodeWidget::customSymbolChanged()
1812 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1814 if ( mCustomSymbolCheckBox->isChecked() )
1819 mLegend->model()->refreshLayerLegend( mLayer );
1823 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1828 mLegend->model()->refreshLayerLegend( mLayer );
1836 mLegend->model()->refreshLayerLegend( mLayer );
1840 const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer,
false );
1845 mLegend->model()->refreshLayerLegend( mLayer );
1849 mLegend->adjustBoxSize();
1851 mLegend->endCommand();
1854void QgsLayoutLegendNodeWidget::colorRampLegendChanged()
1856 mLegend->beginCommand( tr(
"Edit Legend Item" ) );
1860 mLegend->model()->refreshLayerLegend( mLayer );
1862 mLegend->adjustBoxSize();
1864 mLegend->endCommand();
1867void QgsLayoutLegendNodeWidget::columnBreakToggled(
bool checked )
1869 mLegend->beginCommand( tr(
"Edit Legend Columns" ) );
1874 mLegend->model()->refreshLayerLegend( mLayer );
1878 mLayer->setCustomProperty( QStringLiteral(
"legend/column-break" ), QString( checked ?
'1' :
'0' ) );
1882 mNode->setCustomProperty( QStringLiteral(
"legend/column-break" ), QString( checked ?
'1' :
'0' ) );
1885 mLegend->adjustBoxSize();
1887 mLegend->endCommand();
1890void QgsLayoutLegendNodeWidget::columnSplitChanged()
1892 mLegend->beginCommand( tr(
"Edit Legend Columns" ) );
1894 if ( mLayer && !mLegendNode )
1899 mLegend->adjustBoxSize();
1901 mLegend->endCommand();
1908QgsLayoutLegendMapFilteringWidget::QgsLayoutLegendMapFilteringWidget(
QgsLayoutItemLegend *legend )
1910 , mLegendItem( legend )
1913 setPanelTitle( tr(
"Legend Filtering" ) );
1915 setNewItem( legend );
1918bool QgsLayoutLegendMapFilteringWidget::setNewItem(
QgsLayoutItem *item )
1928 mLegendItem = qobject_cast< QgsLayoutItemLegend * >( item );
1935 updateGuiElements();
1940void QgsLayoutLegendMapFilteringWidget::updateGuiElements()
1942 if ( mBlockUpdates )
1945 mBlockUpdates =
true;
1947 if ( mFilterMapItemsListView->model() )
1949 QAbstractItemModel *oldModel = mFilterMapItemsListView->model();
1950 mFilterMapItemsListView->setModel(
nullptr );
1951 oldModel->deleteLater();
1954 QgsLayoutLegendMapFilteringModel *model =
new QgsLayoutLegendMapFilteringModel( mLegendItem, mLegendItem->layout()->itemsModel(), mFilterMapItemsListView );
1955 mFilterMapItemsListView->setModel( model );
1957 mBlockUpdates =
false;
1965 : QSortFilterProxyModel( parent )
1966 , mLayoutModel( layoutModel )
1967 , mLegendItem( legend )
1969 setSourceModel( layoutModel );
1972int QgsLayoutLegendMapFilteringModel::columnCount(
const QModelIndex & )
const
1977QVariant QgsLayoutLegendMapFilteringModel::data(
const QModelIndex &i,
int role )
const
1982 if ( i.column() != 0 )
1987 QgsLayoutItemMap *mapItem = qobject_cast< QgsLayoutItemMap * >( mLayoutModel->itemFromIndex( mapToSource( i ) ) );
1995 case Qt::CheckStateRole:
1996 switch ( i.column() )
2001 return Qt::Unchecked;
2003 return mLegendItem->filterByMapItems().contains( mapItem ) ? Qt::Checked : Qt::Unchecked;
2011 return mLayoutModel->data( sourceIndex, role );
2015bool QgsLayoutLegendMapFilteringModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
2019 if ( !index.isValid() )
2022 QgsLayoutItemMap *mapItem = qobject_cast< QgsLayoutItemMap * >( mLayoutModel->itemFromIndex( mapToSource( index ) ) );
2023 if ( !mapItem || !mLegendItem )
2028 mLegendItem->layout()->undoStack()->beginCommand( mLegendItem, tr(
"Change Legend Linked Maps" ) );
2030 QList< QgsLayoutItemMap * > linkedMaps = mLegendItem->filterByMapItems();
2031 if ( value.toBool() )
2033 if ( !linkedMaps.contains( mapItem ) )
2035 linkedMaps.append( mapItem );
2036 mLegendItem->setFilterByMapItems( linkedMaps );
2041 linkedMaps.removeAll( mapItem );
2042 mLegendItem->setFilterByMapItems( linkedMaps );
2044 emit dataChanged( index, index, QVector<int>() << role );
2046 mLegendItem->layout()->undoStack()->endCommand();
2047 mLegendItem->invalidateCache();
2052Qt::ItemFlags QgsLayoutLegendMapFilteringModel::flags(
const QModelIndex &index )
const
2054 Qt::ItemFlags flags = QSortFilterProxyModel::flags( index );
2056 if ( ! index.isValid() )
2061 QgsLayoutItemMap *mapItem = qobject_cast< QgsLayoutItemMap * >( mLayoutModel->itemFromIndex( mapToSource( index ) ) );
2062 const bool isMainLinkedMapItem = mLegendItem ? ( mLegendItem->linkedMap() == mapItem ) :
false;
2068 if ( !isMainLinkedMapItem )
2070 flags |= Qt::ItemIsEnabled;
2074 flags &= ~Qt::ItemIsEnabled;
2077 switch ( index.column() )
2080 if ( !isMainLinkedMapItem )
2081 return flags | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
2083 return flags | Qt::ItemIsSelectable;
2086 return flags | Qt::ItemIsSelectable;
2090bool QgsLayoutLegendMapFilteringModel::filterAcceptsRow(
int source_row,
const QModelIndex &source_parent )
const
2092 QgsLayoutItem *item = mLayoutModel->itemFromIndex( mLayoutModel->index( source_row, 0, source_parent ) );
2093 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 addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user.
virtual QgsLegendSymbolList legendSymbolItems() const
Returns a list of symbology items for the legend.
Layer tree group node serves as a container for layers and further groups.
void insertChildNode(int index, QgsLayerTreeNode *node)
Insert existing node at specified position.
void setName(const QString &n) override
Sets the group's name.
void removeChildNode(QgsLayerTreeNode *node)
Remove a child node from this group.
QString name() const override
Returns the group's name.
Layer tree node points to a map layer.
void setPatchSize(QSizeF size)
Sets the user (overridden) size for the legend node.
QString labelExpression() const
Returns the expression member of the LayerTreeNode.
LegendNodesSplitBehavior
Legend node column split behavior.
@ AllowSplittingLegendNodesOverMultipleColumns
Allow splitting node's legend nodes across multiple columns.
@ PreventSplittingLegendNodesOverMultipleColumns
Prevent splitting node's legend nodes across multiple columns.
@ UseDefaultLegendSetting
Inherit default legend column splitting setting.
void setLabelExpression(const QString &expression)
set the expression to evaluate
void setPatchShape(const QgsLegendPatchShape &shape)
Sets the symbol patch shape to use when rendering the legend node symbol.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
The QgsLegendRendererItem class is abstract interface for legend items returned from QgsMapLayerLegen...
NodeTypes
Types of legend nodes.
@ SimpleLegend
Simple label with icon legend node type.
@ RasterSymbolLegend
Raster symbol legend node type.
@ ImageLegend
Raster image legend node type.
@ DataDefinedSizeLegend
Marker symbol legend node type.
@ WmsLegend
WMS legend node type.
@ EmbeddedWidget
Embedded widget placeholder node type.
@ ColorRampLegend
Color ramp legend (since QGIS 3.18)
@ SymbolLegend
Vector symbol legend node type.
@ NodeTypeRole
Type of node. Added in 3.16.
QgsLayerTreeModel * model() const
Returns pointer to model owning this legend node.
QgsLayerTreeLayer * layerNode() const
Returns pointer to the parent layer node.
QgsLayerTreeModelLegendNode * legendNodeEmbeddedInParent(QgsLayerTreeLayer *nodeLayer) const
Returns legend node that may be embedded in parent (i.e.
QList< QgsLayerTreeModelLegendNode * > layerOriginalLegendNodes(QgsLayerTreeLayer *nodeLayer)
Returns original (unfiltered) list of legend nodes attached to a particular layer node.
This class is a base class for nodes in a layer tree.
void setCustomProperty(const QString &key, const QVariant &value)
Sets a custom property for the node. Properties are stored in a map and saved in project file.
void removeCustomProperty(const QString &key)
Remove a custom property from layer. Properties are stored in a map and saved in project file.
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer. Properties are stored in a map and saved in project file.
QgsLayerTreeNode * parent()
Gets pointer to the parent. If parent is nullptr, the node is a root node.
QStringList customProperties() const
Returns list of keys stored in custom properties.
virtual QgsLayerTreeNode * clone() const =0
Create a copy of the node. Returns new instance.
static void setLegendFilterByExpression(QgsLayerTreeLayer &layer, const QString &expr, bool enabled=true)
Sets the expression filter of a legend layer.
static QString legendFilterByExpression(const QgsLayerTreeLayer &layer, bool *enabled=nullptr)
Returns the expression filter of a legend layer.
The QgsLayerTreeView class extends QTreeView and provides some additional functionality when working ...
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
static bool isLayer(const QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
static bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
static QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group.
Class used to render QgsLayout as an atlas, by iterating over the features from an associated vector ...
void toggled(bool)
Emitted when atlas is enabled or disabled.
A common interface for layout designer dialogs and widgets.
virtual QgsMessageBar * messageBar()=0
Returns the designer's message bar.
void itemChanged(QgsLayoutItem *item)
Emitted whenever the currently selected item changes.
A layout item subclass for map legends.
QgsLegendModel * model()
Returns the legend model.
Layout graphical items for displaying a map.
@ LayoutLegend
Legend item.
Base class for graphical items within a QgsLayout.
@ UndoLegendMinSymbolSize
Legend minimum symbol size.
@ UndoLegendTitleSpaceBottom
Legend title space.
@ UndoLegendIconSymbolSpace
Legend icon symbol space.
@ UndoLegendLayerFont
Legend layer font.
@ UndoLegendBoxSpace
Legend box space.
@ UndoLegendRasterStrokeColor
Legend raster stroke color.
@ UndoLegendTitleFont
Legend title font.
@ UndoLegendItemFont
Legend item font.
@ UndoLegendWmsLegendWidth
Legend WMS width.
@ UndoLegendLayerSpace
Legend layer spacing.
@ UndoLegendColumnSpace
Legend column space.
@ UndoLegendMaxSymbolSize
Legend maximum symbol size.
@ UndoLegendSymbolSpace
Legend symbol spacing.
@ UndoLegendSymbolWidth
Legend symbol width.
@ UndoLegendColumnCount
Legend column count.
@ UndoLegendSymbolHeight
Legend symbol height.
@ UndoLegendGroupSpace
Legend group spacing.
@ UndoLegendSubgroupIndent
Legend subgroup indent.
@ UndoLegendRasterStrokeWidth
Legend raster stroke width.
@ UndoLegendGroupIndent
Legend group indent.
@ UndoLegendText
Legend text.
@ UndoLegendWmsLegendHeight
Legend WMS height.
@ UndoLegendGroupFont
Legend group font.
int type() const override
Returns a unique graphics item type identifier.
A dialog to add new layers to the legend.
This class provides a method of converting QgsLayoutMeasurements from one unit to another.
QgsLayoutMeasurement convert(QgsLayoutMeasurement measurement, Qgis::LayoutUnit targetUnits) const
Converts a measurement from one unit to another.
void setDpi(const double dpi)
Sets the dots per inch (dpi) for the measurement converter.
A model for items attached to a layout.
const QgsLayout * layout() const
Returns the layout the object is attached to.
void changed()
Emitted when the object's properties change.
@ LegendTitle
Legend title.
@ LegendColumnCount
Legend column count.
void layerChanged(QgsVectorLayer *layer)
Emitted when the context's layer is changed.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
QgsLayoutReportContext & reportContext()
Returns a reference to the layout's report context, which stores information relating to the current ...
Represents a patch shape for use in map legends.
void setSymbolType(Qgis::SymbolType type)
Sets the symbol type associated with this patch.
bool isNull() const
Returns true if the patch shape is a null QgsLegendPatchShape, which indicates that the default legen...
static void setNodeLegendStyle(QgsLayerTreeNode *node, QgsLegendStyle::Style style)
Sets the style of a node.
static QgsLegendStyle::Style nodeLegendStyle(QgsLayerTreeNode *node, QgsLayerTreeModel *model)
Returns the style for the given node, within the specified model.
static QString styleLabel(Style s)
Returns a translated string representing a style component, for use in UI.
Style
Component of legends which can be styled.
@ Group
Legend group title.
@ Symbol
Symbol icon (excluding label)
@ Subgroup
Legend subgroup title.
@ Hidden
Special style, item is hidden including margins around.
@ SymbolLabel
Symbol label (excluding icon)
Map canvas is a class for displaying all GIS data types on a canvas.
static void setLegendNodeOrder(QgsLayerTreeLayer *nodeLayer, const QList< int > &order)
static void setLegendNodeColorRampSettings(QgsLayerTreeLayer *nodeLayer, int originalIndex, const QgsColorRampLegendNodeSettings *settings)
Sets a custom legend color ramp settings for the legend node belonging to nodeLayer at the specified ...
static void setLegendNodeCustomSymbol(QgsLayerTreeLayer *nodeLayer, int originalIndex, const QgsSymbol *symbol)
Sets a custom legend symbol for the legend node belonging to nodeLayer at the specified originalIndex...
static void setLegendNodeUserLabel(QgsLayerTreeLayer *nodeLayer, int originalIndex, const QString &newLabel)
static void setLegendNodeSymbolSize(QgsLayerTreeLayer *nodeLayer, int originalIndex, QSizeF size)
Sets the legend symbol size for the legend node belonging to nodeLayer at the specified originalIndex...
static void setLegendNodeColumnBreak(QgsLayerTreeLayer *nodeLayer, int originalIndex, bool columnBreakBeforeNode)
Sets whether a forced column break should occur before the node.
static void setLegendNodePatchShape(QgsLayerTreeLayer *nodeLayer, int originalIndex, const QgsLegendPatchShape &shape)
Sets the legend patch shape for the legend node belonging to nodeLayer at the specified originalIndex...
static QList< int > legendNodeOrder(QgsLayerTreeLayer *nodeLayer)
Base class for all map layer types.
Interface for master layout type objects, such as print layouts and reports.
Implementation of legend node interface for displaying preview of vector symbols and their labels and...
Abstract base class for all rendered symbols.
static bool isNull(const QVariant &variant)
Returns true if the specified variant should be considered a NULL value.
Represents a vector layer which manages a vector based data sets.
QgsExpressionContextScope * createExpressionContextScope() const FINAL
This method needs to be reimplemented in all classes which implement this interface and return an exp...
long long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
QgsFeatureRenderer * renderer()
Returns the feature renderer used for rendering the features in the layer in 2D map views.
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
QgsLayerTreeModelLegendNode * legendNode(const QString &rule, QgsLayerTreeModel &model)
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
QList< QgsLegendSymbolItem > QgsLegendSymbolList
Q_GUI_EXPORT int qt_defaultDpiX()
Single variable definition for use within a QgsExpressionContextScope.