48 #include <QMessageBox> 
   49 #include <QInputDialog> 
   66   int unfilteredNodeIndex = _unfilteredLegendNodeIndex( 
legendNode );
 
   68   return ( unfilteredNodeIndex >= 0 && unfilteredNodeIndex < order.count() ? order[unfilteredNodeIndex] : -1 );
 
   75   , mMapCanvas( mapCanvas )
 
   80   connect( mWrapCharLineEdit, &QLineEdit::textChanged, 
this, &QgsLayoutLegendWidget::mWrapCharLineEdit_textChanged );
 
   81   connect( mTitleLineEdit, &QLineEdit::textChanged, 
this, &QgsLayoutLegendWidget::mTitleLineEdit_textChanged );
 
   86   connect( mColumnCountSpinBox, 
static_cast < void ( QSpinBox::* )( 
int ) 
> ( &QSpinBox::valueChanged ), 
this, &QgsLayoutLegendWidget::mColumnCountSpinBox_valueChanged );
 
   87   connect( mSplitLayerCheckBox, &QCheckBox::toggled, 
this, &QgsLayoutLegendWidget::mSplitLayerCheckBox_toggled );
 
   88   connect( mEqualColumnWidthCheckBox, &QCheckBox::toggled, 
this, &QgsLayoutLegendWidget::mEqualColumnWidthCheckBox_toggled );
 
   89   connect( mSymbolWidthSpinBox, 
static_cast < void ( QDoubleSpinBox::* )( 
double ) 
> ( &QDoubleSpinBox::valueChanged ), 
this, &QgsLayoutLegendWidget::mSymbolWidthSpinBox_valueChanged );
 
   90   connect( mSymbolHeightSpinBox, 
static_cast < void ( QDoubleSpinBox::* )( 
double ) 
> ( &QDoubleSpinBox::valueChanged ), 
this, &QgsLayoutLegendWidget::mSymbolHeightSpinBox_valueChanged );
 
   91   connect( mMaxSymbolSizeSpinBox, 
static_cast < void ( QDoubleSpinBox::* )( 
double ) 
> ( &QDoubleSpinBox::valueChanged ), 
this, &QgsLayoutLegendWidget::mMaxSymbolSizeSpinBox_valueChanged );
 
   92   connect( mMinSymbolSizeSpinBox, 
static_cast < void ( QDoubleSpinBox::* )( 
double ) 
> ( &QDoubleSpinBox::valueChanged ), 
this, &QgsLayoutLegendWidget::mMinSymbolSizeSpinBox_valueChanged );
 
   93   connect( mWmsLegendWidthSpinBox, 
static_cast < void ( QDoubleSpinBox::* )( 
double ) 
> ( &QDoubleSpinBox::valueChanged ), 
this, &QgsLayoutLegendWidget::mWmsLegendWidthSpinBox_valueChanged );
 
   94   connect( mWmsLegendHeightSpinBox, 
static_cast < void ( QDoubleSpinBox::* )( 
double ) 
> ( &QDoubleSpinBox::valueChanged ), 
this, &QgsLayoutLegendWidget::mWmsLegendHeightSpinBox_valueChanged );
 
   95   connect( mTitleSpaceBottomSpinBox, 
static_cast < void ( QDoubleSpinBox::* )( 
double ) 
> ( &QDoubleSpinBox::valueChanged ), 
this, &QgsLayoutLegendWidget::mTitleSpaceBottomSpinBox_valueChanged );
 
   96   connect( mGroupSpaceSpinBox, 
static_cast < void ( QDoubleSpinBox::* )( 
double ) 
> ( &QDoubleSpinBox::valueChanged ), 
this, &QgsLayoutLegendWidget::mGroupSpaceSpinBox_valueChanged );
 
   97   connect( 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 );
 
  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( mLineSpacingSpinBox, 
static_cast < void ( QDoubleSpinBox::* )( 
double ) 
> ( &QDoubleSpinBox::valueChanged ), 
this, &QgsLayoutLegendWidget::mLineSpacingSpinBox_valueChanged );
 
  109   connect( mCheckBoxAutoUpdate, &QCheckBox::stateChanged, 
this, [ = ]( 
int state ) { mCheckBoxAutoUpdate_stateChanged( state ); } );
 
  110   connect( mCheckboxResizeContents, &QCheckBox::toggled, 
this, &QgsLayoutLegendWidget::mCheckboxResizeContents_toggled );
 
  111   connect( mRasterStrokeGroupBox, &QgsCollapsibleGroupBoxBasic::toggled, 
this, &QgsLayoutLegendWidget::mRasterStrokeGroupBox_toggled );
 
  112   connect( mRasterStrokeWidthSpinBox, 
static_cast < void ( QDoubleSpinBox::* )( 
double ) 
> ( &QDoubleSpinBox::valueChanged ), 
this, &QgsLayoutLegendWidget::mRasterStrokeWidthSpinBox_valueChanged );
 
  113   connect( mRasterStrokeColorButton, &
QgsColorButton::colorChanged, 
this, &QgsLayoutLegendWidget::mRasterStrokeColorButton_colorChanged );
 
  114   connect( mMoveDownToolButton, &QToolButton::clicked, 
this, &QgsLayoutLegendWidget::mMoveDownToolButton_clicked );
 
  115   connect( mMoveUpToolButton, &QToolButton::clicked, 
this, &QgsLayoutLegendWidget::mMoveUpToolButton_clicked );
 
  116   connect( mRemoveToolButton, &QToolButton::clicked, 
this, &QgsLayoutLegendWidget::mRemoveToolButton_clicked );
 
  117   connect( mAddToolButton, &QToolButton::clicked, 
this, &QgsLayoutLegendWidget::mAddToolButton_clicked );
 
  118   connect( mEditPushButton, &QToolButton::clicked, 
this, &QgsLayoutLegendWidget::mEditPushButton_clicked );
 
  119   connect( mCountToolButton, &QToolButton::clicked, 
this, &QgsLayoutLegendWidget::mCountToolButton_clicked );
 
  120   connect( mExpressionFilterButton, &QgsLegendFilterButton::toggled, 
this, &QgsLayoutLegendWidget::mExpressionFilterButton_toggled );
 
  121   connect( mLayerExpressionButton, &QToolButton::clicked, 
this, &QgsLayoutLegendWidget::mLayerExpressionButton_clicked );
 
  122   connect( mFilterByMapCheckBox, &QCheckBox::toggled, 
this, &QgsLayoutLegendWidget::mFilterByMapCheckBox_toggled );
 
  123   connect( mUpdateAllPushButton, &QToolButton::clicked, 
this, &QgsLayoutLegendWidget::mUpdateAllPushButton_clicked );
 
  124   connect( mAddGroupToolButton, &QToolButton::clicked, 
this, &QgsLayoutLegendWidget::mAddGroupToolButton_clicked );
 
  125   connect( mFilterLegendByAtlasCheckBox, &QCheckBox::toggled, 
this, &QgsLayoutLegendWidget::mFilterLegendByAtlasCheckBox_toggled );
 
  126   connect( mItemTreeView, &QgsLayerTreeView::doubleClicked, 
this, &QgsLayoutLegendWidget::mItemTreeView_doubleClicked );
 
  127   setPanelTitle( tr( 
"Legend Properties" ) );
 
  134   mTitleAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
 
  135   mGroupAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
 
  136   mSubgroupAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
 
  137   mItemAlignCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight );
 
  139   mArrangementCombo->setAvailableAlignments( Qt::AlignLeft | Qt::AlignRight );
 
  141   mArrangementCombo->customizeAlignmentDisplay( Qt::AlignLeft, tr( 
"Symbols on Left" ), 
QgsApplication::getThemeIcon( QStringLiteral( 
"/mIconArrangeSymbolsLeft.svg" ) ) );
 
  142   mArrangementCombo->customizeAlignmentDisplay( Qt::AlignRight, tr( 
"Symbols on Right" ), 
QgsApplication::getThemeIcon( QStringLiteral( 
"/mIconArrangeSymbolsRight.svg" ) ) );
 
  144   mSpaceBelowGroupHeadingSpinBox->setClearValue( 0 );
 
  145   mGroupSideSpinBox->setClearValue( 0 );
 
  146   mSpaceBelowSubgroupHeadingSpinBox->setClearValue( 0 );
 
  147   mSubgroupSideSpinBox->setClearValue( 0 );
 
  148   mSymbolSideSpaceSpinBox->setClearValue( 0 );
 
  169   mFontColorButton->setColorDialogTitle( tr( 
"Select Font Color" ) );
 
  170   mFontColorButton->setContext( QStringLiteral( 
"composer" ) );
 
  172   mRasterStrokeColorButton->setColorDialogTitle( tr( 
"Select Stroke Color" ) );
 
  173   mRasterStrokeColorButton->setAllowOpacity( 
true );
 
  174   mRasterStrokeColorButton->setContext( QStringLiteral( 
"composer " ) );
 
  176   mMapComboBox->setCurrentLayout( legend->
layout() );
 
  182   mainLayout->addWidget( mItemPropertiesWidget );
 
  184   mItemTreeView->setHeaderHidden( 
true );
 
  186   mItemTreeView->setModel( legend->
model() );
 
  187   mItemTreeView->setMenuProvider( 
new QgsLayoutLegendMenuProvider( mItemTreeView, 
this ) );
 
  188   setLegendMapViewData();
 
  194     connect( layoutAtlas(), &
QgsLayoutAtlas::toggled, 
this, &QgsLayoutLegendWidget::updateFilterLegendByAtlasButton );
 
  203   connect( mItemTreeView->selectionModel(), &QItemSelectionModel::currentChanged,
 
  204            this, &QgsLayoutLegendWidget::selectedChanged );
 
  213   if ( mItemPropertiesWidget )
 
  214     mItemPropertiesWidget->setMasterLayout( masterLayout );
 
  217 void QgsLayoutLegendWidget::setGuiElements()
 
  224   blockAllSignals( 
true );
 
  225   mTitleLineEdit->setText( mLegend->title() );
 
  226   whileBlocking( mTitleAlignCombo )->setCurrentAlignment( mLegend->titleAlignment() );
 
  230   whileBlocking( mArrangementCombo )->setCurrentAlignment( mLegend->symbolAlignment() );
 
  231   mFilterByMapCheckBox->setChecked( mLegend->legendFilterByMapEnabled() );
 
  232   mColumnCountSpinBox->setValue( mLegend->columnCount() );
 
  233   mSplitLayerCheckBox->setChecked( mLegend->splitLayer() );
 
  234   mEqualColumnWidthCheckBox->setChecked( mLegend->equalColumnWidth() );
 
  235   mSymbolWidthSpinBox->setValue( mLegend->symbolWidth() );
 
  236   mSymbolHeightSpinBox->setValue( mLegend->symbolHeight() );
 
  237   mMaxSymbolSizeSpinBox->setValue( mLegend->maximumSymbolSize() );
 
  238   mMinSymbolSizeSpinBox->setValue( mLegend->minimumSymbolSize() );
 
  239   mWmsLegendWidthSpinBox->setValue( mLegend->wmsLegendWidth() );
 
  240   mWmsLegendHeightSpinBox->setValue( mLegend->wmsLegendHeight() );
 
  252   mBoxSpaceSpinBox->setValue( mLegend->boxSpace() );
 
  253   mColumnSpaceSpinBox->setValue( mLegend->columnSpace() );
 
  254   mLineSpacingSpinBox->setValue( mLegend->lineSpacing() );
 
  256   mRasterStrokeGroupBox->setChecked( mLegend->drawRasterStroke() );
 
  257   mRasterStrokeWidthSpinBox->setValue( mLegend->rasterStrokeWidth() );
 
  258   mRasterStrokeColorButton->setColor( mLegend->rasterStrokeColor() );
 
  260   mCheckBoxAutoUpdate->setChecked( mLegend->autoUpdateModel() );
 
  262   mCheckboxResizeContents->setChecked( mLegend->resizeToContents() );
 
  263   mFilterLegendByAtlasCheckBox->setChecked( mLegend->legendFilterOutAtlas() );
 
  264   mWrapCharLineEdit->setText( mLegend->wrapString() );
 
  267   mMapComboBox->setItem( map );
 
  268   mFontColorButton->setColor( mLegend->fontColor() );
 
  274   blockAllSignals( 
false );
 
  276   mCheckBoxAutoUpdate_stateChanged( mLegend->autoUpdateModel() ? Qt::Checked : Qt::Unchecked, 
false );
 
  277   updateDataDefinedButton( mLegendTitleDDBtn );
 
  278   updateDataDefinedButton( mColumnsDDBtn );
 
  281 void QgsLayoutLegendWidget::mWrapCharLineEdit_textChanged( 
const QString &text )
 
  285     mLegend->beginCommand( tr( 
"Change Legend Wrap" ) );
 
  286     mLegend->setWrapString( text );
 
  287     mLegend->adjustBoxSize();
 
  289     mLegend->endCommand();
 
  293 void QgsLayoutLegendWidget::mTitleLineEdit_textChanged( 
const QString &text )
 
  298     mLegend->setTitle( text );
 
  299     mLegend->adjustBoxSize();
 
  301     mLegend->endCommand();
 
  305 void QgsLayoutLegendWidget::titleAlignmentChanged()
 
  309     Qt::AlignmentFlag alignment = 
