diff --git a/python/core/layout/qgslayoutframe.sip b/python/core/layout/qgslayoutframe.sip
index 5a2de801d50..187f5b6a0d2 100644
--- a/python/core/layout/qgslayoutframe.sip
+++ b/python/core/layout/qgslayoutframe.sip
@@ -43,6 +43,9 @@ Creates a new QgsLayoutFrame belonging to the specified ``layout``.
virtual QString displayName() const;
+ virtual void cleanup();
+
+
void setContentSection( const QRectF §ion );
%Docstring
Sets the visible part of the multiframe's content which is visible within
diff --git a/python/core/layout/qgslayoutmultiframe.sip b/python/core/layout/qgslayoutmultiframe.sip
index 9c3ce3bebad..45683fb7b76 100644
--- a/python/core/layout/qgslayoutmultiframe.sip
+++ b/python/core/layout/qgslayoutmultiframe.sip
@@ -383,20 +383,6 @@ in finalizeRestoreFromXml(), not readPropertiesFromElement().
- protected slots:
-
- void handlePageChange();
-%Docstring
-Adapts to changed number of layout pages if resize type is RepeatOnEveryPage.
-%End
-
- void handleFrameRemoval();
-%Docstring
-Called when a frame is removed. Updates frame list and recalculates
-content of remaining frames.
-%End
-
-
};
diff --git a/src/core/layout/qgslayoutframe.cpp b/src/core/layout/qgslayoutframe.cpp
index f573fe9740a..f94c5d12a59 100644
--- a/src/core/layout/qgslayoutframe.cpp
+++ b/src/core/layout/qgslayoutframe.cpp
@@ -192,6 +192,14 @@ QString QgsLayoutFrame::displayName() const
return tr( "" );
}
+void QgsLayoutFrame::cleanup()
+{
+ if ( mMultiFrame )
+ mMultiFrame->handleFrameRemoval( this );
+
+ QgsLayoutItem::cleanup();
+}
+
void QgsLayoutFrame::draw( QgsRenderContext &context, const QStyleOptionGraphicsItem *itemStyle )
{
if ( mMultiFrame )
diff --git a/src/core/layout/qgslayoutframe.h b/src/core/layout/qgslayoutframe.h
index 69bb97334f6..2ba42a7a8aa 100644
--- a/src/core/layout/qgslayoutframe.h
+++ b/src/core/layout/qgslayoutframe.h
@@ -52,6 +52,8 @@ class CORE_EXPORT QgsLayoutFrame: public QgsLayoutItem
//Overridden to allow multiframe to set display name
QString displayName() const override;
+ void cleanup() override;
+
/**
* Sets the visible part of the multiframe's content which is visible within
* this frame (relative to the total multiframe extent in layout units).
diff --git a/src/core/layout/qgslayoutmultiframe.cpp b/src/core/layout/qgslayoutmultiframe.cpp
index df8f48e15b1..3f8a5647180 100644
--- a/src/core/layout/qgslayoutmultiframe.cpp
+++ b/src/core/layout/qgslayoutmultiframe.cpp
@@ -60,7 +60,10 @@ void QgsLayoutMultiFrame::addFrame( QgsLayoutFrame *frame, bool recalcFrameSizes
mFrameItems.push_back( frame );
frame->mMultiFrame = this;
connect( frame, &QgsLayoutItem::sizePositionChanged, this, &QgsLayoutMultiFrame::recalculateFrameSizes );
- connect( frame, &QgsLayoutFrame::destroyed, this, &QgsLayoutMultiFrame::handleFrameRemoval );
+ connect( frame, &QgsLayoutFrame::destroyed, this, [this, frame ]
+ {
+ handleFrameRemoval( frame );
+ } );
if ( mLayout )
{
mLayout->addLayoutItem( frame );
@@ -306,12 +309,11 @@ void QgsLayoutMultiFrame::refresh()
refreshDataDefinedProperty();
}
-void QgsLayoutMultiFrame::handleFrameRemoval()
+void QgsLayoutMultiFrame::handleFrameRemoval( QgsLayoutFrame *frame )
{
if ( mBlockUpdates )
return;
- QgsLayoutFrame *frame = qobject_cast( sender() );
if ( !frame )
{
return;
diff --git a/src/core/layout/qgslayoutmultiframe.h b/src/core/layout/qgslayoutmultiframe.h
index 8b6cef3b3de..390c8fbd34a 100644
--- a/src/core/layout/qgslayoutmultiframe.h
+++ b/src/core/layout/qgslayoutmultiframe.h
@@ -370,7 +370,7 @@ class CORE_EXPORT QgsLayoutMultiFrame: public QgsLayoutObject, public QgsLayoutU
ResizeMode mResizeMode = UseExistingFrames;
- protected slots:
+ private slots:
/**
* Adapts to changed number of layout pages if resize type is RepeatOnEveryPage.
@@ -381,7 +381,7 @@ class CORE_EXPORT QgsLayoutMultiFrame: public QgsLayoutObject, public QgsLayoutU
* Called when a frame is removed. Updates frame list and recalculates
* content of remaining frames.
*/
- void handleFrameRemoval();
+ void handleFrameRemoval( QgsLayoutFrame *frame );
private:
@@ -394,6 +394,7 @@ class CORE_EXPORT QgsLayoutMultiFrame: public QgsLayoutObject, public QgsLayoutU
//! Unique id
QString mUuid;
+ friend class QgsLayoutFrame;
};
diff --git a/tests/src/core/testqgslayoutmultiframe.cpp b/tests/src/core/testqgslayoutmultiframe.cpp
index ac279f69b56..c1678fce870 100644
--- a/tests/src/core/testqgslayoutmultiframe.cpp
+++ b/tests/src/core/testqgslayoutmultiframe.cpp
@@ -47,6 +47,7 @@ class TestQgsLayoutMultiFrame : public QObject
void undoRedoRemovedFrame(); //test that undo doesn't crash with removed frames
void undoRedoRemovedFrame2();
void registry();
+ void deleteFrame();
private:
QgsLayout *mLayout = nullptr;
@@ -556,5 +557,28 @@ void TestQgsLayoutMultiFrame::registry()
QVERIFY( props.isEmpty() );
}
+void TestQgsLayoutMultiFrame::deleteFrame()
+{
+ QgsLayout l( QgsProject::instance() );
+ l.initializeDefaults();
+
+ QgsLayoutItemHtml *htmlItem = new QgsLayoutItemHtml( &l );
+ QgsLayoutFrame *frame1 = new QgsLayoutFrame( &l, htmlItem );
+ frame1->attemptSetSceneRect( QRectF( 0, 0, 100, 200 ) );
+ htmlItem->addFrame( frame1 );
+ QgsLayoutFrame *frame2 = new QgsLayoutFrame( &l, htmlItem );
+ frame2->attemptSetSceneRect( QRectF( 0, 0, 100, 200 ) );
+ htmlItem->addFrame( frame2 );
+
+ QCOMPARE( htmlItem->frameCount(), 2 );
+ QCOMPARE( htmlItem->frames(), QList< QgsLayoutFrame * >() << frame1 << frame2 );
+ l.removeLayoutItem( frame1 );
+ QCOMPARE( htmlItem->frameCount(), 1 );
+ QCOMPARE( htmlItem->frames(), QList< QgsLayoutFrame * >() << frame2 );
+ l.removeLayoutItem( frame2 );
+ QCOMPARE( htmlItem->frameCount(), 0 );
+ QVERIFY( htmlItem->frames().empty() );
+}
+
QGSTEST_MAIN( TestQgsLayoutMultiFrame )
#include "testqgslayoutmultiframe.moc"