Skip to content

Commit af94d6d

Browse files
authored
Merge pull request #60536 from Djedouas/composer-filtered-legend
Correctly move layout legend nodes when they are filtered
2 parents f4e3641 + 6f32786 commit af94d6d

File tree

1 file changed

+47
-33
lines changed

1 file changed

+47
-33
lines changed

src/gui/layout/qgslayoutlegendwidget.cpp

+47-33
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,40 @@
5353

5454
///@cond PRIVATE
5555

56-
static int _unfilteredLegendNodeIndex( QgsLayerTreeModelLegendNode *legendNode )
56+
namespace
5757
{
58-
return legendNode->model()->layerOriginalLegendNodes( legendNode->layerNode() ).indexOf( legendNode );
59-
}
58+
int _unfilteredLegendNodeIndex( QgsLayerTreeModelLegendNode *legendNode )
59+
{
60+
return legendNode->model()->layerOriginalLegendNodes( legendNode->layerNode() ).indexOf( legendNode );
61+
}
6062

61-
static int _originalLegendNodeIndex( QgsLayerTreeModelLegendNode *legendNode )
62-
{
63-
// figure out index of the legend node as it comes out of the map layer legend.
64-
// first legend nodes may be reordered, output of that is available in layerOriginalLegendNodes().
65-
// next the nodes may be further filtered (by scale, map content etc).
66-
// so here we go in reverse order: 1. find index before filtering, 2. find index before reorder
67-
int unfilteredNodeIndex = _unfilteredLegendNodeIndex( legendNode );
68-
QList<int> order = QgsMapLayerLegendUtils::legendNodeOrder( legendNode->layerNode() );
69-
return ( unfilteredNodeIndex >= 0 && unfilteredNodeIndex < order.count() ? order[unfilteredNodeIndex] : -1 );
70-
}
63+
int _originalLegendNodeIndex( QgsLayerTreeModelLegendNode *legendNode )
64+
{
65+
// figure out index of the legend node as it comes out of the map layer legend.
66+
// first legend nodes may be reordered, output of that is available in layerOriginalLegendNodes().
67+
// next the nodes may be further filtered (by scale, map content etc).
68+
// so here we go in reverse order: 1. find index before filtering, 2. find index before reorder
69+
int unfilteredNodeIndex = _unfilteredLegendNodeIndex( legendNode );
70+
QList<int> order = QgsMapLayerLegendUtils::legendNodeOrder( legendNode->layerNode() );
71+
return ( unfilteredNodeIndex >= 0 && unfilteredNodeIndex < order.count() ? order[unfilteredNodeIndex] : -1 );
72+
}
7173

74+
void _moveLegendNode( QgsLayerTreeLayer *nodeLayer, int legendNodeIndex, int destLegendNodeIndex )
75+
{
76+
QList<int> order = QgsMapLayerLegendUtils::legendNodeOrder( nodeLayer );
77+
const int offset = destLegendNodeIndex - legendNodeIndex;
78+
79+
if ( legendNodeIndex < 0 || legendNodeIndex >= order.count() )
80+
return;
81+
if ( legendNodeIndex + offset < 0 || legendNodeIndex + offset >= order.count() )
82+
return;
83+
84+
int id = order.takeAt( legendNodeIndex );
85+
order.insert( legendNodeIndex + offset, id );
86+
87+
QgsMapLayerLegendUtils::setLegendNodeOrder( nodeLayer, order );
88+
}
89+
} //namespace
7290

7391
QgsLayoutLegendWidget::QgsLayoutLegendWidget( QgsLayoutItemLegend *legend, QgsMapCanvas *mapCanvas )
7492
: QgsLayoutItemBaseWidget( nullptr, legend )
@@ -726,22 +744,6 @@ void QgsLayoutLegendWidget::mColumnSpaceSpinBox_valueChanged( double d )
726744
}
727745
}
728746

729-
static void _moveLegendNode( QgsLayerTreeLayer *nodeLayer, int legendNodeIndex, int offset )
730-
{
731-
QList<int> order = QgsMapLayerLegendUtils::legendNodeOrder( nodeLayer );
732-
733-
if ( legendNodeIndex < 0 || legendNodeIndex >= order.count() )
734-
return;
735-
if ( legendNodeIndex + offset < 0 || legendNodeIndex + offset >= order.count() )
736-
return;
737-
738-
int id = order.takeAt( legendNodeIndex );
739-
order.insert( legendNodeIndex + offset, id );
740-
741-
QgsMapLayerLegendUtils::setLegendNodeOrder( nodeLayer, order );
742-
}
743-
744-
745747
void QgsLayoutLegendWidget::mMoveDownToolButton_clicked()
746748
{
747749
if ( !mLegend )
@@ -770,8 +772,14 @@ void QgsLayoutLegendWidget::mMoveDownToolButton_clicked()
770772
}
771773
else // legend node
772774
{
773-
_moveLegendNode( legendNode->layerNode(), _unfilteredLegendNodeIndex( legendNode ), 1 );
774-
mItemTreeView->layerTreeModel()->refreshLayerLegend( legendNode->layerNode() );
775+
// get the next index, the one that will have to be above our index,
776+
const QModelIndex nextIndex = index.siblingAtRow( index.row() + 1 );
777+
QgsLayerTreeModelLegendNode *nextLegendNode = nextIndex.isValid() ? mItemTreeView->index2legendNode( nextIndex ) : nullptr;
778+
if ( nextLegendNode )
779+
{
780+
_moveLegendNode( legendNode->layerNode(), _unfilteredLegendNodeIndex( legendNode ), _unfilteredLegendNodeIndex( nextLegendNode ) );
781+
mItemTreeView->layerTreeModel()->refreshLayerLegend( legendNode->layerNode() );
782+
}
775783
}
776784

777785
mItemTreeView->setCurrentIndex( mItemTreeView->proxyModel()->mapFromSource( mItemTreeView->layerTreeModel()->index( sourceIndex.row() + 1, 0, parentIndex ) ) );
@@ -808,8 +816,14 @@ void QgsLayoutLegendWidget::mMoveUpToolButton_clicked()
808816
}
809817
else // legend node
810818
{
811-
_moveLegendNode( legendNode->layerNode(), _unfilteredLegendNodeIndex( legendNode ), -1 );
812-
mItemTreeView->layerTreeModel()->refreshLayerLegend( legendNode->layerNode() );
819+
// get the previous index, the one that will have to be below our index,
820+
const QModelIndex prevIndex = index.siblingAtRow( index.row() - 1 );
821+
QgsLayerTreeModelLegendNode *prevLegendNode = prevIndex.isValid() ? mItemTreeView->index2legendNode( prevIndex ) : nullptr;
822+
if ( prevLegendNode )
823+
{
824+
_moveLegendNode( legendNode->layerNode(), _unfilteredLegendNodeIndex( legendNode ), _unfilteredLegendNodeIndex( prevLegendNode ) );
825+
mItemTreeView->layerTreeModel()->refreshLayerLegend( legendNode->layerNode() );
826+
}
813827
}
814828

815829
mItemTreeView->setCurrentIndex( mItemTreeView->proxyModel()->mapFromSource( mItemTreeView->layerTreeModel()->index( sourceIndex.row() - 1, 0, parentIndex ) ) );

0 commit comments

Comments
 (0)