static_cast< Qt::AlignmentFlag 
>( 
static_cast< int  >( mTitleAlignCombo->currentAlignment() & Qt::AlignHorizontal_Mask ) );
 
  310     mLegend->beginCommand( tr( 
"Change Title Alignment" ) );
 
  311     mLegend->setTitleAlignment( alignment );
 
  313     mLegend->endCommand();
 
  317 void QgsLayoutLegendWidget::groupAlignmentChanged()
 
  321     mLegend->beginCommand( tr( 
"Change Group Alignment" ) );
 
  324     mLegend->endCommand();
 
  328 void QgsLayoutLegendWidget::subgroupAlignmentChanged()
 
  332     mLegend->beginCommand( tr( 
"Change Subgroup Alignment" ) );
 
  335     mLegend->endCommand();
 
  339 void QgsLayoutLegendWidget::itemAlignmentChanged()
 
  343     mLegend->beginCommand( tr( 
"Change Item Alignment" ) );
 
  346     mLegend->endCommand();
 
  350 void QgsLayoutLegendWidget::arrangementChanged()
 
  354     Qt::AlignmentFlag alignment = 
static_cast< Qt::AlignmentFlag 
>( 
static_cast< int  >( mArrangementCombo->currentAlignment() & Qt::AlignHorizontal_Mask ) );
 
  355     mLegend->beginCommand( tr( 
"Change Legend Arrangement" ) );
 
  356     mLegend->setSymbolAlignment( alignment );
 
  358     mLegend->endCommand();
 
  362 void QgsLayoutLegendWidget::mColumnCountSpinBox_valueChanged( 
int c )
 
  367     mLegend->setColumnCount( 
c );
 
  368     mLegend->adjustBoxSize();
 
  370     mLegend->endCommand();
 
  372   mSplitLayerCheckBox->setEnabled( 
c > 1 );
 
  373   mEqualColumnWidthCheckBox->setEnabled( 
c > 1 );
 
  376 void QgsLayoutLegendWidget::mSplitLayerCheckBox_toggled( 
bool checked )
 
  380     mLegend->beginCommand( tr( 
"Split Legend Layers" ) );
 
  381     mLegend->setSplitLayer( checked );
 
  382     mLegend->adjustBoxSize();
 
  384     mLegend->endCommand();
 
  388 void QgsLayoutLegendWidget::mEqualColumnWidthCheckBox_toggled( 
bool checked )
 
  392     mLegend->beginCommand( tr( 
"Legend Column Width" ) );
 
  393     mLegend->setEqualColumnWidth( checked );
 
  394     mLegend->adjustBoxSize();
 
  396     mLegend->endCommand();
 
  400 void QgsLayoutLegendWidget::mSymbolWidthSpinBox_valueChanged( 
double d )
 
  405     mLegend->setSymbolWidth( d );
 
  406     mLegend->adjustBoxSize();
 
  408     mLegend->endCommand();
 
  412 void QgsLayoutLegendWidget::mMaxSymbolSizeSpinBox_valueChanged( 
double d )
 
  417     mLegend->setMaximumSymbolSize( d );
 
  418     mLegend->adjustBoxSize();
 
  420     mLegend->endCommand();
 
  424 void QgsLayoutLegendWidget::mMinSymbolSizeSpinBox_valueChanged( 
double d )
 
  429     mLegend->setMinimumSymbolSize( d );
 
  430     mLegend->adjustBoxSize();
 
  432     mLegend->endCommand();
 
  436 void QgsLayoutLegendWidget::mSymbolHeightSpinBox_valueChanged( 
double d )
 
  441     mLegend->setSymbolHeight( d );
 
  442     mLegend->adjustBoxSize();
 
  444     mLegend->endCommand();
 
  448 void QgsLayoutLegendWidget::mWmsLegendWidthSpinBox_valueChanged( 
double d )
 
  453     mLegend->setWmsLegendWidth( d );
 
  454     mLegend->adjustBoxSize();
 
  456     mLegend->endCommand();
 
  460 void QgsLayoutLegendWidget::mWmsLegendHeightSpinBox_valueChanged( 
double d )
 
  465     mLegend->setWmsLegendHeight( d );
 
  466     mLegend->adjustBoxSize();
 
  468     mLegend->endCommand();
 
  472 void QgsLayoutLegendWidget::mTitleSpaceBottomSpinBox_valueChanged( 
double d )
 
  478     mLegend->adjustBoxSize();
 
  480     mLegend->endCommand();
 
  484 void QgsLayoutLegendWidget::mGroupSpaceSpinBox_valueChanged( 
double d )
 
  490     mLegend->adjustBoxSize();
 
  492     mLegend->endCommand();
 
  496 void QgsLayoutLegendWidget::spaceBelowGroupHeadingChanged( 
double space )
 
  502     mLegend->adjustBoxSize();
 
  504     mLegend->endCommand();
 
  508 void QgsLayoutLegendWidget::spaceGroupSideChanged( 
double space )
 
  514     mLegend->adjustBoxSize();
 
  516     mLegend->endCommand();
 
  520 void QgsLayoutLegendWidget::spaceSubGroupSideChanged( 
double space )
 
  526     mLegend->adjustBoxSize();
 
  528     mLegend->endCommand();
 
  532 void QgsLayoutLegendWidget::spaceSymbolSideChanged( 
double space )
 
  538     mLegend->adjustBoxSize();
 
  540     mLegend->endCommand();
 
  544 void QgsLayoutLegendWidget::mLayerSpaceSpinBox_valueChanged( 
double d )
 
  550     mLegend->adjustBoxSize();
 
  552     mLegend->endCommand();
 
  556 void QgsLayoutLegendWidget::mSymbolSpaceSpinBox_valueChanged( 
double d )
 
  564     mLegend->adjustBoxSize();
 
  566     mLegend->endCommand();
 
  570 void QgsLayoutLegendWidget::mIconLabelSpaceSpinBox_valueChanged( 
double d )
 
  576     mLegend->adjustBoxSize();
 
  578     mLegend->endCommand();
 
  582 void QgsLayoutLegendWidget::titleFontChanged()
 
  588     mLegend->adjustBoxSize();
 
  590     mLegend->endCommand();
 
  594 void QgsLayoutLegendWidget::groupFontChanged()
 
  600     mLegend->adjustBoxSize();
 
  602     mLegend->endCommand();
 
  606 void QgsLayoutLegendWidget::layerFontChanged()
 
  612     mLegend->adjustBoxSize();
 
  614     mLegend->endCommand();
 
  618 void QgsLayoutLegendWidget::itemFontChanged()
 
  624     mLegend->adjustBoxSize();
 
  626     mLegend->endCommand();
 
  630 void QgsLayoutLegendWidget::spaceBelowSubGroupHeadingChanged( 
double space )
 
  636     mLegend->adjustBoxSize();
 
  638     mLegend->endCommand();
 
  642 void QgsLayoutLegendWidget::mFontColorButton_colorChanged( 
const QColor &newFontColor )
 
  650   mLegend->setFontColor( newFontColor );
 
  652   mLegend->endCommand();
 
  655 void QgsLayoutLegendWidget::mBoxSpaceSpinBox_valueChanged( 
double d )
 
  660     mLegend->setBoxSpace( d );
 
  661     mLegend->adjustBoxSize();
 
  663     mLegend->endCommand();
 
  667 void QgsLayoutLegendWidget::mColumnSpaceSpinBox_valueChanged( 
double d )
 
  672     mLegend->setColumnSpace( d );
 
  673     mLegend->adjustBoxSize();
 
  675     mLegend->endCommand();
 
  679 void QgsLayoutLegendWidget::mLineSpacingSpinBox_valueChanged( 
double d )
 
  684     mLegend->setLineSpacing( d );
 
  685     mLegend->adjustBoxSize();
 
  687     mLegend->endCommand();
 
  691 static void _moveLegendNode( 
QgsLayerTreeLayer *nodeLayer, 
int legendNodeIndex, 
int offset )
 
  695   if ( legendNodeIndex < 0 || legendNodeIndex >= order.count() )
 
  697   if ( legendNodeIndex + offset < 0 || legendNodeIndex + offset >= order.count() )
 
  700   int id = order.takeAt( legendNodeIndex );
 
  701   order.insert( legendNodeIndex + offset, 
id );
 
  707 void QgsLayoutLegendWidget::mMoveDownToolButton_clicked()
 
  714   const QModelIndex index = mItemTreeView->selectionModel()->currentIndex();
 
  715   const QModelIndex sourceIndex = mItemTreeView->proxyModel()->mapToSource( index );
 
  716   const QModelIndex parentIndex = sourceIndex.parent();
 
  717   if ( !sourceIndex.isValid() || sourceIndex.row() == mItemTreeView->layerTreeModel()->rowCount( parentIndex ) - 1 )
 
  725   mLegend->beginCommand( tr( 
"Moved Legend Item Down" ) );
 
  739   mItemTreeView->setCurrentIndex( mItemTreeView->proxyModel()->mapFromSource( mItemTreeView->layerTreeModel()->index( sourceIndex.row() + 1, 0, parentIndex ) ) );
 
  742   mLegend->endCommand();
 
  745 void QgsLayoutLegendWidget::mMoveUpToolButton_clicked()
 
  752   const QModelIndex index = mItemTreeView->selectionModel()->currentIndex();
 
  753   const QModelIndex sourceIndex = mItemTreeView->proxyModel()->mapToSource( index );
 
  754   const QModelIndex parentIndex = sourceIndex.parent();
 
  755   if ( !sourceIndex.isValid() || sourceIndex.row() == 0 )
 
  763   mLegend->beginCommand( tr( 
"Move Legend Item Up" ) );
 
  777   mItemTreeView->setCurrentIndex( mItemTreeView->proxyModel()->mapFromSource( mItemTreeView->layerTreeModel()->index( sourceIndex.row() - 1, 0, parentIndex ) ) );
 
  780   mLegend->endCommand();
 
  783 void QgsLayoutLegendWidget::mCheckBoxAutoUpdate_stateChanged( 
int state, 
bool userTriggered )
 
  787     mLegend->beginCommand( tr( 
"Change Auto Update" ) );
 
  789     mLegend->setAutoUpdateModel( state == Qt::Checked );
 
  791     mLegend->updateFilterByMap();
 
  792     mLegend->endCommand();
 
  796   QList<QWidget *> widgets;
 
  797   widgets << mMoveDownToolButton << mMoveUpToolButton << mRemoveToolButton << mAddToolButton
 
  798           << mEditPushButton << mCountToolButton << mUpdateAllPushButton << mAddGroupToolButton
 
  799           << mExpressionFilterButton;
 
  800   for ( QWidget *w : std::as_const( widgets ) )
 
  801     w->setEnabled( state != Qt::Checked );
 
  803   if ( state == Qt::Unchecked )
 
  806     selectedChanged( QModelIndex(), QModelIndex() );
 
  810 void QgsLayoutLegendWidget::composerMapChanged( 
QgsLayoutItem *item )
 
  826     mLegend->beginCommand( tr( 
"Change Legend Map" ) );
 
  827     mLegend->setLinkedMap( map );
 
  828     mLegend->updateFilterByMap();
 
  829     mLegend->endCommand();
 
  831     setLegendMapViewData();
 
  835 void QgsLayoutLegendWidget::mCheckboxResizeContents_toggled( 
bool checked )
 
  842   mLegend->beginCommand( tr( 
"Resize Legend to Contents" ) );
 
  843   mLegend->setResizeToContents( checked );
 
  845     mLegend->adjustBoxSize();
 
  846   mLegend->updateFilterByMap();
 
  847   mLegend->endCommand();
 
  850 void QgsLayoutLegendWidget::mRasterStrokeGroupBox_toggled( 
bool state )
 
  857   mLegend->beginCommand( tr( 
"Change Legend Borders" ) );
 
  858   mLegend->setDrawRasterStroke( state );
 
  859   mLegend->adjustBoxSize();
 
  861   mLegend->endCommand();
 
  864 void QgsLayoutLegendWidget::mRasterStrokeWidthSpinBox_valueChanged( 
double d )
 
  872   mLegend->setRasterStrokeWidth( d );
 
  873   mLegend->adjustBoxSize();
 
  875   mLegend->endCommand();
 
  878 void QgsLayoutLegendWidget::mRasterStrokeColorButton_colorChanged( 
const QColor &newColor )
 
  886   mLegend->setRasterStrokeColor( newColor );
 
  888   mLegend->endCommand();
 
  891 void QgsLayoutLegendWidget::mAddToolButton_clicked()
 
  898   QList< QgsMapLayer * > visibleLayers;
 
  899   if ( mLegend->linkedMap() )
 
  901     visibleLayers = mLegend->linkedMap()->layersToRender();
 
  903   if ( visibleLayers.isEmpty() )
 
  906     visibleLayers = mMapCanvas->layers();
 
  910   addDialog.setVisibleLayers( visibleLayers );
 
  911   if ( addDialog.exec() == QDialog::Accepted )
 
  913     const QList<QgsMapLayer *> layers = addDialog.selectedLayers();
 
  914     if ( !layers.empty() )
 
  916       mLegend->beginCommand( tr( 
"Add Legend Item(s)" ) );
 
  919         mLegend->model()->rootGroup()->addLayer( layer );
 
  921       mLegend->updateLegend();
 
  923       mLegend->endCommand();
 
  928 void QgsLayoutLegendWidget::mRemoveToolButton_clicked()
 
  935   QItemSelectionModel *selectionModel = mItemTreeView->selectionModel();
 
  936   if ( !selectionModel )
 
  941   mLegend->beginCommand( tr( 
"Remove Legend Item" ) );
 
  943   QList<QPersistentModelIndex> proxyIndexes;
 
  944   const QModelIndexList viewSelection = selectionModel->selectedIndexes();
 
  945   for ( 
const QModelIndex &index : viewSelection )
 
  946     proxyIndexes << index;
 
  949   QHash<QgsLayerTreeLayer *, QList<int> > nodesWithRemoval;
 
  950   for ( 
const QPersistentModelIndex &proxyIndex : std::as_const( proxyIndexes ) )
 
  955       nodesWithRemoval[nodeLayer].append( _unfilteredLegendNodeIndex( 
legendNode ) );
 
  958   for ( 
auto it = nodesWithRemoval.constBegin(); it != nodesWithRemoval.constEnd(); ++it )
 
  960     QList<int> toDelete = it.value();
 
  961     std::sort( toDelete.begin(), toDelete.end(), std::greater<int>() );
 
  964     for ( 
int i : std::as_const( toDelete ) )
 
  966       if ( i >= 0 && i < order.count() )
 
  971     mItemTreeView->layerTreeModel()->refreshLayerLegend( it.key() );
 
  975   for ( 
const QPersistentModelIndex &proxyIndex : std::as_const( proxyIndexes ) )
 
  977     if ( proxyIndex.isValid() && mItemTreeView->index2node( proxyIndex ) )
 
  979       const QModelIndex sourceIndex = mItemTreeView->proxyModel()->mapToSource( proxyIndex );
 
  980       mLegend->model()->removeRow( sourceIndex.row(), sourceIndex.parent() );
 
  984   mLegend->updateLegend();
 
  986   mLegend->endCommand();
 
  989 void QgsLayoutLegendWidget::mEditPushButton_clicked()
 
  996   QModelIndex idx = mItemTreeView->selectionModel()->currentIndex();
 
  997   mItemTreeView_doubleClicked( idx );
 
 1000 void QgsLayoutLegendWidget::resetLayerNodeToDefaults()
 
 1008   QModelIndex currentIndex = mItemTreeView->currentIndex();
 
 1009   if ( !currentIndex.isValid() )
 
 1028   mLegend->beginCommand( tr( 
"Update Legend" ) );
 
 1031   for ( 
const QString &key : constCustomProperties )
 
 1033     if ( key.startsWith( QLatin1String( 
"legend/" ) ) )
 
 1040   mItemTreeView->layerTreeModel()->refreshLayerLegend( nodeLayer );
 
 1042   mLegend->updateLegend();
 
 1044   mLegend->endCommand();
 
 1047 void QgsLayoutLegendWidget::mCountToolButton_clicked( 
bool checked )
 
 1054   const QList< QModelIndex > selectedIndexes = mItemTreeView->selectionModel()->selectedIndexes();
 
 1055   if ( selectedIndexes.empty() )
 
 1058   mLegend->beginCommand( tr( 
"Update Legend" ) );
 
 1059   for ( 
const QModelIndex &index : selectedIndexes )
 
 1065     currentNode->
