Git commit 800591e0f80f05aa7043e16874e1380f54f1189f by Sebastian Sauer. Committed on 30/04/2011 at 22:10. Pushed by sebsauer into branch 'master'. Invalidate the root-areas if a KWFrame goes out of scope. M +7 -0 libs/textlayout/KoTextDocumentLayout.cpp M +6 -0 libs/textlayout/KoTextDocumentLayout.h M +1 -1 words/part/KWDocument.cpp M +6 -2 words/part/KWRootAreaProvider.cpp M +29 -2 words/part/frames/KWFrame.cpp M +2 -0 words/part/frames/KWFrame.h M +4 -3 words/part/frames/KWFrameLayout.cpp http://commits.kde.org/calligra/800591e0f80f05aa7043e16874e1380f54f1189f diff --git a/libs/textlayout/KoTextDocumentLayout.cpp b/libs/textlayout/KoTextDocumentLayout.cpp index 4d3bb8e..65a8ac6 100644 --- a/libs/textlayout/KoTextDocumentLayout.cpp +++ b/libs/textlayout/KoTextDocumentLayout.cpp @@ -588,6 +588,13 @@ QList KoTextDocumentLayout::rootAreas() const return d->rootAreaList; } +void KoTextDocumentLayout::removeRootArea(KoTextLayoutRootArea *rootArea) +{ + int indexOf = rootArea ? qMax(0, d->rootAreaList.indexOf(rootArea)) : 0; + for(int i = d->rootAreaList.count() - 1; i >= indexOf; --i) + d->rootAreaList.removeAt(i); +} + QList KoTextDocumentLayout::shapes() const { QList listOfShapes; diff --git a/libs/textlayout/KoTextDocumentLayout.h b/libs/textlayout/KoTextDocumentLayout.h index 146dd10..1b923c7 100644 --- a/libs/textlayout/KoTextDocumentLayout.h +++ b/libs/textlayout/KoTextDocumentLayout.h @@ -153,6 +153,12 @@ public: */ KoTextLayoutRootArea *rootAreaForPosition(int position) const; + /** + * Remove the root-areas \p rootArea from the list of \a rootAreas() . + * \param rootArea root-area to remove. If NULL then all root-areas are removed. + */ + void removeRootArea(KoTextLayoutRootArea *rootArea = 0); + /// reimplemented from QAbstractTextDocumentLayout virtual void documentChanged(int position, int charsRemoved, int charsAdded); diff --git a/words/part/KWDocument.cpp b/words/part/KWDocument.cpp index 44c9cd3..94af1a3 100644 --- a/words/part/KWDocument.cpp +++ b/words/part/KWDocument.cpp @@ -399,7 +399,7 @@ void KWDocument::relayout() KoToolManager::instance()->switchToolRequested(KoInteractionTool_ID); // remove header/footer frames that are not visible. - m_frameLayout.cleanupHeadersFooters(); + //m_frameLayout.cleanupHeadersFooters(); // re-layout the pages foreach (const KWPage &page, m_pageManager.pages()) { diff --git a/words/part/KWRootAreaProvider.cpp b/words/part/KWRootAreaProvider.cpp index 56e13b2..b80373c 100755 --- a/words/part/KWRootAreaProvider.cpp +++ b/words/part/KWRootAreaProvider.cpp @@ -45,8 +45,12 @@ class KWTextLayoutRootArea : public KoTextLayoutRootArea { public: - KWTextLayoutRootArea(KoTextDocumentLayout *documentLayout, KWTextFrameSet *frameSet, const KWPage &page) : KoTextLayoutRootArea(documentLayout), m_frameSet(frameSet), m_page(page) {} - virtual ~KWTextLayoutRootArea() {} + KWTextLayoutRootArea(KoTextDocumentLayout *documentLayout, KWTextFrameSet *frameSet, const KWPage &page) : KoTextLayoutRootArea(documentLayout), m_frameSet(frameSet), m_page(page) { + kDebug(); + } + virtual ~KWTextLayoutRootArea() { + kDebug(); + } virtual bool layout(FrameIterator *cursor) { kDebug(32001) << "pageNumber=" << m_page.pageNumber() << "frameSetType=" << KWord::frameSetTypeName(m_frameSet->textFrameSetType()) << "isDirty=" << isDirty(); return KoTextLayoutRootArea::layout(cursor); diff --git a/words/part/frames/KWFrame.cpp b/words/part/frames/KWFrame.cpp index d2a201e..327a6b4 100644 --- a/words/part/frames/KWFrame.cpp +++ b/words/part/frames/KWFrame.cpp @@ -27,7 +27,10 @@ #include "KWOutlineShape.h" #include "KoTextAnchor.h" #include "KWPage.h" +#include "KWRootAreaProvider.h" #include +#include +#include #include #include @@ -66,11 +69,13 @@ KWFrame::~KWFrame() KoShape *ourShape = m_shape; m_shape = 0; // no delete is needed as the shape deletes us. + if (m_frameSet) { bool justMe = m_frameSet->frameCount() == 1; m_frameSet->removeFrame(this, ourShape); // first remove me so we won't get double // deleted. ourShape is needed to mark any // copyShapes as retired + cleanupShape(ourShape); if (justMe) { kDebug(32001) << "Last KWFrame removed from frameSet=" << m_frameSet; delete m_frameSet; @@ -88,14 +93,36 @@ void KWFrame::setMinimumFrameHeight(qreal minimumFrameHeight) { m_minimumFrameHeight = minimumFrameHeight; } - + +void KWFrame::cleanupShape(KoShape* shape) +{ + KWTextFrameSet *tfs = dynamic_cast(m_frameSet); + if (tfs) { + KWRootAreaProvider *rootAreaProvider = tfs->rootAreaProvider(); + KoTextDocumentLayout *lay = dynamic_cast(tfs->document()->documentLayout()); + Q_ASSERT(lay); + QList layoutRootAreas = lay->rootAreas(); + for(int i = 0; i < layoutRootAreas.count(); ++i) { + KoTextLayoutRootArea *rootArea = layoutRootAreas[i]; + if (rootArea->associatedShape() == shape) { + rootAreaProvider->releaseAllAfter(rootArea); + lay->removeRootArea(rootArea); + rootArea->setAssociatedShape(0); + } + } + } +} + void KWFrame::setFrameSet(KWFrameSet *fs) { if (fs == m_frameSet) return; Q_ASSERT_X(!fs || !m_frameSet, __FUNCTION__, "Changing the FrameSet afterwards needs to invalidate lots of stuff including whatever is done in the KWRootAreaProvider. The better way would be to not allow this."); - if (m_frameSet) + if (m_frameSet) { m_frameSet->removeFrame(this); + if (m_shape) + cleanupShape(m_shape); + } m_frameSet = fs; if (fs) fs->addFrame(this); diff --git a/words/part/frames/KWFrame.h b/words/part/frames/KWFrame.h index 1e6ba29..8c626b4 100644 --- a/words/part/frames/KWFrame.h +++ b/words/part/frames/KWFrame.h @@ -158,6 +158,8 @@ private: KWFrameSet *m_frameSet; qreal m_minimumFrameHeight; + + void cleanupShape(KoShape* shape); }; #endif diff --git a/words/part/frames/KWFrameLayout.cpp b/words/part/frames/KWFrameLayout.cpp index 221118a..019ca1c 100644 --- a/words/part/frames/KWFrameLayout.cpp +++ b/words/part/frames/KWFrameLayout.cpp @@ -112,7 +112,6 @@ else kDebug(32001) << "Nooooo FooterTextFrame"; delete background->shape(); } -#if 1 // delete headers/footer frames that are not needed on this page foreach (KWFrame *frame, framesInPage(page.rect())) { if (frame->frameSet()->type() != KWord::TextFrameSet) @@ -126,10 +125,8 @@ else kDebug(32001) << "Nooooo FooterTextFrame"; kDebug(32001)<<"Delete disabled header/footer frame=" << frame << "pageRect=" << page.rect() << "pageNumber=" << p.pageNumber(); tfs->removeFrame(frame); delete frame->shape(); -Q_ASSERT(false); } } -#endif // create main text frame. All columns of them. if (page.pageStyle().hasMainTextFrame()) { @@ -676,6 +673,7 @@ KWFrame *KWFrameLayout::frameOn(KWFrameSet *fs, int pageNumber) const void KWFrameLayout::cleanupHeadersFooters() { kDebug(32001); +#if 0 QHash pageStyles; foreach (KWFrameSet *fs, m_frameSets) { KWTextFrameSet *tfs = dynamic_cast(fs); @@ -746,6 +744,9 @@ kDebug()<<"remove evenFooters frameSets"; break; } } +#else + Q_ASSERT(false); +#endif m_setup = false; }