[Libreoffice-commits] core.git: Branch 'private/swe/libreoffice-5-2+backports' - sw/source
Armin Le Grand
Armin.Le.Grand at cib.de
Thu Dec 21 15:02:21 UTC 2017
sw/source/core/layout/pagechg.cxx | 113 ++++++++++++++++++++++++++++++++++----
1 file changed, 104 insertions(+), 9 deletions(-)
New commits:
commit d0f51d571c2e24c647eea7f68085531d251ce812
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date: Wed Dec 20 09:51:52 2017 +0100
Make used Pages alive in AssertFlyPages
There is a case where docs are created/exist that have an empty
2nd page with a single, page-anchored Frame (e.g. graphic), not
using a PageBreak. Persistence works in this case due to method
AssertFlyPages adding the missing page at end, but when multiple of
these docs get serialized (e.g. MailMerge) the problem exists for
in-between pages, too, and needs to be corrected. Also need to
correct the Pages for the Frames when Pages in that situation were
corrected.
Change-Id: I7c8bbbf0668438af98bc615e5b7c472ea6eee906
Reviewed-on: https://gerrit.libreoffice.org/46855
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Armin Le Grand <Armin.Le.Grand at cib.de>
Reviewed-on: https://gerrit.libreoffice.org/46891
Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
diff --git a/sw/source/core/layout/pagechg.cxx b/sw/source/core/layout/pagechg.cxx
index f081ad6c6f3a..aac2ab98461d 100644
--- a/sw/source/core/layout/pagechg.cxx
+++ b/sw/source/core/layout/pagechg.cxx
@@ -191,10 +191,11 @@ SwPageFrame::SwPageFrame( SwFrameFormat *pFormat, SwFrame* pSib, SwPageDesc *pPg
Frame().SSize( pFormat->GetFrameSize().GetSize() );
// create and insert body area if it is not a blank page
- SwDoc *pDoc = pFormat->GetDoc();
- if ( !(m_bEmptyPage = (pFormat == pDoc->GetEmptyPageFormat())) )
+ SwDoc* pDoc(pFormat->GetDoc());
+ m_bEmptyPage = (pFormat == pDoc->GetEmptyPageFormat());
+
+ if(!m_bEmptyPage)
{
- m_bEmptyPage = false;
Calc(pRenderContext); // so that the PrtArea is correct
SwBodyFrame *pBodyFrame = new SwBodyFrame( pDoc->GetDfltFrameFormat(), this );
pBodyFrame->ChgSize( Prt().SSize() );
@@ -544,6 +545,28 @@ void SwPageFrame::UpdateAttr_( const SfxPoolItem *pOld, const SfxPoolItem *pNew,
{
case RES_FMT_CHG:
{
+ // state of m_bEmptyPage needs to be determined newly
+ const bool bNewState(GetFormat() == GetFormat()->GetDoc()->GetEmptyPageFormat());
+
+ if(m_bEmptyPage != bNewState)
+ {
+ // copy new state
+ m_bEmptyPage = bNewState;
+
+ if(nullptr == GetLower())
+ {
+ // if we were an empty page before there is not yet a BodyArea in the
+ // form of a SwBodyFrame, see constructor
+ SwViewShell* pSh(getRootFrame()->GetCurrShell());
+ vcl::RenderContext* pRenderContext(pSh ? pSh->GetOut() : nullptr);
+ Calc(pRenderContext); // so that the PrtArea is correct
+ SwBodyFrame* pBodyFrame = new SwBodyFrame(GetFormat(), this);
+ pBodyFrame->ChgSize( Prt().SSize() );
+ pBodyFrame->Paste(this);
+ pBodyFrame->InvalidatePos();
+ }
+ }
+
// If the frame format is changed, several things might also change:
// 1. columns:
assert(pOld && pNew); //FMT_CHG Missing Format
@@ -1389,19 +1412,81 @@ void SwRootFrame::AssertFlyPages()
const SwFrameFormats *pTable = pDoc->GetSpzFrameFormats();
// what page targets the "last" Fly?
- sal_uInt16 nMaxPg = 0;
+ // note the needed pages in a set
+ sal_uInt16 nMaxPg(0);
+ std::set< sal_uInt16 > neededPages;
for ( size_t i = 0; i < pTable->size(); ++i )
{
const SwFormatAnchor &rAnch = (*pTable)[i]->GetAnchor();
- if ( !rAnch.GetContentAnchor() && nMaxPg < rAnch.GetPageNum() )
- nMaxPg = rAnch.GetPageNum();
+ if(!rAnch.GetContentAnchor())
+ {
+ const sal_uInt16 nPageNum(rAnch.GetPageNum());
+
+ // calc MaxPage (as before)
+ nMaxPg = std::max(nMaxPg, nPageNum);
+
+ // note as needed page
+ neededPages.insert(nPageNum);
+ }
}
+
// How many pages exist at the moment?
- SwPageFrame *pPage = static_cast<SwPageFrame*>(Lower());
- while ( pPage && pPage->GetNext() &&
- !static_cast<SwPageFrame*>(pPage->GetNext())->IsFootnotePage() )
+ // And are there EmptyPages that are needed?
+ SwPageFrame* pPage(static_cast<SwPageFrame*>(Lower()));
+ SwPageFrame* pPrevPage(nullptr);
+ SwPageFrame* pFirstRevivedEmptyPage(nullptr);
+
+ while(pPage) // moved two while-conditions to break-statements (see below)
{
+ const sal_uInt16 nPageNum(pPage->GetPhyPageNum());
+
+ if(pPage->IsEmptyPage() &&
+ nullptr != pPrevPage &&
+ neededPages.find(nPageNum) != neededPages.end())
+ {
+ // This is an empty page, but it *is* needed since a SwFrame
+ // is anchored at it directly. Initially these SwFrames are
+ // not fully initialized. Need to change the format of this SwFrame
+ // and let the ::Notify mechanism newly evaluate
+ // m_bEmptyPage (see SwPageFrame::UpdateAttr_). Code is taken and
+ // adapted from ::InsertPage (used below), this needs previous page
+ bool bWishedOdd(!pPrevPage->OnRightPage());
+ SwPageDesc* pDesc(pPrevPage->GetPageDesc()->GetFollow());
+ assert(pDesc && "Missing PageDesc");
+
+ if(!(bWishedOdd ? pDesc->GetRightFormat() : pDesc->GetLeftFormat()))
+ {
+ bWishedOdd = !bWishedOdd;
+ }
+
+ bool const bWishedFirst(pDesc != pPrevPage->GetPageDesc());
+ SwFrameFormat* pFormat(bWishedOdd ? pDesc->GetRightFormat(bWishedFirst) : pDesc->GetLeftFormat(bWishedFirst));
+
+ // set SwFrameFormat, this will trigger SwPageFrame::UpdateAttr_ and re-evaluate
+ // m_bEmptyPage, too
+ pPage->SetFrameFormat(pFormat);
+
+ if(nullptr == pFirstRevivedEmptyPage)
+ {
+ // remember first (lowest) SwPageFrame which needed correction
+ pFirstRevivedEmptyPage = pPage;
+ }
+ }
+
+ // original while-condition II
+ if(nullptr == pPage->GetNext())
+ {
+ break;
+ }
+
+ // original while-condition III
+ if(static_cast< SwPageFrame* >(pPage->GetNext())->IsFootnotePage())
+ {
+ break;
+ }
+
+ pPrevPage = pPage;
pPage = static_cast<SwPageFrame*>(pPage->GetNext());
}
@@ -1447,6 +1532,16 @@ void SwRootFrame::AssertFlyPages()
}
}
}
+
+ // if we corrected SwFrameFormat and changed one (or more) m_bEmptyPage
+ // flags, we need to correct evtl. currently wrong positioned SwFrame(s)
+ // which did think until now that these Page(s) are empty.
+ // After trying to correct myself I found SwRootFrame::AssertPageFlys
+ // directly below that already does that, so use it.
+ if(nullptr != pFirstRevivedEmptyPage)
+ {
+ AssertPageFlys(pFirstRevivedEmptyPage);
+ }
}
/// Ensure that after the given page all page-bound objects are located on the correct page
More information about the Libreoffice-commits
mailing list