setCustomProperty( QStringLiteral( 
"showFeatureCount" ), checked ? 1 : 0 );
 
 1067   mLegend->updateFilterByMap();
 
 1068   mLegend->adjustBoxSize();
 
 1069   mLegend->endCommand();
 
 1072 void QgsLayoutLegendWidget::mFilterByMapCheckBox_toggled( 
bool checked )
 
 1074   mLegend->beginCommand( tr( 
"Update Legend" ) );
 
 1075   mLegend->setLegendFilterByMapEnabled( checked );
 
 1076   mLegend->adjustBoxSize();
 
 1078   mLegend->endCommand();
 
 1081 void QgsLayoutLegendWidget::mExpressionFilterButton_toggled( 
bool checked )
 
 1089   QModelIndex currentIndex = mItemTreeView->currentIndex();
 
 1090   if ( !currentIndex.isValid() )
 
 1100       mExpressionFilterButton->expressionText(),
 
 1103   mLegend->beginCommand( tr( 
"Update Legend" ) );
 
 1104   mLegend->updateFilterByMap();
 
 1105   mLegend->adjustBoxSize();
 
 1106   mLegend->endCommand();
 
 1109 void QgsLayoutLegendWidget::mLayerExpressionButton_clicked()
 
 1116   QModelIndex currentIndex = mItemTreeView->currentIndex();
 
 1117   if ( !currentIndex.isValid() )
 
 1124   QgsLayerTreeLayer *layerNode = qobject_cast<QgsLayerTreeLayer *>( currentNode );
 
 1130   QString currentExpression;
 
 1132     currentExpression = QStringLiteral( 
"@symbol_label" );
 
 1142   QStringList highlighted;
 
 1147     if ( !legendSymbols.empty() )
 
 1153       highlighted << QStringLiteral( 
"symbol_label" ) << QStringLiteral( 
"symbol_id" );
 
 1155       highlighted << QStringLiteral( 
"symbol_count" );
 
 1164   if ( expressiondialog.exec() )
 
 1167   mLegend->beginCommand( tr( 
"Update Legend" ) );
 
 1169   mLegend->adjustBoxSize();
 
 1170   mLegend->endCommand();
 
 1173 void QgsLayoutLegendWidget::mUpdateAllPushButton_clicked()
 
 1178 void QgsLayoutLegendWidget::mAddGroupToolButton_clicked()
 
 1182     mLegend->beginCommand( tr( 
"Add Legend Group" ) );
 
 1183     mLegend->model()->rootGroup()->addGroup( tr( 
"Group" ) );
 
 1184     mLegend->updateLegend();
 
 1186     mLegend->endCommand();
 
 1190 void QgsLayoutLegendWidget::mFilterLegendByAtlasCheckBox_toggled( 
bool toggled )
 
 1195     mLegend->setLegendFilterOutAtlas( toggled );
 
 1201 void QgsLayoutLegendWidget::updateLegend()
 
 1205     mLegend->beginCommand( tr( 
"Update Legend" ) );
 
 1208     mLegend->setAutoUpdateModel( 
true );
 
 1209     mLegend->setAutoUpdateModel( 
false );
 
 1210     mLegend->updateFilterByMap();
 
 1211     mLegend->endCommand();
 
 1215 void QgsLayoutLegendWidget::setReportTypeString( 
const QString &
string )
 
 1217   mFilterLegendByAtlasCheckBox->setText( tr( 
"Only show items inside current %1 feature" ).arg( 
string ) );
 
 1218   mFilterLegendByAtlasCheckBox->setToolTip( tr( 
"Filter out legend elements that lie outside the current %1 feature." ).arg( 
string ) );
 
 1221 bool QgsLayoutLegendWidget::setNewItem( 
QgsLayoutItem *item )
 
 1231   mLegend = qobject_cast< QgsLayoutItemLegend * >( item );
 
 1232   mItemPropertiesWidget->setItem( mLegend );
 
 1236     mItemTreeView->setModel( mLegend->model() );
 
 1245 void QgsLayoutLegendWidget::blockAllSignals( 
bool b )
 
 1247   mTitleLineEdit->blockSignals( b );
 
 1248   mTitleAlignCombo->blockSignals( b );
 
 1249   mItemTreeView->blockSignals( b );
 
 1250   mCheckBoxAutoUpdate->blockSignals( b );
 
 1251   mMapComboBox->blockSignals( b );
 
 1252   mFilterByMapCheckBox->blockSignals( b );
 
 1253   mColumnCountSpinBox->blockSignals( b );
 
 1254   mSplitLayerCheckBox->blockSignals( b );
 
 1255   mEqualColumnWidthCheckBox->blockSignals( b );
 
 1256   mSymbolWidthSpinBox->blockSignals( b );
 
 1257   mSymbolHeightSpinBox->blockSignals( b );
 
 1258   mMaxSymbolSizeSpinBox->blockSignals( b );
 
 1259   mMinSymbolSizeSpinBox->blockSignals( b );
 
 1260   mGroupSpaceSpinBox->blockSignals( b );
 
 1261   mSpaceBelowGroupHeadingSpinBox->blockSignals( b );
 
 1262   mGroupSideSpinBox->blockSignals( b );
 
 1263   mSpaceBelowSubgroupHeadingSpinBox->blockSignals( b );
 
 1264   mSubgroupSideSpinBox->blockSignals( b );
 
 1265   mLayerSpaceSpinBox->blockSignals( b );
 
 1266   mSymbolSpaceSpinBox->blockSignals( b );
 
 1267   mSymbolSideSpaceSpinBox->blockSignals( b );
 
 1268   mIconLabelSpaceSpinBox->blockSignals( b );
 
 1269   mBoxSpaceSpinBox->blockSignals( b );
 
 1270   mColumnSpaceSpinBox->blockSignals( b );
 
 1271   mFontColorButton->blockSignals( b );
 
 1272   mRasterStrokeGroupBox->blockSignals( b );
 
 1273   mRasterStrokeColorButton->blockSignals( b );
 
 1274   mRasterStrokeWidthSpinBox->blockSignals( b );
 
 1275   mWmsLegendWidthSpinBox->blockSignals( b );
 
 1276   mWmsLegendHeightSpinBox->blockSignals( b );
 
 1277   mCheckboxResizeContents->blockSignals( b );
 
 1278   mTitleSpaceBottomSpinBox->blockSignals( b );
 
 1279   mFilterLegendByAtlasCheckBox->blockSignals( b );
 
 1280   mTitleFontButton->blockSignals( b );
 
 1281   mGroupFontButton->blockSignals( b );
 
 1282   mLayerFontButton->blockSignals( b );
 
 1283   mItemFontButton->blockSignals( b );
 
 1284   mWrapCharLineEdit->blockSignals( b );
 
 1285   mLineSpacingSpinBox->blockSignals( b );
 
 1288 void QgsLayoutLegendWidget::selectedChanged( 
const QModelIndex ¤t, 
const QModelIndex &previous )
 
 1291   Q_UNUSED( previous )
 
 1293   mLayerExpressionButton->setEnabled( 
false );
 
 1295   if ( mLegend && mLegend->autoUpdateModel() )
 
 1306     mLayerExpressionButton->setEnabled( 
true );
 
 1310   mCountToolButton->setChecked( 
false );
 
 1311   mCountToolButton->setEnabled( 
false );
 
 1314   mExpressionFilterButton->blockSignals( 
true );
 
 1315   mExpressionFilterButton->setChecked( 
false );
 
 1316   mExpressionFilterButton->setEnabled( 
false );
 
 1317   mExpressionFilterButton->blockSignals( 
false );
 
 1328   mCountToolButton->setChecked( currentNode->
customProperty( QStringLiteral( 
"showFeatureCount" ), 0 ).toInt() );
 
 1329   mCountToolButton->setEnabled( 
true );
 
 1330   mLayerExpressionButton->setEnabled( 
true );
 
 1334   mExpressionFilterButton->blockSignals( 
true );
 
 1335   mExpressionFilterButton->setExpressionText( expr );
 
 1336   mExpressionFilterButton->setVectorLayer( vl );
 
 1337   mExpressionFilterButton->setEnabled( 
true );
 
 1338   mExpressionFilterButton->setChecked( exprEnabled );
 
 1339   mExpressionFilterButton->blockSignals( 
false );
 
 1342 void QgsLayoutLegendWidget::setCurrentNodeStyleFromAction()
 
 1344   QAction *a = qobject_cast<QAction *>( sender() );
 
 1345   if ( !a || !mItemTreeView->currentNode() )
 
 1349   mLegend->updateFilterByMap();
 
 1352 void QgsLayoutLegendWidget::setLegendMapViewData()
 
 1354   if ( mLegend->linkedMap() )
 
 1358     measurementConverter.
setDpi( dpi );
 
 1361     double mapUnitsPerPixelX = mLegend->linkedMap()->extent().width() / mapWidth;
 
 1362     double mapUnitsPerPixelY = mLegend->linkedMap()->extent().height() / mapHeight;
 
 1363     mLegend->model()->setLegendMapViewData( ( mapUnitsPerPixelX > mapUnitsPerPixelY ? mapUnitsPerPixelX : mapUnitsPerPixelY ), dpi, mLegend->linkedMap()->scale() );
 
 1367 void QgsLayoutLegendWidget::updateFilterLegendByAtlasButton()
 
 1371     mFilterLegendByAtlasCheckBox->setEnabled( atlas->enabled() && mLegend->layout()->reportContext().layer() && mLegend->layout()->reportContext().layer()->geometryType() == 
QgsWkbTypes::PolygonGeometry );
 
 1375 void QgsLayoutLegendWidget::mItemTreeView_doubleClicked( 
const QModelIndex &idx )
 
 1377   if ( !mLegend || !idx.isValid() )
 
 1382   if ( mLegend->autoUpdateModel() )
 
 1388   int originalIndex = -1;
 
 1391     originalIndex = _originalLegendNodeIndex( 
legendNode );
 
 1395   QgsLayoutLegendNodeWidget *widget = 
new QgsLayoutLegendNodeWidget( mLegend, currentNode, 
legendNode, originalIndex );
 
 1396   openPanel( widget );
 
 1404 QgsLayoutLegendMenuProvider::QgsLayoutLegendMenuProvider( 
QgsLayerTreeView *view, QgsLayoutLegendWidget *w )
 
 1409 QMenu *QgsLayoutLegendMenuProvider::createContextMenu()
 
 1411   if ( !mView->currentNode() )
 
 1414   if ( mWidget->legend()->autoUpdateModel() )
 
 1417   QMenu *menu = 
new QMenu();
 
 1421     menu->addAction( QObject::tr( 
"Reset to Defaults" ), mWidget, &QgsLayoutLegendWidget::resetLayerNodeToDefaults );
 
 1422     menu->addSeparator();
 
 1427   QList<QgsLegendStyle::Style> lst;
 
 1431     QAction *action = menu->addAction( 
QgsLegendStyle::styleLabel( style ), mWidget, &QgsLayoutLegendWidget::setCurrentNodeStyleFromAction );
 
 1432     action->setCheckable( 
true );
 
 1433     action->setChecked( currentStyle == style );
 
 1434     action->setData( 
static_cast< int >( style ) );
 
 1449   , mOriginalLegendNodeIndex( originalLegendNodeIndex )
 
 1452   setPanelTitle( tr( 
"Legend Item Properties" ) );
 
 1461   QString currentLabel;
 
 1464     currentLabel = mLegendNode->data( Qt::EditRole ).toString();
 
 1465     mColumnBreakBeforeCheckBox->setChecked( mLegendNode->columnBreak() );
 
 1469     currentLabel = mLayer->name();
 
 1470     QVariant v = mLayer->customProperty( QStringLiteral( 
"legend/title-label" ) );
 
 1472       currentLabel = v.toString();
 
 1473     mColumnBreakBeforeCheckBox->setChecked( mLayer->customProperty( QStringLiteral( 
"legend/column-break" ) ).toInt() );
 
 1475     mColumnSplitBehaviorComboBox->setCurrentIndex( mColumnSplitBehaviorComboBox->findData( mLayer->legendSplitBehavior() ) );
 
 1480     mColumnBreakBeforeCheckBox->setChecked( mNode->customProperty( QStringLiteral( 
"legend/column-break" ) ).toInt() );
 
 1483   mWidthSpinBox->setClearValue( 0, tr( 
"Default" ) );
 
 1484   mHeightSpinBox->setClearValue( 0, tr( 
"Default" ) );
 
 1485   mWidthSpinBox->setVisible( mLegendNode || mLayer );
 
 1486   mHeightSpinBox->setVisible( mLegendNode || mLayer );
 
 1487   mPatchGroup->setVisible( mLegendNode || mLayer );
 
 1488   mPatchWidthLabel->setVisible( mLegendNode || mLayer );
 
 1489   mPatchHeightLabel->setVisible( mLegendNode || mLayer );
 
 1490   mCustomSymbolCheckBox->setVisible( mLegendNode || mLegend->model()->legendNodeEmbeddedInParent( mLayer ) );
 
 1491   mColumnSplitLabel->setVisible( mLayer && !mLegendNode );
 
 1492   mColumnSplitBehaviorComboBox->setVisible( mLayer && !mLegendNode );
 
 1495     mWidthSpinBox->setValue( mLegendNode->userPatchSize().width() );
 
 1496     mHeightSpinBox->setValue( mLegendNode->userPatchSize().height() );
 
 1500     mWidthSpinBox->setValue( mLayer->patchSize().width() );
 
 1501     mHeightSpinBox->setValue( mLayer->patchSize().height() );
 
 1504   mCustomSymbolCheckBox->setChecked( 
false );
 
 1509     patchShape = symbolLegendNode->patchShape();
 
 1511     std::unique_ptr< QgsSymbol > customSymbol( symbolLegendNode->customSymbol() ? symbolLegendNode->customSymbol()->clone() : 
nullptr );
 
 1512     mCustomSymbolCheckBox->setChecked( customSymbol.get() );
 
 1515       mPatchShapeButton->setPreviewSymbol( customSymbol->clone() );
 
 1516       mCustomSymbolButton->setSymbolType( customSymbol->type() );
 
 1517       mCustomSymbolButton->setSymbol( customSymbol.release() );
 
 1519     else if ( symbolLegendNode->symbol() )
 
 1521       mPatchShapeButton->setPreviewSymbol( symbolLegendNode->symbol()->clone() );
 
 1522       mCustomSymbolButton->setSymbolType( symbolLegendNode->symbol()->type() );
 
 1523       mCustomSymbolButton->setSymbol( symbolLegendNode->symbol()->clone() );
 
 1526   else if ( !mLegendNode && mLayer )
 
 1528     patchShape = mLayer->patchShape();
 
 1531       if ( 
QgsSymbol *customSymbol = symbolLegendNode->customSymbol() )
 
 1533         mCustomSymbolCheckBox->setChecked( 
true );
 
 1534         mPatchShapeButton->setPreviewSymbol( customSymbol->clone() );
 
 1536         mCustomSymbolButton->setSymbol( customSymbol->clone() );
 
 1540         mPatchShapeButton->setPreviewSymbol( symbolLegendNode->symbol()->clone() );
 
 1541         mCustomSymbolButton->setSymbolType( symbolLegendNode->symbol()->type() );
 
 1542         mCustomSymbolButton->setSymbol( symbolLegendNode->symbol()->clone() );
 
 1549     switch ( qobject_cast< QgsVectorLayer * >( mLayer->layer() )->geometryType() )
 
 1564         mPatchShapeLabel->hide();
 
 1565         mPatchShapeButton->hide();
 
 1568     if ( !patchShape.
isNull() )
 
 1569       mPatchShapeButton->setShape( patchShape );
 
 1574     if ( symbolLegendNode->symbol() )
 
 1576       mPatchShapeButton->setSymbolType( symbolLegendNode->symbol()->type() );
 
 1580       mPatchShapeLabel->hide();
 
 1581       mPatchShapeButton->hide();
 
 1586     mPatchShapeLabel->hide();
 
 1587     mPatchShapeButton->hide();
 
 1592     mLabelGroup->hide();
 
 1593     mColorRampLegendWidget->setSettings( colorRampNode->settings() );
 
 1597     mColorRampLegendWidget->hide();
 
 1610         mCustomSymbolCheckBox->hide();
 
 1619   mLabelEdit->setPlainText( currentLabel );
 
 1620   connect( mLabelEdit, &QPlainTextEdit::textChanged, 
this, &QgsLayoutLegendNodeWidget::labelChanged );
 
 1622   connect( mInsertExpressionButton, &QPushButton::clicked, 
this, &QgsLayoutLegendNodeWidget::insertExpression );
 
 1624   connect( mWidthSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), 
this, &QgsLayoutLegendNodeWidget::sizeChanged );
 
 1625   connect( mHeightSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), 
this, &QgsLayoutLegendNodeWidget::sizeChanged );
 
 1627   connect( mCustomSymbolCheckBox, &QGroupBox::toggled, 
this, &QgsLayoutLegendNodeWidget::customSymbolChanged );
 
 1630   connect( mColumnBreakBeforeCheckBox, &QCheckBox::toggled, 
this, &QgsLayoutLegendNodeWidget::columnBreakToggled );
 
 1632   connect( mColumnSplitBehaviorComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), 
this, &QgsLayoutLegendNodeWidget::columnSplitChanged );
 
 1636   connectChildPanel( mColorRampLegendWidget );
 
 1639 void QgsLayoutLegendNodeWidget::setDockMode( 
bool dockMode )
 
 1641   mColorRampLegendWidget->setDockMode( dockMode );
 
 1645 void QgsLayoutLegendNodeWidget::labelChanged()
 
 1649   const QString label = mLabelEdit->toPlainText();
 
 1654   else if ( mLegendNode )
 
 1657     mLegend->model()->refreshLayerLegend( mLayer );
 
 1661     mLayer->setCustomProperty( QStringLiteral( 
"legend/title-label" ), label );
 
 1665       embeddedNode->setUserLabel( QString() );
 
 1668   mLegend->adjustBoxSize();
 
 1669   mLegend->updateFilterByMap();
 
 1670   mLegend->endCommand();
 
 1673 void QgsLayoutLegendNodeWidget::patchChanged()
 
 1675   mLegend->beginCommand( tr( 
"Edit Legend Item" ) );
 
 1681     mLegend->model()->refreshLayerLegend( mLayer );
 
 1685     mLayer->setPatchShape( shape );
 
 1686     const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer, 
false );
 
 1691     mLegend->model()->refreshLayerLegend( mLayer );
 
 1694   mLegend->adjustBoxSize();
 
 1695   mLegend->updateFilterByMap();
 
 1696   mLegend->endCommand();
 
 1699 void QgsLayoutLegendNodeWidget::insertExpression()
 
 1704   QString selText = mLabelEdit->textCursor().selectedText();
 
 1707   selText = selText.replace( QChar( 0x2029 ), QChar( 
'\n' ) );
 
 1710   if ( selText.startsWith( QLatin1String( 
"[%" ) ) && selText.endsWith( QLatin1String( 
"%]" ) ) )
 
 1711     selText = selText.mid( 2, selText.size() - 4 );
 
 1714   QgsVectorLayer *layer = mLegend->layout() ? mLegend->layout()->reportContext().layer() : 
nullptr;
 
 1718   if ( mLayer && mLayer->layer() )
 
 1724                                    << QStringLiteral( 
"legend_column_count" )
 
 1725                                    << QStringLiteral( 
"legend_split_layers" )
 
 1726                                    << QStringLiteral( 
"legend_wrap_string" )
 
 1727                                    << QStringLiteral( 
"legend_filter_by_map" )
 
 1728                                    << QStringLiteral( 
"legend_filter_out_atlas" ) );
 
 1732   exprDlg.setWindowTitle( tr( 
"Insert Expression" ) );
 
 1733   if ( exprDlg.exec() == QDialog::Accepted )
 
 1735     QString expression = exprDlg.expressionText();
 
 1736     if ( !expression.isEmpty() )
 
 1738       mLegend->beginCommand( tr( 
"Insert expression" ) );
 
 1739       mLabelEdit->insertPlainText( 
"[%" + expression + 
"%]" );
 
 1740       mLegend->endCommand();
 
 1745 void QgsLayoutLegendNodeWidget::sizeChanged( 
double )
 
 1747   mLegend->beginCommand( tr( 
"Edit Legend Item" ) );
 
 1748   const QSizeF size = QSizeF( mWidthSpinBox->value(), mHeightSpinBox->value() );
 
 1753     mLegend->model()->refreshLayerLegend( mLayer );
 
 1757     mLayer->setPatchSize( size );
 
 1758     const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer, 
false );
 
 1763     mLegend->model()->refreshLayerLegend( mLayer );
 
 1766   mLegend->adjustBoxSize();
 
 1767   mLegend->updateFilterByMap();
 
 1768   mLegend->endCommand();
 
 1771 void QgsLayoutLegendNodeWidget::customSymbolChanged()
 
 1773   mLegend->beginCommand( tr( 
"Edit Legend Item" ) );
 
 1775   if ( mCustomSymbolCheckBox->isChecked() )
 
 1780       mLegend->model()->refreshLayerLegend( mLayer );
 
 1784       const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer, 
false );
 
 1789       mLegend->model()->refreshLayerLegend( mLayer );
 
 1797       mLegend->model()->refreshLayerLegend( mLayer );
 
 1801       const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer, 
false );
 
 1806       mLegend->model()->refreshLayerLegend( mLayer );
 
 1810   mLegend->adjustBoxSize();
 
 1811   mLegend->updateFilterByMap();
 
 1812   mLegend->endCommand();
 
 1815 void QgsLayoutLegendNodeWidget::colorRampLegendChanged()
 
 1817   mLegend->beginCommand( tr( 
"Edit Legend Item" ) );
 
 1821   mLegend->model()->refreshLayerLegend( mLayer );
 
 1823   mLegend->adjustBoxSize();
 
 1824   mLegend->updateFilterByMap();
 
 1825   mLegend->endCommand();
 
 1828 void QgsLayoutLegendNodeWidget::columnBreakToggled( 
bool checked )
 
 1830   mLegend->beginCommand( tr( 
"Edit Legend Columns" ) );
 
 1835     mLegend->model()->refreshLayerLegend( mLayer );
 
 1839     mLayer->setCustomProperty( QStringLiteral( 
"legend/column-break" ), QString( checked ? 
'1' : 
'0' ) );
 
 1843     mNode->setCustomProperty( QStringLiteral( 
"legend/column-break" ), QString( checked ? 
'1' : 
'0' ) );
 
 1846   mLegend->adjustBoxSize();
 
 1847   mLegend->updateFilterByMap();
 
 1848   mLegend->endCommand();
 
 1851 void QgsLayoutLegendNodeWidget::columnSplitChanged()
 
 1853   mLegend->beginCommand( tr( 
"Edit Legend Columns" ) );
 
 1855   if ( mLayer && !mLegendNode )
 
 1860   mLegend->adjustBoxSize();
 
 1861   mLegend->updateFilterByMap();
 
 1862   mLegend->endCommand();
 
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.
QgsLayerTreeLayer * layerNode() const
Returns pointer to the parent layer node.
@ NodeTypeRole
Type of node. Added in 3.16.
QgsLayerTreeModel * model() const
Returns pointer to model owning this legend 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.
virtual QgsLayerTreeNode * clone() const =0
Create a copy of the node. Returns new instance.
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.
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 bool isLayer(const QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
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.
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.
@ UndoLegendLineSpacing
Legend line spacing.
@ UndoLegendBoxSpace
Legend box space.
@ UndoLegendRasterStrokeColor
Legend raster stroke color.
@ UndoLegendTitleFont
Legend title font.
@ UndoLegendFontColor
Legend font color.
@ 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.
@ UndoLegendRasterStrokeWidth
Legend raster stroke width.
@ 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, QgsUnitTypes::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.
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.
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.