external/boost/UnpackedTarball_boost.mk                     |    4 
 external/boost/boost.tuple_basic.Wundef.warnings.patch      |   34 +
 include/sal/log-areas.dox                                   |    1 
 sw/inc/IDocumentContentOperations.hxx                       |    2 
 sw/inc/doc.hxx                                              |    6 
 sw/inc/docary.hxx                                           |  112 +++++
 sw/inc/format.hxx                                           |    4 
 sw/inc/frmfmt.hxx                                           |   20 +
 sw/inc/pagedesc.hxx                                         |   94 ++++
 sw/inc/textboxhelper.hxx                                    |   36 +
 sw/qa/extras/mailmerge/data/sections_first_last.odt         |binary
 sw/qa/extras/mailmerge/mailmerge.cxx                        |   38 +
 sw/qa/extras/uiwriter/uiwriter.cxx                          |   19 
 sw/source/core/doc/DocumentLayoutManager.cxx                |    6 
 sw/source/core/doc/docdesc.cxx                              |   63 +--
 sw/source/core/doc/docedt.cxx                               |    2 
 sw/source/core/doc/docfly.cxx                               |   18 
 sw/source/core/doc/docfmt.cxx                               |  139 ++++++-
 sw/source/core/doc/doclay.cxx                               |    8 
 sw/source/core/doc/docnew.cxx                               |   70 ++-
 sw/source/core/doc/textboxhelper.cxx                        |  189 +++------
 sw/source/core/docnode/nodes.cxx                            |   39 +
 sw/source/core/draw/dcontact.cxx                            |    2 
 sw/source/core/draw/dview.cxx                               |    2 
 sw/source/core/frmedt/fecopy.cxx                            |   15 
 sw/source/core/frmedt/feshview.cxx                          |    8 
 sw/source/core/inc/rootfrm.hxx                              |    8 
 sw/source/core/layout/atrfrm.cxx                            |   57 ++
 sw/source/core/layout/flowfrm.cxx                           |   13 
 sw/source/core/layout/fly.cxx                               |    5 
 sw/source/core/layout/frmtool.cxx                           |    2 
 sw/source/core/layout/layact.cxx                            |    5 
 sw/source/core/layout/pagechg.cxx                           |  235 +++++++-----
 sw/source/core/layout/pagedesc.cxx                          |   75 +++
 sw/source/core/objectpositioning/anchoredobjectposition.cxx |    2 
 sw/source/core/text/porfly.cxx                              |    2 
 sw/source/core/undo/unattr.cxx                              |    8 
 sw/source/core/undo/undobj1.cxx                             |    2 
 sw/source/core/undo/untbl.cxx                               |    2 
 sw/source/core/unocore/unocoll.cxx                          |    4 
 sw/source/core/unocore/unodraw.cxx                          |   36 -
 sw/source/core/unocore/unoframe.cxx                         |    3 
 sw/source/core/unocore/unoobj2.cxx                          |    7 
 sw/source/core/unocore/unoportenum.cxx                      |    9 
 sw/source/filter/basflt/shellio.cxx                         |    2 
 sw/source/filter/ww8/docxattributeoutput.cxx                |    4 
 sw/source/filter/ww8/docxsdrexport.cxx                      |    4 
 sw/source/filter/ww8/rtfsdrexport.cxx                       |    7 
 sw/source/filter/ww8/rtfsdrexport.hxx                       |    3 
 sw/source/filter/ww8/wrtw8esh.cxx                           |    3 
 sw/source/filter/xml/xmltble.cxx                            |    3 
 sw/source/uibase/dbui/dbmgr.cxx                             |    7 
 sw/source/uibase/docvw/edtwin.cxx                           |   11 
 sw/source/uibase/shells/drawsh.cxx                          |    4 
 sw/source/uibase/uiview/viewdraw.cxx                        |    2 
 55 files changed, 999 insertions(+), 457 deletions(-)

New commits:
commit 412f514365ce6646f6221768ed2c46206dd0c91f
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Thu Aug 11 18:45:21 2016 +0200

    MM don't keep undo information
    
    Doen't make much sense to store undo information for all merge
    based progress. Actually it even prevents crahes when undoing a
    merged ODT document.
    
    Change-Id: Ic3a3982f3e5eb4f6de9f027a6a5e376c2833e8a5

diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index d70b4b9..9642b26 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -78,6 +78,7 @@
 #include <IDocumentLinksAdministration.hxx>
 #include <IDocumentContentOperations.hxx>
 #include <IDocumentFieldsAccess.hxx>
+#include <IDocumentUndoRedo.hxx>
 #include <swwait.hxx>
 #include <swunohelper.hxx>
 #include <dbui.hrc>
@@ -990,6 +991,7 @@ static SfxObjectShell* lcl_CreateWorkingDocument(
     pWorkWrtShell->GetViewOptions()->SetIdle( false );
     pWorkView->AttrChangedNotify( pWorkWrtShell );// in order for SelectShell 
to be called
     SwDoc* pWorkDoc = pWorkWrtShell->GetDoc();
+    pWorkDoc->GetIDocumentUndoRedo().DoUndo( false );
     pWorkDoc->ReplaceDocumentProperties( *pSourceDoc );
 
     if( aType == WorkingDocType::TARGET )
@@ -1530,6 +1532,7 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
         pTargetShell->CalcLayout();
         SAL_INFO( "sw.pageframe", "MergeMailFiles pTargetShell->CalcLayout 
out)" );
         pTargetShell->GetViewOptions()->SetIdle( true );
+        pTargetDoc->GetIDocumentUndoRedo().DoUndo( true );
         for ( auto aLayout : pTargetShell->GetDoc()->GetAllLayouts() )
         {
             aLayout->FreezeLayout(false);
commit d943d4faf92f0b86c25f3cd6fe77ed8a7d4905d1
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Thu Aug 11 18:39:20 2016 +0200

    Fix SwDoc::AppendDoc for trailing sections
    
    We already treat the StartOfContent node special in the CopyRange
    function to prevent merging of SwTextNodes.
    
    For trailing sections, we have to expand the code to treat
    EndOfContent special too, because the supplied SwPaM range is
    handled as [mark, point[, so it previously missed the section end
    node, which resulted in "unhiding" the last section, if it was the
    last node in the document.
    
    Change-Id: Ie094e2a0182647a49c9ba45d08a7dd2cabe667c6

diff --git a/sw/inc/IDocumentContentOperations.hxx 
b/sw/inc/IDocumentContentOperations.hxx
index 75b4f84..1572e21 100644
--- a/sw/inc/IDocumentContentOperations.hxx
+++ b/sw/inc/IDocumentContentOperations.hxx
@@ -80,7 +80,7 @@ public:
         be within the range!
 
         \warning The range has to include at least two nodes or has to be a
-        SwDoc::IsColumnSelection!
+        SwDoc::IsColumnSelection, because the rPam is treated [mark, point[.
 
         Normally this function should work only with content nodes. But there
         is a special case used by SwDoc::Paste, which starts the SwPaM at the
diff --git a/sw/qa/extras/mailmerge/data/sections_first_last.odt 
b/sw/qa/extras/mailmerge/data/sections_first_last.odt
new file mode 100644
index 0000000..5a92adb
Binary files /dev/null and 
b/sw/qa/extras/mailmerge/data/sections_first_last.odt differ
diff --git a/sw/qa/extras/mailmerge/mailmerge.cxx 
b/sw/qa/extras/mailmerge/mailmerge.cxx
index 4b2e8ef..84331cc8 100644
--- a/sw/qa/extras/mailmerge/mailmerge.cxx
+++ b/sw/qa/extras/mailmerge/mailmerge.cxx
@@ -32,6 +32,7 @@
 #include <edtwin.hxx>
 #include <olmenu.hxx>
 #include <cmdid.h>
+#include <pagefrm.hxx>
 
 /**
  * Maps database URIs to the registered database names for quick lookups
@@ -531,5 +532,42 @@ DECLARE_SHELL_MAILMERGE_TEST_SELECTION(testTdf95292, 
"linked-labels.odt", "10-te
     CPPUNIT_ASSERT_EQUAL( sal_uInt16( 5 ), pWrtShell->GetPhyPageNum() );
 }
 
+DECLARE_SHELL_MAILMERGE_TEST(test_sections_first_last, 
"sections_first_last.odt", "10-testing-addresses.ods", "testing-addresses")
+{
+    // A document with a leading, middle and trailing section
+    // Originally we were losing the trailing section during merge
+    executeMailMerge();
+
+    SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument 
*>(mxComponent.get());
+    CPPUNIT_ASSERT(pTextDoc);
+
+    // Get the size of the document in nodes
+    SwDoc *pDoc = pTextDoc->GetDocShell()->GetDoc();
+    sal_uLong nSize = pDoc->GetNodes().GetEndOfContent().GetIndex() - 
pDoc->GetNodes().GetEndOfExtras().GetIndex();
+    nSize -= 2; // The common start and end node
+    CPPUNIT_ASSERT_EQUAL( sal_uLong(13), nSize );
+
+    SwXTextDocument* pTextDocMM = dynamic_cast<SwXTextDocument 
*>(mxMMComponent.get());
+    CPPUNIT_ASSERT(pTextDocMM);
+
+    SwDoc *pDocMM = pTextDocMM->GetDocShell()->GetDoc();
+    sal_uLong nSizeMM = pDocMM->GetNodes().GetEndOfContent().GetIndex() - 
pDocMM->GetNodes().GetEndOfExtras().GetIndex();
+    nSizeMM -= 2;
+    CPPUNIT_ASSERT_EQUAL( sal_uLong(10 * nSize), nSizeMM );
+
+    CPPUNIT_ASSERT_EQUAL( sal_uInt16(19), 
pDocMM->GetDocShell()->GetWrtShell()->GetPhyPageNum() );
+
+    // All even pages should be empty, all sub-documents have two pages
+    const SwRootFrame* pLayout = 
pDocMM->getIDocumentLayoutAccess().GetCurrentLayout();
+    const SwPageFrame* pPageFrm = static_cast<const SwPageFrame*>( 
pLayout->Lower() );
+    while ( pPageFrm )
+    {
+        bool bOdd = (1 == (pPageFrm->GetPhyPageNum() % 2));
+        CPPUNIT_ASSERT_EQUAL( !bOdd, pPageFrm->IsEmptyPage() );
+        CPPUNIT_ASSERT_EQUAL( sal_uInt16( bOdd ? 1 : 2 ), 
pPageFrm->GetVirtPageNum() );
+        pPageFrm = static_cast<const SwPageFrame*>( pPageFrm->GetNext() );
+    }
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index 8079e8f..aeaf702 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -964,20 +964,13 @@ SwNodeIndex SwDoc::AppendDoc(const SwDoc& rSource, 
sal_uInt16 const nStartPageNu
     SAL_INFO( "sw.pagefrm", "(SwDoc::AppendDoc in " << bDeletePrevious );
 
     // GetEndOfExtras + 1 = StartOfContent == no content node!
-    // this ensures, that we have at least two nodes in the SwPaM.
-    // @see IDocumentContentOperations::CopyRange
+    // This ensures it won't be merged in the SwTextNode at the position.
     SwNodeIndex aSourceIdx( rSource.GetNodes().GetEndOfExtras(), 1 );
-    SwNodeIndex aSourceEndIdx( rSource.GetNodes().GetEndOfContent(), -1 );
-    SwPaM aCpyPam( aSourceIdx );
-
-    if ( aSourceEndIdx.GetNode().IsTextNode() ) {
-        aCpyPam.SetMark();
-        // moves to the last content node before EOC; for single paragraph
-        // documents this would result in [n, n], which is considered empty
-        aCpyPam.Move( fnMoveForward, fnGoDoc );
-    }
-    else
-        aCpyPam = SwPaM( aSourceIdx, aSourceEndIdx );
+    // CopyRange works on the range a [mark, point[ and considers an
+    // index < point outside the selection.
+    // @see IDocumentContentOperations::CopyRange
+    SwNodeIndex aSourceEndIdx( rSource.GetNodes().GetEndOfContent(), 0 );
+    SwPaM aCpyPam( aSourceIdx, aSourceEndIdx );
 
 #ifdef DBG_UTIL
     SAL_INFO( "sw.docappend", "NodeType 0x" << std::hex << (int) 
aSourceIdx.GetNode().GetNodeType()
@@ -994,10 +987,8 @@ SwNodeIndex SwDoc::AppendDoc(const SwDoc& rSource, 
sal_uInt16 const nStartPageNu
     SAL_INFO( "sw.docappend", ".." );
     SAL_INFO( "sw.docappend", "NodeType 0x" << std::hex << (int) 
aSourceEndIdx.GetNode().GetNodeType()
                               << std::dec << " " << 
aSourceEndIdx.GetNode().GetIndex() );
-    aSourceEndIdx++;
     SAL_INFO( "sw.docappend", "NodeType 0x" << std::hex << (int) 
aSourceEndIdx.GetNode().GetNodeType()
                               << std::dec << " " << 
aSourceEndIdx.GetNode().GetIndex() );
-    aSourceEndIdx--;
     SAL_INFO( "sw.docappend", "Src-Nd: " << CNTNT_DOC( &rSource ) );
     SAL_INFO( "sw.docappend", "Nd: " << CNTNT_DOC( this ) );
 #endif
@@ -1041,9 +1032,23 @@ SwNodeIndex SwDoc::AppendDoc(const SwDoc& rSource, 
sal_uInt16 const nStartPageNu
         }
 
         // Otherwise we have to handle SwPlaceholderNodes as first node
-        if ( pTargetPageDesc ) {
+        if ( pTargetPageDesc )
+        {
+            SwNodeIndex aBreakIdx( GetNodes().GetEndOfContent(), -1 );
+            SwPosition aBreakPos( aBreakIdx );
+            // InsertPageBreak just works on SwTextNode nodes, so make
+            // sure the last node is one!
+            bool bIsTextNode = aBreakIdx.GetNode().IsTextNode();
+            if ( !bIsTextNode )
+                getIDocumentContentOperations().AppendTextNode( aBreakPos );
             OUString name = pTargetPageDesc->GetName();
             pTargetShell->InsertPageBreak( &name, nStartPageNumber );
+            if ( !bIsTextNode )
+            {
+                pTargetShell->SttEndDoc( false );
+                --aBreakIdx;
+                GetNodes().Delete( aBreakIdx, 1 );
+            }
 
             // There is now a new empty text node on the new page. If it has
             // any marks, those are from the previous page: move them back
@@ -1103,7 +1108,8 @@ SwNodeIndex SwDoc::AppendDoc(const SwDoc& rSource, 
sal_uInt16 const nStartPageNu
     this->GetIDocumentUndoRedo().StartUndo( UNDO_INSGLOSSARY, nullptr );
     this->getIDocumentFieldsAccess().LockExpFields();
 
-    // Position where the appended doc starts. Will be filled in later (uses 
GetEndOfContent() because SwNodeIndex has no default ctor).
+    // Position where the appended doc starts. Will be filled in later.
+    // Initially uses GetEndOfContent() because SwNodeIndex has no default 
ctor.
     SwNodeIndex aStartAppendIndex( GetNodes().GetEndOfContent() );
 
     {
diff --git a/sw/source/core/docnode/nodes.cxx b/sw/source/core/docnode/nodes.cxx
index 7927af3..4b04d07 100644
--- a/sw/source/core/docnode/nodes.cxx
+++ b/sw/source/core/docnode/nodes.cxx
@@ -1695,24 +1695,30 @@ void SwNodes::CopyNodes( const SwNodeRange& rRange,
                 !pAktNode->m_pStartOfSection->IsSectionNode() ) )
         ++aRg.aStart;
 
-    // if aEnd-1 points to no ContentNode, search previous one
-    --aRg.aEnd;
-    // #i107142#: if aEnd is start node of a special section, do nothing.
-    // Otherwise this could lead to crash: going through all previous
-    // special section nodes and then one before the first.
-    if (aRg.aEnd.GetNode().StartOfSectionIndex() != 0)
+    const SwNode *aEndNode = &aRg.aEnd.GetNode();
+    int nIsEndOfContent = (aEndNode == 
&aEndNode->GetNodes().GetEndOfContent()) ? 1 : 0;
+
+    if (0 == nIsEndOfContent)
     {
-        while( ((pAktNode = & aRg.aEnd.GetNode())->GetStartNode() &&
-                !pAktNode->IsSectionNode() ) ||
-                ( pAktNode->IsEndNode() &&
-                ND_STARTNODE == pAktNode->m_pStartOfSection->GetNodeType()) )
+        // if aEnd-1 points to no ContentNode, search previous one
+        --aRg.aEnd;
+        // #i107142#: if aEnd is start node of a special section, do nothing.
+        // Otherwise this could lead to crash: going through all previous
+        // special section nodes and then one before the first.
+        if (aRg.aEnd.GetNode().StartOfSectionIndex() != 0)
         {
-            --aRg.aEnd;
+            while( ((pAktNode = & aRg.aEnd.GetNode())->GetStartNode() &&
+                    !pAktNode->IsSectionNode() ) ||
+                    ( pAktNode->IsEndNode() &&
+                    ND_STARTNODE == 
pAktNode->m_pStartOfSection->GetNodeType()) )
+            {
+                --aRg.aEnd;
+            }
         }
+        ++aRg.aEnd;
     }
-    ++aRg.aEnd;
 
-    // if in same array, check insertion position
+    // is there anything left to copy?
     if( aRg.aStart >= aRg.aEnd )
         return;
 
@@ -1787,7 +1793,7 @@ void SwNodes::CopyNodes( const SwNodeRange& rRange,
                 if (nDistance < nNodeCnt)
                     nNodeCnt -= nDistance;
                 else
-                    nNodeCnt = 1;
+                    nNodeCnt = 1 - nIsEndOfContent;
 
                 aRg.aStart = pAktNode->EndOfSectionIndex();
 
@@ -1815,7 +1821,7 @@ void SwNodes::CopyNodes( const SwNodeRange& rRange,
                 if (nDistance < nNodeCnt)
                     nNodeCnt -= nDistance;
                 else
-                    nNodeCnt = 1;
+                    nNodeCnt = 1 - nIsEndOfContent;
                 aRg.aStart = pAktNode->EndOfSectionIndex();
 
                 if( bNewFrames && pSectNd &&
@@ -1840,6 +1846,9 @@ void SwNodes::CopyNodes( const SwNodeRange& rRange,
                 --nLevel;
                 ++aInsPos; // EndNode already exists
             }
+            else if( 1 == nNodeCnt && 1 == nIsEndOfContent )
+                // we have reached the EndOfContent node - nothing to do!
+                continue;
             else if( !pAktNode->m_pStartOfSection->IsSectionNode() )
             {
                 // create a section at the original InsertPosition
commit 345b7023b80587e1a022ff7d2ce16e8afb23d9c5
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Wed Aug 10 12:42:29 2016 +0200

    MM block idle-handling of generated documents
    
    We don't need any background idle jobs for the generated documents,
    like spell checking, statistics etc.
    
    This can be done when (or even if) the document is presented to the
    user as a background task.
    
    Change-Id: I4c72ed6e0d2f90d43e7f04cd0ea4418cbffe1206

diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index 51cedc2..d70b4b9 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -987,6 +987,7 @@ static SfxObjectShell* lcl_CreateWorkingDocument(
 
     SwView* pWorkView = static_cast< SwView* >( pWorkFrame->GetViewShell() );
     SwWrtShell* pWorkWrtShell = pWorkView->GetWrtShellPtr();
+    pWorkWrtShell->GetViewOptions()->SetIdle( false );
     pWorkView->AttrChangedNotify( pWorkWrtShell );// in order for SelectShell 
to be called
     SwDoc* pWorkDoc = pWorkWrtShell->GetDoc();
     pWorkDoc->ReplaceDocumentProperties( *pSourceDoc );
@@ -1528,6 +1529,7 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
         SAL_INFO( "sw.pageframe", "(MergeMailFiles pTargetShell->CalcLayout 
in" );
         pTargetShell->CalcLayout();
         SAL_INFO( "sw.pageframe", "MergeMailFiles pTargetShell->CalcLayout 
out)" );
+        pTargetShell->GetViewOptions()->SetIdle( true );
         for ( auto aLayout : pTargetShell->GetDoc()->GetAllLayouts() )
         {
             aLayout->FreezeLayout(false);
commit 9031b1aeac7cc9e7eb1ab250a9b523240efae4f6
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Wed Aug 10 11:37:15 2016 +0200

    Add SAL_INFOs to dump the SwPageFrame lifecycle
    
    Debug area name is "sw.pageframe".
    
    Change-Id: I136cc8192137a8c682900a6ce2c557f6b6b3a6cd

diff --git a/include/sal/log-areas.dox b/include/sal/log-areas.dox
index ac824a8..29f5227 100644
--- a/include/sal/log-areas.dox
+++ b/include/sal/log-areas.dox
@@ -471,6 +471,7 @@ certain functionality.
 @li @c sw.idle
 @li @c sw.level2
 @li @c sw.mailmerge - Writer mail merge
+@li @c sw.pageframe - debug lifecycle of SwPageFrame
 @li @c sw.rtf - .rtf export filter
 @li @c sw.tiled
 @li @c sw.ui
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index 07ac968..8079e8f 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -878,6 +878,7 @@ void SwDoc::ReplaceCompatibilityOptions(const SwDoc& 
rSource)
 
 SfxObjectShell* SwDoc::CreateCopy( bool bCallInitNew, bool bEmpty ) const
 {
+    SAL_INFO( "sw.pagefrm", "(SwDoc::CreateCopy in" );
     SwDoc* pRet = new SwDoc;
 
     // we have to use pointer here, since the callee has to decide whether
@@ -916,6 +917,7 @@ SfxObjectShell* SwDoc::CreateCopy( bool bCallInitNew, bool 
bEmpty ) const
 
     (void)pRet->release();
 
+    SAL_INFO( "sw.pagefrm", "SwDoc::CreateCopy out)" );
     return pRetShell;
 }
 
@@ -959,6 +961,8 @@ static void lcl_CopyFollowPageDesc(
 SwNodeIndex SwDoc::AppendDoc(const SwDoc& rSource, sal_uInt16 const 
nStartPageNumber,
                              bool const bDeletePrevious, int pageOffset, const 
sal_uLong nDocNo)
 {
+    SAL_INFO( "sw.pagefrm", "(SwDoc::AppendDoc in " << bDeletePrevious );
+
     // GetEndOfExtras + 1 = StartOfContent == no content node!
     // this ensures, that we have at least two nodes in the SwPaM.
     // @see IDocumentContentOperations::CopyRange
@@ -1070,7 +1074,9 @@ SwNodeIndex SwDoc::AppendDoc(const SwDoc& rSource, 
sal_uInt16 const nStartPageNu
             // Flush the page break, if we want to keep it
             if ( !bDeletePrevious )
             {
+                SAL_INFO( "sw.pagefrm", "(Flush pagebreak AKA EndAllAction" );
                 pTargetShell->EndAllAction();
+                SAL_INFO( "sw.pagefrm",  "Flush changes AKA EndAllAction)" );
                 pTargetShell->StartAllAction();
             }
         }
@@ -1246,6 +1252,7 @@ else
     if ( pTargetShell )
         pTargetShell->EndAllAction();
 
+    SAL_INFO( "sw.pagefrm", "SwDoc::AppendDoc out)" );
     return aStartAppendIndex;
 }
 
diff --git a/sw/source/core/layout/flowfrm.cxx 
b/sw/source/core/layout/flowfrm.cxx
index a28f36a..3b3cfcd 100644
--- a/sw/source/core/layout/flowfrm.cxx
+++ b/sw/source/core/layout/flowfrm.cxx
@@ -856,6 +856,13 @@ bool SwFrame::WrongPageDesc( SwPageFrame* pNew )
     const SwPageDesc *pNewDesc= ( pNewFlow && !pNewFlow->IsFollow() )
             ? pNewFlow->GetFrame().GetAttrSet()->GetPageDesc().GetPageDesc() : 
nullptr;
 
+    SAL_INFO( "sw.pagefrm", "WrongPageDesc p: " << pNew << " phys: " << 
pNew->GetPhyPageNum() );
+    SAL_INFO( "sw.pagefrm", "WrongPageDesc " << pNew->GetPageDesc() << " " << 
pDesc );
+    SAL_INFO( "sw.pagefrm", "WrongPageDesc odd: " << bOdd
+              << " first: " << bFirst << " " << pNew->GetFormat() << " == "
+              << (bOdd ? pDesc->GetRightFormat(bFirst) : 
pDesc->GetLeftFormat(bFirst)) << " "
+              << (bOdd ? pDesc->GetLeftFormat(bFirst) : 
pDesc->GetRightFormat(bFirst)) );
+
     return (pNew->GetPageDesc() != pDesc)   //  own desc ?
         || (pNew->GetFormat() !=
               (bOdd ? pDesc->GetRightFormat(bFirst) : 
pDesc->GetLeftFormat(bFirst)))
diff --git a/sw/source/core/layout/frmtool.cxx 
b/sw/source/core/layout/frmtool.cxx
index 3e36f3f..b69d987 100644
--- a/sw/source/core/layout/frmtool.cxx
+++ b/sw/source/core/layout/frmtool.cxx
@@ -2663,10 +2663,12 @@ SwPageFrame * InsertNewPage( SwPageDesc &rDesc, SwFrame 
*pUpper,
         SwPageDesc *pTmpDesc = pSibling && pSibling->GetPrev() ?
                 static_cast<SwPageFrame*>(pSibling->GetPrev())->GetPageDesc() 
: &rDesc;
         pRet = new SwPageFrame( pDoc->GetEmptyPageFormat(), pUpper, pTmpDesc );
+        SAL_INFO( "sw.pageframe", "InsertNewPage - insert empty p: " << pRet 
<< " d: " << pTmpDesc );
         pRet->Paste( pUpper, pSibling );
         pRet->PreparePage( bFootnote );
     }
     pRet = new SwPageFrame( pFormat, pUpper, &rDesc );
+    SAL_INFO( "sw.pageframe", "InsertNewPage p: " << pRet << " d: " << &rDesc 
<< " f: " << pFormat );
     pRet->Paste( pUpper, pSibling );
     pRet->PreparePage( bFootnote );
     if ( pRet->GetNext() )
diff --git a/sw/source/core/layout/pagechg.cxx 
b/sw/source/core/layout/pagechg.cxx
index 28477e9..493c0ec 100644
--- a/sw/source/core/layout/pagechg.cxx
+++ b/sw/source/core/layout/pagechg.cxx
@@ -966,6 +966,7 @@ void SwPageFrame::PrepareRegisterChg()
  */
 void SwFrame::CheckPageDescs( SwPageFrame *pStart, bool bNotifyFields, 
SwPageFrame** ppPrev )
 {
+    SAL_INFO( "sw.pageframe", "(CheckPageDescs in phy: " << 
pStart->GetPhyPageNum() );
     assert(pStart && "no starting page.");
 
     SwViewShell *pSh   = pStart->getRootFrame()->GetCurrShell();
@@ -974,6 +975,8 @@ void SwFrame::CheckPageDescs( SwPageFrame *pStart, bool 
bNotifyFields, SwPageFra
     if ( pImp && pImp->IsAction() && !pImp->GetLayAction().IsCheckPages() )
     {
         pImp->GetLayAction().SetCheckPageNum( pStart->GetPhyPageNum() );
+        SAL_INFO( "sw.pageframe", "CheckPageDescs out fast - via 
SetCheckPageNum: "
+                  << pStart->GetPhyPageNum() << ")" );
         return;
     }
 
@@ -1045,7 +1048,7 @@ void SwFrame::CheckPageDescs( SwPageFrame *pStart, bool 
bNotifyFields, SwPageFra
                         pNextFormatWish = bNextWantOdd ? 
pNextDesc->GetLeftFormat() : pNextDesc->GetRightFormat();
                     if ( pNextFormatWish && pNextPage->GetFormat() == 
pNextFormatWish )
                     {
-                        SAL_INFO( "sw.swpagefrm", "CheckPageDescs phys: " << 
pPage->GetPhyPageNum()
+                        SAL_INFO( "sw.pageframe", "CheckPageDescs phys: " << 
pPage->GetPhyPageNum()
                                   << " c: 1+3 - skip next page of p: " << 
pPage );
                         if (pPage->GetPageDesc() != pPrevPage->GetPageDesc())
                             pPage->SetPageDesc( pPrevPage->GetPageDesc(), 0 );
@@ -1059,6 +1062,8 @@ void SwFrame::CheckPageDescs( SwPageFrame *pStart, bool 
bNotifyFields, SwPageFra
                 bool bUpdatePrev = false;
                 if (ppPrev && *ppPrev == pPage)
                     bUpdatePrev = true;
+                SAL_INFO( "sw.pageframe", "CheckPageDescs phys: " << 
pPage->GetPhyPageNum()
+                          << " c: 1 - destroy p: " << pPage );
                 SwFrame::DestroyFrame(pPage);
                 if ( pStart == pPage )
                     pStart = pNextPage;
@@ -1070,6 +1075,8 @@ void SwFrame::CheckPageDescs( SwPageFrame *pStart, bool 
bNotifyFields, SwPageFra
             else if ( bIsEmpty && !pFormatWish &&  //2.
                       pDesc != pPage->GetPageDesc() )
             {
+                SAL_INFO( "sw.pageframe", "CheckPageDescs phys: " << 
pPage->GetPhyPageNum()
+                          << " c: 2 - set desc p: " << pPage << " d: " << 
pDesc );
                 pPage->SetPageDesc( pDesc, nullptr );
             }
             else if ( !bIsEmpty &&      //3.
@@ -1082,6 +1089,8 @@ void SwFrame::CheckPageDescs( SwPageFrame *pStart, bool 
bNotifyFields, SwPageFra
                 if ( pPrevPage )
                     pDesc = pPrevPage->GetPageDesc();
                 SwPageFrame *pTmp = new SwPageFrame( 
pDoc->GetEmptyPageFormat(), pRoot, pDesc );
+                SAL_INFO( "sw.pageframe", "CheckPageDescs phys: " << 
pPage->GetPhyPageNum()
+                          << " c: 3 - insert empty p: " << pTmp << " d: " << 
pDesc );
                 pTmp->Paste( pRoot, pPage );
                 pTmp->PreparePage( false );
                 pPage = pTmp;
@@ -1090,6 +1099,9 @@ void SwFrame::CheckPageDescs( SwPageFrame *pStart, bool 
bNotifyFields, SwPageFra
             {
                 SwPageDesc *pOld = pPage->GetPageDesc();
                 pPage->SetPageDesc( pDesc, pFormatWish );
+                SAL_INFO( "sw.pageframe", "CheckPageDescs phys: " << 
pPage->GetPhyPageNum()
+                          << " c: 4 - set desc + format p: " << pPage
+                          << " d: " << pDesc << " f: " << pFormatWish );
                 if ( bFootnotes )
                 {
                     // If specific values of the FootnoteInfo are changed, 
something has to happen.
@@ -1104,13 +1116,19 @@ void SwFrame::CheckPageDescs( SwPageFrame *pStart, bool 
bNotifyFields, SwPageFra
             else if ( pFormatWish && pPage->GetFormat() != pFormatWish )       
  //5.
             {
                 pPage->SetFrameFormat( pFormatWish );
+                SAL_INFO( "sw.pageframe", "CheckPageDescs phys: " << 
pPage->GetPhyPageNum()
+                          << " c: 5 - set format p: " << pPage << " f: " << 
pFormatWish );
             }
             else if ( !pFormatWish )                                       //6.
             {
                 // get format with inverted logic
                 pFormatWish = bWantOdd ? pDesc->GetLeftFormat() : 
pDesc->GetRightFormat();
                 if ( pFormatWish && pPage->GetFormat() != pFormatWish )
+                {
                     pPage->SetFrameFormat( pFormatWish );
+                    SAL_INFO( "sw.pageframe", "CheckPageDescs phys: " << 
pPage->GetPhyPageNum()
+                              << " c: 6 - set format p: " << pPage << " f: " 
<< pFormatWish );
+                }
             }
 #if OSL_DEBUG_LEVEL > 0
             else
@@ -1134,6 +1152,7 @@ void SwFrame::CheckPageDescs( SwPageFrame *pStart, bool 
bNotifyFields, SwPageFra
                 if (ppPrev && *ppPrev == pPage)
                     bUpdatePrev = true;
                 SwFrame::DestroyFrame(pPage);
+                SAL_INFO( "sw.pageframe", "CheckPageDescs - handle bIsEmpty - 
destroy p: " << pPage );
                 if ( pStart == pPage )
                     pStart = pTmp;
                 pPage = pTmp;
@@ -1175,6 +1194,7 @@ void SwFrame::CheckPageDescs( SwPageFrame *pStart, bool 
bNotifyFields, SwPageFra
         pPg = static_cast<SwPageFrame*>(pPg->GetNext());
     }
 #endif
+    SAL_INFO( "sw.pageframe", "CheckPageDescs out)" );
 }
 
 namespace
@@ -1193,7 +1213,14 @@ namespace
         SwPageFrame *pPage = new SwPageFrame(pFormat, pRoot, pDesc);
         SwPageFrame *pSibling = *pRefSibling;
         if ( pRefPage )
+        {
             *pRefPage = pPage;
+            SAL_INFO( "sw.pageframe", "doInsertPage p: " << pPage
+                                      << " d: " << pDesc << " f: " << pFormat 
);
+        }
+        else
+            SAL_INFO( "sw.pageframe", "doInsertPage - insert empty p: "
+                                      << pPage << " d: " << pDesc );
         pPage->Paste( pRoot, pSibling );
         pPage->PreparePage( bFootnote );
         // If the sibling has no body text, destroy it as long as it is no 
footnote page.
@@ -1268,8 +1295,12 @@ SwPageFrame *SwFrame::InsertPage( SwPageFrame 
*pPrevPage, bool bFootnote )
             {
                 const sal_uInt16 nNum = pImp->GetLayAction().GetCheckPageNum();
                 if ( nNum == pPrevPage->GetPhyPageNum() + 1 )
+                {
                     pImp->GetLayAction().SetCheckPageNumDirect(
                                                     pSibling->GetPhyPageNum() 
);
+                    SAL_INFO( "sw.pageframe", "InsertPage - 
SetCheckPageNumDirect: "
+                              << pSibling->GetPhyPageNum() );
+                }
                 return pPage;
             }
         }
@@ -1406,6 +1437,7 @@ void SwRootFrame::RemoveSuperfluous()
 
         if ( pPage )
         {
+            SAL_INFO( "sw.pageframe", "RemoveSuperfluous - DestroyFrm p: " << 
pPage );
             RemovePage( &pPage, SwRemoveResult::Prev );
             nDocPos = pPage ? pPage->Frame().Top() : 0;
         }
@@ -1469,11 +1501,27 @@ void SwRootFrame::AssertFlyPages()
             }
         }
     }
+
+#if OSL_DEBUG_LEVEL > 0
+    pPage = static_cast<SwPageFrame*>(Lower());
+    while ( pPage && pPage->GetNext() &&
+            !static_cast<SwPageFrame*>(pPage->GetNext())->IsFootnotePage() )
+    {
+        SAL_INFO( "sw.pageframe",  "AssertFlyPages p: " << pPage << " d: " << 
pPage->GetPageDesc()
+                   << " f: " << pPage->GetFormat() << " virt: " << 
pPage->GetVirtPageNum()
+                   << " phys: " << pPage->GetPhyPageNum() << " empty: " << 
pPage->IsEmptyPage() );
+        pPage = static_cast<SwPageFrame*>(pPage->GetNext());
+    }
+    SAL_INFO( "sw.pageframe", "AssertFlyPages p: " << pPage << " d: " << 
pPage->GetPageDesc()
+              << " f: " << pPage->GetFormat() << " virt: " << 
pPage->GetVirtPageNum()
+              << " phys: " << pPage->GetPhyPageNum() << " empty: " << 
pPage->IsEmptyPage() );
+#endif
 }
 
 /// Ensure that after the given page all page-bound objects are located on the 
correct page
 void SwRootFrame::AssertPageFlys( SwPageFrame *pPage )
 {
+    SAL_INFO( "sw.pageframe", "(AssertPageFlys in" );
     while ( pPage )
     {
         if (pPage->GetSortedObjs())
@@ -1488,6 +1536,7 @@ void SwRootFrame::AssertPageFlys( SwPageFrame *pPage )
                 if ((rAnch.GetAnchorId() == FLY_AT_PAGE) &&
                      nPg != pPage->GetPhyPageNum() )
                 {
+                    SAL_INFO( "sw.pageframe", nPg << " " << 
pPage->GetPhyPageNum() );
                     // If on the wrong page, check if previous page is empty
                     if( nPg && !(pPage->GetPhyPageNum()-1 == nPg &&
                         
static_cast<SwPageFrame*>(pPage->GetPrev())->IsEmptyPage()) )
@@ -1511,6 +1560,7 @@ void SwRootFrame::AssertPageFlys( SwPageFrame *pPage )
         }
         pPage = static_cast<SwPageFrame*>(pPage->GetNext());
     }
+    SAL_INFO( "sw.pageframe", "AssertPageFlys out)" );
 }
 
 Size SwRootFrame::ChgSize( const Size& aNewSize )
diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index 33d497a..51cedc2 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -1525,7 +1525,9 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
         pTargetDoc->SetAllUniqueFlyNames();
 
         // Unfreeze target document layouts and correct all PageDescs.
+        SAL_INFO( "sw.pageframe", "(MergeMailFiles pTargetShell->CalcLayout 
in" );
         pTargetShell->CalcLayout();
+        SAL_INFO( "sw.pageframe", "MergeMailFiles pTargetShell->CalcLayout 
out)" );
         for ( auto aLayout : pTargetShell->GetDoc()->GetAllLayouts() )
         {
             aLayout->FreezeLayout(false);
commit 0599989164b77f6c3368b3a2feedc8861107e37b
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Wed Aug 10 11:29:16 2016 +0200

    Don't oscillate empty pages in CheckPageDescs
    
    For the first case of dropping "wrong" empty pages,look ahead and
    pre-validate the next page, if it needs this empty page, to
    prevent case three for the next page.
    
    This prevents destruction and re-insert of the empty page.
    
    Change-Id: I475aa98a2693f814afcc41bd4bc73f04e742c105

diff --git a/sw/source/core/layout/pagechg.cxx 
b/sw/source/core/layout/pagechg.cxx
index 3142e33..28477e9 100644
--- a/sw/source/core/layout/pagechg.cxx
+++ b/sw/source/core/layout/pagechg.cxx
@@ -1028,6 +1028,33 @@ void SwFrame::CheckPageDescs( SwPageFrame *pStart, bool 
bNotifyFields, SwPageFra
             if ( bIsEmpty && ( pFormatWish ||          //1.
                  ( !bWantOdd && !pPrevPage ) ) )
             {
+                // Check all cases for the next page, so we don't oscillate 
empty pages
+                // Skip case 1 and 2, as we require a non-empty next page to 
save the empty page
+                // Case 3 is the one we actually want to predict and skip
+                // We can skip the empty check of case 3, as we just work on 
an existing next page
+                bool bNextWantOdd;
+                SwPageDesc *pNextDesc;
+                if ( pNextPage && !pNextPage->IsEmptyPage() &&    //3.
+                     pNextPage->OnRightPage() == (bNextWantOdd = 
pNextPage->WannaRightPage()) &&
+                     pNextPage->GetPageDesc() == (pNextDesc = 
pNextPage->FindPageDesc()) )   //4.
+                {
+                    bool bNextFirst = pNextPage->OnFirstPage();
+                    SwFrameFormat *pNextFormatWish = (bNextWantOdd) ?   //5.
+                        pNextDesc->GetRightFormat(bNextFirst) : 
pNextDesc->GetLeftFormat(bNextFirst);
+                    if ( !pNextFormatWish )    // 6.
+                        pNextFormatWish = bNextWantOdd ? 
pNextDesc->GetLeftFormat() : pNextDesc->GetRightFormat();
+                    if ( pNextFormatWish && pNextPage->GetFormat() == 
pNextFormatWish )
+                    {
+                        SAL_INFO( "sw.swpagefrm", "CheckPageDescs phys: " << 
pPage->GetPhyPageNum()
+                                  << " c: 1+3 - skip next page of p: " << 
pPage );
+                        if (pPage->GetPageDesc() != pPrevPage->GetPageDesc())
+                            pPage->SetPageDesc( pPrevPage->GetPageDesc(), 0 );
+                        // We can skip the next page, as all checks were 
already done!
+                        pPage = 
static_cast<SwPageFrame*>(pNextPage->GetNext());
+                        continue;
+                    }
+                }
+
                 pPage->Cut();
                 bool bUpdatePrev = false;
                 if (ppPrev && *ppPrev == pPage)
commit adf4c82b6c4ec9d8892f5c417e4a81cf04808447
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Wed Aug 10 11:23:23 2016 +0200

    Flush the page break for correct layouting
    
    This is a workaround to create correct SwPageFrm objects for
    layouting, so the page break is actually visible when
    copying nodes, so we create the correct SwPageFrm.
    
    This is especially problematic for mail merge after the fix in
    commit 60d34e1c840d2c317bb7d0a5b14f4602c22b3fcc, which -
    correctly - checks all later SwPageDesc for every fix done by
    CheckPageDescs().
    
    Change-Id: Ie6ea2e9a0587199be4dbaf3ed63a94c29b318ce2

diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index 3e162fd..07ac968 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -1066,6 +1066,13 @@ SwNodeIndex SwDoc::AppendDoc(const SwDoc& rSource, 
sal_uInt16 const nStartPageNu
                 for (sw::mark::IMark* pMark : aSeenMarks)
                     pMarkAccess->repositionMark(pMark, aPaM);
             }
+
+            // Flush the page break, if we want to keep it
+            if ( !bDeletePrevious )
+            {
+                pTargetShell->EndAllAction();
+                pTargetShell->StartAllAction();
+            }
         }
     }
 #ifdef DBG_UTIL
commit 0b5352f67e9c684e59c4f8653ed7fcdd9ae5aa05
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Wed Aug 10 11:06:33 2016 +0200

    Use InsertPage in AssertFlyPages
    
    AssertFlyPages used its own code to insert pages. It had two
    flaws:
    
      1. It used the SwPageDesc of the previous page, unaware of
         changed page description of a new page, which would later
         be fixed by CheckPageDescs, eventually requiring re-layout.
    
      2. The Code has an of-by-one error when setting the initial
         bOdd, which would also insert wrong / inverse left and
         right pages.
    
    So this changes AssertFlyPages to use InsertPage, which has a
    little more overhead for inserts, but prevents later expensive
    corrections, especially when CheckPageDescs() inserts or removes
    "early" pages, which need to evaluate and move all page bound
    flys.
    
    Change-Id: I8806cebb26db60602d8438f117e0416e07228b3b

diff --git a/sw/source/core/layout/pagechg.cxx 
b/sw/source/core/layout/pagechg.cxx
index b679cc6..3142e33 100644
--- a/sw/source/core/layout/pagechg.cxx
+++ b/sw/source/core/layout/pagechg.cxx
@@ -1422,29 +1422,9 @@ void SwRootFrame::AssertFlyPages()
 
     if ( nMaxPg > pPage->GetPhyPageNum() )
     {
-        // Continue pages based on the rules of the PageDesc after the last 
page.
-        bool bOdd = (pPage->GetPhyPageNum() % 2) != 0;
-        SwPageDesc *pDesc = pPage->GetPageDesc();
-        SwFrame *pSibling = pPage->GetNext();
-        for ( sal_uInt16 i = pPage->GetPhyPageNum(); i < nMaxPg; ++i  )
-        {
-            if ( !(bOdd ? pDesc->GetRightFormat() : pDesc->GetLeftFormat()) )
-            {
-                // Insert empty page (but Flys will be stored in the next page)
-                pPage = new SwPageFrame( pDoc->GetEmptyPageFormat(), this, 
pDesc );
-                pPage->Paste( this, pSibling );
-                pPage->PreparePage( false );
-                bOdd = !bOdd;
-                ++i;
-            }
-            pPage = new
-                    SwPageFrame( (bOdd ? pDesc->GetRightFormat() :
-                                       pDesc->GetLeftFormat()), this, pDesc );
-            pPage->Paste( this, pSibling );
-            pPage->PreparePage( false );
-            bOdd = !bOdd;
-            pDesc = pDesc->GetFollow();
-        }
+        for ( sal_uInt16 i = pPage->GetPhyPageNum(); i < nMaxPg; ++i )
+            pPage = InsertPage( pPage, false );
+
         // If the endnote pages are now corrupt, destroy them.
         if ( !pDoc->GetFootnoteIdxs().empty() )
         {
@@ -1455,7 +1435,7 @@ void SwRootFrame::AssertFlyPages()
             if ( pPage )
             {
                 SwPageDesc *pTmpDesc = pPage->FindPageDesc();
-                bOdd = pPage->OnRightPage();
+                bool bOdd = pPage->OnRightPage();
                 if ( pPage->GetFormat() !=
                      (bOdd ? pTmpDesc->GetRightFormat() : 
pTmpDesc->GetLeftFormat()) )
                     RemoveFootnotes( pPage, false, true );
commit f075c30ed6b7820a7723cf18049c2ec2384c5dab
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Wed Aug 10 10:15:33 2016 +0200

    Refactor duplicated code in SwFrame::InsertPage
    
    Change-Id: Iff9a78cf2f5e6ded4d1b03a8303529aa324ddad9

diff --git a/sw/source/core/inc/rootfrm.hxx b/sw/source/core/inc/rootfrm.hxx
index 66dc0ec..078a838 100644
--- a/sw/source/core/inc/rootfrm.hxx
+++ b/sw/source/core/inc/rootfrm.hxx
@@ -58,6 +58,12 @@ namespace o3tl
     template<> struct typed_flags<SwInvalidateFlags> : 
is_typed_flags<SwInvalidateFlags, 0x7f> {};
 };
 
+enum class SwRemoveResult
+{
+    Next,
+    Prev
+};
+
 /// The root element of a Writer document layout.
 class SwRootFrame: public SwLayoutFrame
 {
@@ -385,6 +391,8 @@ public:
 
     bool IsLayoutFreezed() const { return mbLayoutFreezed; }
     void FreezeLayout( bool freeze ) { mbLayoutFreezed = freeze; }
+
+    void RemovePage( SwPageFrame **pDel, SwRemoveResult eResult );
 };
 
 inline long SwRootFrame::GetBrowseWidth() const
diff --git a/sw/source/core/layout/pagechg.cxx 
b/sw/source/core/layout/pagechg.cxx
index 6375f8c..b679cc6 100644
--- a/sw/source/core/layout/pagechg.cxx
+++ b/sw/source/core/layout/pagechg.cxx
@@ -1158,6 +1158,27 @@ namespace
         const SwFrame* pBodyContent = pBody ? pBody->Lower() : nullptr;
         return pBodyContent && pBodyContent->IsDeleteForbidden();
     }
+
+    bool doInsertPage( SwRootFrame *pRoot, SwPageFrame **pRefSibling,
+                       SwFrameFormat *pFormat, SwPageDesc *pDesc,
+                       bool bFootnote, SwPageFrame **pRefPage )
+    {
+        SwPageFrame *pPage = new SwPageFrame(pFormat, pRoot, pDesc);
+        SwPageFrame *pSibling = *pRefSibling;
+        if ( pRefPage )
+            *pRefPage = pPage;
+        pPage->Paste( pRoot, pSibling );
+        pPage->PreparePage( bFootnote );
+        // If the sibling has no body text, destroy it as long as it is no 
footnote page.
+        if ( pSibling && !pSibling->IsFootnotePage() &&
+             !pSibling->FindFirstBodyContent() &&
+             (!pRefPage || !isDeleteForbidden(pSibling)) )
+        {
+            pRoot->RemovePage( pRefSibling, SwRemoveResult::Next ) ;
+            return false;
+        }
+        return true;
+    }
 }
 
 SwPageFrame *SwFrame::InsertPage( SwPageFrame *pPrevPage, bool bFootnote )
@@ -1197,44 +1218,16 @@ SwPageFrame *SwFrame::InsertPage( SwPageFrame 
*pPrevPage, bool bFootnote )
     // If there is no FrameFormat for this page, create an empty page.
     if( bWishedOdd != bNextOdd )
     {
-        SwFrameFormat *const pEmptyFormat = pDoc->GetEmptyPageFormat();
-        SwPageDesc *pTmpDesc = pPrevPage->GetPageDesc();
-        SwPageFrame *pPage = new SwPageFrame(pEmptyFormat, pRoot, pTmpDesc);
-        pPage->Paste( pRoot, pSibling );
-        pPage->PreparePage( bFootnote );
-        // If the sibling has no body text, destroy it as long as it is no 
footnote page.
-        if ( pSibling && !pSibling->IsFootnotePage() &&
-             !pSibling->FindFirstBodyContent() )
-        {
-            SwPageFrame *pDel = pSibling;
-            pSibling = static_cast<SwPageFrame*>(pSibling->GetNext());
-            if ( !pDoc->GetFootnoteIdxs().empty() )
-                pRoot->RemoveFootnotes( pDel, true );
-            pDel->Cut();
-            SwFrame::DestroyFrame(pDel);
-        }
-        else
+        if( doInsertPage( pRoot, &pSibling, pDoc->GetEmptyPageFormat(),
+                          pPrevPage->GetPageDesc(), bFootnote, nullptr ) )
             bCheckPages = true;
     }
     SwFrameFormat *const pFormat( (bWishedOdd)
             ? pDesc->GetRightFormat(bWishedFirst)
             : pDesc->GetLeftFormat(bWishedFirst) );
     assert(pFormat);
-    SwPageFrame *pPage = new SwPageFrame( pFormat, pRoot, pDesc );
-    pPage->Paste( pRoot, pSibling );
-    pPage->PreparePage( bFootnote );
-    // If the sibling has no body text, destroy it as long as it is no 
footnote page.
-    if ( pSibling && !pSibling->IsFootnotePage() &&
-         !pSibling->FindFirstBodyContent() && !isDeleteForbidden(pSibling) )
-    {
-        SwPageFrame *pDel = pSibling;
-        pSibling = static_cast<SwPageFrame*>(pSibling->GetNext());
-        if ( !pDoc->GetFootnoteIdxs().empty() )
-            pRoot->RemoveFootnotes( pDel, true );
-        pDel->Cut();
-        SwFrame::DestroyFrame(pDel);
-    }
-    else
+    SwPageFrame *pPage = nullptr;
+    if( doInsertPage( pRoot, &pSibling, pFormat, pDesc, bFootnote, &pPage ) )
         bCheckPages = true;
 
     if ( pSibling )
@@ -1304,6 +1297,17 @@ SwTwips SwRootFrame::ShrinkFrame( SwTwips nDist, bool 
bTst, bool )
     return nDist;
 }
 
+void SwRootFrame::RemovePage( SwPageFrame **pDelRef, SwRemoveResult eResult )
+{
+    SwPageFrame *pDel = *pDelRef;
+    (*pDelRef) = static_cast<SwPageFrame*>(
+        eResult == SwRemoveResult::Next ? pDel->GetNext() : pDel->GetPrev() );
+    if ( !GetFormat()->GetDoc()->GetFootnoteIdxs().empty() )
+        RemoveFootnotes( pDel, true );
+    pDel->Cut();
+    SwFrame::DestroyFrame( pDel );
+}
+
 /// remove pages that are not needed at all
 void SwRootFrame::RemoveSuperfluous()
 {
@@ -1375,12 +1379,7 @@ void SwRootFrame::RemoveSuperfluous()
 
         if ( pPage )
         {
-            SwPageFrame *pEmpty = pPage;
-            pPage = static_cast<SwPageFrame*>(pPage->GetPrev());
-            if ( !GetFormat()->GetDoc()->GetFootnoteIdxs().empty() )
-                RemoveFootnotes( pEmpty, true );
-            pEmpty->Cut();
-            SwFrame::DestroyFrame(pEmpty);
+            RemovePage( &pPage, SwRemoveResult::Prev );
             nDocPos = pPage ? pPage->Frame().Top() : 0;
         }
     } while ( pPage );
commit 978a54b99d7e2df9c0df61cdc3d4153a005618b0
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Wed Aug 10 10:05:08 2016 +0200

    Fix some variable scopes and clarify names
    
    Helps understanding the code, especially CheckPageDescs().
    
    Change-Id: I53e7d0ea65d6c6ae3da98acba4d366a47d2c4210

diff --git a/sw/source/core/layout/flowfrm.cxx 
b/sw/source/core/layout/flowfrm.cxx
index f207a89..a28f36a 100644
--- a/sw/source/core/layout/flowfrm.cxx
+++ b/sw/source/core/layout/flowfrm.cxx
@@ -818,15 +818,15 @@ bool SwFrame::WrongPageDesc( SwPageFrame* pNew )
     // Way out of the situation: Try to preliminarily insert a
     // new page once (empty pages are already inserted by InsertPage()
     // if required)
-    const SwFormatPageDesc &rFormatDesc = GetAttrSet()->GetPageDesc();
 
     //My Pagedesc doesn't count if I'm a follow!
-    SwPageDesc *pDesc = nullptr;
+    const SwPageDesc *pDesc = nullptr;
     int nTmp = 0;
     SwFlowFrame *pFlow = SwFlowFrame::CastFlowFrame( this );
     if ( !pFlow || !pFlow->IsFollow() )
     {
-        pDesc = const_cast<SwPageDesc*>(rFormatDesc.GetPageDesc());
+        const SwFormatPageDesc &rFormatDesc = GetAttrSet()->GetPageDesc();
+        pDesc = rFormatDesc.GetPageDesc();
         if( pDesc )
         {
             if( !pDesc->GetRightFormat() )
diff --git a/sw/source/core/layout/pagechg.cxx 
b/sw/source/core/layout/pagechg.cxx
index 7ea39752..6375f8c 100644
--- a/sw/source/core/layout/pagechg.cxx
+++ b/sw/source/core/layout/pagechg.cxx
@@ -990,19 +990,21 @@ void SwFrame::CheckPageDescs( SwPageFrame *pStart, bool 
bNotifyFields, SwPageFra
         pPage = static_cast<SwPageFrame*>(pPage->GetPrev());
     while ( pPage )
     {
-        // obtain PageDesc and FrameFormat
+        SwPageFrame *pPrevPage = static_cast<SwPageFrame*>(pPage->GetPrev());
+        SwPageFrame *pNextPage = static_cast<SwPageFrame*>(pPage->GetNext());
+
         SwPageDesc *pDesc = pPage->FindPageDesc();
-        bool bCheckEmpty = pPage->IsEmptyPage();
-        bool bActOdd = pPage->OnRightPage();
-        bool bOdd = pPage->WannaRightPage();
+        bool bIsEmpty = pPage->IsEmptyPage();
+        bool bIsOdd = pPage->OnRightPage();
+        bool bWantOdd = pPage->WannaRightPage();
         bool bFirst = pPage->OnFirstPage();
-        SwFrameFormat *pFormatWish = (bOdd)
+        SwFrameFormat *pFormatWish = (bWantOdd)
             ? pDesc->GetRightFormat(bFirst) : pDesc->GetLeftFormat(bFirst);
 
-        if ( bActOdd != bOdd ||
+        if ( bIsOdd != bWantOdd ||
              pDesc != pPage->GetPageDesc() ||        // wrong Desc
-             ( pFormatWish != pPage->GetFormat()  &&       // wrong format and
-               ( !pPage->IsEmptyPage() || pFormatWish ) // not blank /empty
+             ( pFormatWish != pPage->GetFormat() &&       // wrong format and
+               ( !bIsEmpty || pFormatWish ) // not blank /empty
              )
            )
         {
@@ -1012,8 +1014,7 @@ void SwFrame::CheckPageDescs( SwPageFrame *pStart, bool 
bNotifyFields, SwPageFra
 
             // invalidate the field, starting from here
             if ( nDocPos == LONG_MAX )
-                nDocPos = pPage->GetPrev() ?
-                            pPage->GetPrev()->Frame().Top() : 
pPage->Frame().Top();
+                nDocPos = pPrevPage ? pPrevPage->Frame().Top() : 
pPage->Frame().Top();
 
             // Cases:
             //  1. Empty page should be "normal" page -> remove empty page and 
take next one
@@ -1024,38 +1025,36 @@ void SwFrame::CheckPageDescs( SwPageFrame *pStart, bool 
bNotifyFields, SwPageFra
             //  5. Normal page should have different format -> change
             //  6. No "wish" format provided -> take the "other" format 
(left/right) of the PageDesc
 
-            if ( pPage->IsEmptyPage() && ( pFormatWish ||          //1.
-                 ( !bOdd && !pPage->GetPrev() ) ) )
+            if ( bIsEmpty && ( pFormatWish ||          //1.
+                 ( !bWantOdd && !pPrevPage ) ) )
             {
-                SwPageFrame *pTmp = 
static_cast<SwPageFrame*>(pPage->GetNext());
                 pPage->Cut();
                 bool bUpdatePrev = false;
                 if (ppPrev && *ppPrev == pPage)
                     bUpdatePrev = true;
                 SwFrame::DestroyFrame(pPage);
                 if ( pStart == pPage )
-                    pStart = pTmp;
-                pPage = pTmp;
+                    pStart = pNextPage;
+                pPage = pNextPage;
                 if (bUpdatePrev)
-                    *ppPrev = pTmp;
+                    *ppPrev = pNextPage;
                 continue;
             }
-            else if ( pPage->IsEmptyPage() && !pFormatWish &&  //2.
+            else if ( bIsEmpty && !pFormatWish &&  //2.
                       pDesc != pPage->GetPageDesc() )
             {
                 pPage->SetPageDesc( pDesc, nullptr );
             }
-            else if ( !pPage->IsEmptyPage() &&      //3.
-                      bActOdd != bOdd &&
-                      ( ( !pPage->GetPrev() && !bOdd ) ||
-                        ( pPage->GetPrev() &&
-                          
!static_cast<SwPageFrame*>(pPage->GetPrev())->IsEmptyPage() )
+            else if ( !bIsEmpty &&      //3.
+                      bIsOdd != bWantOdd &&
+                      ( ( !pPrevPage && !bWantOdd ) ||
+                        ( pPrevPage && !pPrevPage->IsEmptyPage() )
                       )
                     )
             {
-                if ( pPage->GetPrev() )
-                    pDesc = 
static_cast<SwPageFrame*>(pPage->GetPrev())->GetPageDesc();
-                SwPageFrame *pTmp = new SwPageFrame( 
pDoc->GetEmptyPageFormat(),pRoot,pDesc);
+                if ( pPrevPage )
+                    pDesc = pPrevPage->GetPageDesc();
+                SwPageFrame *pTmp = new SwPageFrame( 
pDoc->GetEmptyPageFormat(), pRoot, pDesc );
                 pTmp->Paste( pRoot, pPage );
                 pTmp->PreparePage( false );
                 pPage = pTmp;
@@ -1082,8 +1081,8 @@ void SwFrame::CheckPageDescs( SwPageFrame *pStart, bool 
bNotifyFields, SwPageFra
             else if ( !pFormatWish )                                       //6.
             {
                 // get format with inverted logic
-                pFormatWish = bOdd ? pDesc->GetLeftFormat() : 
pDesc->GetRightFormat();
-                if ( pPage->GetFormat() != pFormatWish )
+                pFormatWish = bWantOdd ? pDesc->GetLeftFormat() : 
pDesc->GetRightFormat();
+                if ( pFormatWish && pPage->GetFormat() != pFormatWish )
                     pPage->SetFrameFormat( pFormatWish );
             }
 #if OSL_DEBUG_LEVEL > 0
@@ -1093,7 +1092,7 @@ void SwFrame::CheckPageDescs( SwPageFrame *pStart, bool 
bNotifyFields, SwPageFra
             }
 #endif
         }
-        if ( bCheckEmpty )
+        if ( bIsEmpty )
         {
             // It also might be that an empty page is not needed at all.
             // However, the algorithm above cannot determine that. It is not 
needed if the following
commit 9eff9e699e17cc5a8a25895bd28dc8e4ceb8071e
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Wed Aug 10 09:47:40 2016 +0200

    Don't re-check valid SwPageDescs when layouting
    
    nCheckPageNum is set to USHRT_MAX, if all SwPageDesc were checked.
    Code manipulating SwPageFrm objects checks the pages via
    CheckPageDescs(). If this is currently forbidden, CheckPageDescs()
    sets nCheckPageNum to the first page to check.
    
    I guess the !pPage check is there to check the pages - at the end,
    if someone has missed the CheckPageDescs call. And we have to run
    the check, if the current page is unchecked AKA
      pPage->GetPhyPageNum() >= nCheckPageNum
    to do correct layouting.
    
    Change-Id: Ib67878115cde04b7161c919a67131a1e1dc67d8d

diff --git a/sw/source/core/layout/layact.cxx b/sw/source/core/layout/layact.cxx
index a8d04af..f416426 100644
--- a/sw/source/core/layout/layact.cxx
+++ b/sw/source/core/layout/layact.cxx
@@ -454,7 +454,10 @@ void SwLayAction::InternalAction(OutputDevice* 
pRenderContext)
     sal_uInt16 nPercentPageNum = 0;
     while ( (pPage && !IsInterrupt()) || m_nCheckPageNum != USHRT_MAX )
     {
-        if (!pPage || (m_nCheckPageNum != USHRT_MAX && pPage->GetPhyPageNum() 
>= m_nCheckPageNum))
+        // nCheckPageNum is set to USHRT_MAX in this code path after we have
+        // checked the SwPageDescs and set tos the minimal changed SwPageDesc.
+        // We don't need to check the SwPageDescs without changes.
+        if ( (m_nCheckPageNum != USHRT_MAX) && (!pPage || 
pPage->GetPhyPageNum() >= m_nCheckPageNum) )
         {
             if ( !pPage || pPage->GetPhyPageNum() > m_nCheckPageNum )
             {
commit 28b4c575703430602c72a442f59bb5f9f6aeb749
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Fri Jul 22 18:00:59 2016 +0200

    Remove now unused SwTextBoxHelper functions
    
    Change-Id: I39500424c79040b1887ea74081fdf0ea0bc5f009

diff --git a/sw/inc/textboxhelper.hxx b/sw/inc/textboxhelper.hxx
index 98983ba..32fc216 100644
--- a/sw/inc/textboxhelper.hxx
+++ b/sw/inc/textboxhelper.hxx
@@ -73,8 +73,6 @@ public:
     static SwFrameFormat* getOtherTextBoxFormat(const SwFrameFormat* pFormat, 
sal_uInt16 nType);
     /// If we have an associated TextFrame, then return that.
     static SwFrameFormat* 
getOtherTextBoxFormat(css::uno::Reference<css::drawing::XShape> xShape);
-    static SwFrameFormat* findTextBox(const SwFrameFormat* pShape);
-    static SwFrameFormat* findTextBox(const 
css::uno::Reference<css::drawing::XShape>& xShape);
     /// Return the textbox rectangle of a draw shape (in twips).
     static Rectangle getTextRectangle(SwFrameFormat* pShape, bool bAbsolute = 
true);
 
@@ -91,17 +89,6 @@ public:
     /// Is pObject a textbox of a drawinglayer shape?
     static bool isTextBox(const SdrObject* pObject);
 
-    /// Look up TextFrames in a document, which are in fact TextBoxes.
-    static std::set<const SwFrameFormat*> findTextBoxes(const SwDoc* pDoc);
-    /**
-     * Look up TextFrames in a document, which are in fact TextBoxes.
-     *
-     * If rNode has a matching SwContentFrame, then only TextBoxes of rNode are
-     * returned.
-     */
-    static std::set<const SwFrameFormat*> findTextBoxes(const SwNode& rNode);
-    /// Build a textbox -> shape format map.
-    static std::map<SwFrameFormat*, SwFrameFormat*> findShapes(const SwDoc* 
pDoc);
     /// Count number of shapes in the document, excluding TextBoxes.
     static sal_Int32 getCount(const SwDoc* pDoc);
     /// Count number of shapes on the page, excluding TextBoxes.
diff --git a/sw/source/core/doc/textboxhelper.cxx 
b/sw/source/core/doc/textboxhelper.cxx
index 5049f10..8a561bb 100644
--- a/sw/source/core/doc/textboxhelper.cxx
+++ b/sw/source/core/doc/textboxhelper.cxx
@@ -126,25 +126,6 @@ void SwTextBoxHelper::destroy(SwFrameFormat* pShape)
     }
 }
 
-std::set<const SwFrameFormat*> SwTextBoxHelper::findTextBoxes(const SwDoc* 
pDoc)
-{
-    std::set<const SwFrameFormat*> aTextBoxes;
-
-    const SwFrameFormats& rSpzFrameFormats = *pDoc->GetSpzFrameFormats();
-    for (const SwFrameFormat* pFormat : rSpzFrameFormats)
-    {
-        // A TextBox in the context of this class is a fly frame that has a
-        // matching (same RES_CNTNT) draw frame.
-        if (!pFormat->GetAttrSet().HasItem(RES_CNTNT) || 
!pFormat->GetContent().GetContentIdx())
-            continue;
-
-        if (pFormat->Which() == RES_FLYFRMFMT && nullptr != 
pFormat->GetOtherTextBoxFormat())
-            aTextBoxes.insert(pFormat);
-    }
-
-    return aTextBoxes;
-}
-
 bool SwTextBoxHelper::isTextBox(const SwFrameFormat* pShape, sal_uInt16 nType)
 {
    assert(nType == RES_FLYFRMFMT || nType == RES_DRAWFRMFMT);
@@ -167,49 +148,6 @@ bool SwTextBoxHelper::isTextBox(const SwFrameFormat* 
pShape, sal_uInt16 nType)
    return true;
 }
 
-std::set<const SwFrameFormat*> SwTextBoxHelper::findTextBoxes(const SwNode& 
rNode)
-{
-    const SwDoc* pDoc = rNode.GetDoc();
-    const SwContentNode* pContentNode = nullptr;
-    const SwContentFrame* pContentFrame = nullptr;
-    bool bHaveViewShell = 
pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
-    if (bHaveViewShell && (pContentNode = rNode.GetContentNode()) && 
(pContentFrame = 
pContentNode->getLayoutFrame(pDoc->getIDocumentLayoutAccess().GetCurrentLayout())))
-    {
-        // We can use the layout information to iterate over only the frames 
which are anchored to us.
-        std::set<const SwFrameFormat*> aRet;
-        const SwSortedObjs* pSortedObjs = pContentFrame->GetDrawObjs();
-        if (pSortedObjs)
-        {
-            for (SwAnchoredObject* pAnchoredObject : *pSortedObjs)
-            {
-                SwFrameFormat* pTextBox = 
getOtherTextBoxFormat(&pAnchoredObject->GetFrameFormat(), RES_DRAWFRMFMT);
-                if (pTextBox)
-                    aRet.insert(pTextBox);
-            }
-        }
-        return aRet;
-    }
-    else
-        // If necessary, here we could manually limit the returned set to the
-        // ones which are anchored to rNode, but currently no need to do so.
-        return findTextBoxes(pDoc);
-}
-
-std::map<SwFrameFormat*, SwFrameFormat*> SwTextBoxHelper::findShapes(const 
SwDoc* pDoc)
-{
-    std::map<SwFrameFormat*, SwFrameFormat*> aRet;
-
-    const SwFrameFormats& rSpzFrameFormats = *pDoc->GetSpzFrameFormats();
-    for (SwFrameFormat* pFormat : rSpzFrameFormats)
-    {
-        SwFrameFormat* pTextBox = getOtherTextBoxFormat(pFormat, 
RES_DRAWFRMFMT);
-        if (pTextBox)
-            aRet[pTextBox] = pFormat;
-    }
-
-    return aRet;
-}
-
 bool SwTextBoxHelper::isTextBox(const SdrObject* pObject)
 {
     const SwVirtFlyDrawObj* pVirtFlyDrawObj = dynamic_cast<const 
SwVirtFlyDrawObj*>(pObject);
@@ -310,38 +248,6 @@ SwFrameFormat* 
SwTextBoxHelper::getOtherTextBoxFormat(uno::Reference<drawing::XS
     return getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT);
 }
 
-SwFrameFormat* SwTextBoxHelper::findTextBox(const 
uno::Reference<drawing::XShape>& xShape)
-{
-    SwXShape* pShape = dynamic_cast<SwXShape*>(xShape.get());
-    if (!pShape)
-        return nullptr;
-
-    return findTextBox(pShape->GetFrameFormat());
-}
-
-SwFrameFormat* SwTextBoxHelper::findTextBox(const SwFrameFormat* pShape)
-{
-    SwFrameFormat* pRet = nullptr;
-
-    // Only draw frames can have TextBoxes.
-    if (pShape && pShape->Which() == RES_DRAWFRMFMT && 
pShape->GetAttrSet().HasItem(RES_CNTNT))
-    {
-        const SwFormatContent& rContent = pShape->GetContent();
-        const SwFrameFormats& rSpzFrameFormats = 
*pShape->GetDoc()->GetSpzFrameFormats();
-        for (SwFrameFormat* pFormat : rSpzFrameFormats)
-        {
-            // Only a fly frame can be a TextBox.
-            if (pFormat->Which() == RES_FLYFRMFMT && 
pFormat->GetAttrSet().HasItem(RES_CNTNT) && pFormat->GetContent() == rContent)
-            {
-                pRet = pFormat;
-                break;
-            }
-        }
-    }
-
-    return pRet;
-}
-
 template < typename T >
 void lcl_queryInterface(SwFrameFormat* pShape, uno::Any& rAny)
 {
commit f7f5d27066b696ac4e33246d3794bde8058e8622
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Fri Jul 22 17:59:28 2016 +0200

    Add convenience function getOtherTextBoxFormat
    
    Since we already have isTextBox to identify a text box, this
    just adds a call to SwFrameFormat::GetOtherTextBoxFormat() to
    actually return the corresponding SwFrameFormat.
    
    This gets rid off all the remaining occurences of the
    SwFrameFormat / Textbox sets and maps.
    
    Change-Id: Id5f05a1ff71e604658e7d8a0d0825f5671335b3f

diff --git a/sw/inc/textboxhelper.hxx b/sw/inc/textboxhelper.hxx
index eb94bbc..98983ba 100644
--- a/sw/inc/textboxhelper.hxx
+++ b/sw/inc/textboxhelper.hxx
@@ -62,7 +62,17 @@ public:
     /// Similar to syncProperty(), but used by the internal API (e.g. for UI 
purposes).
     static void syncFlyFrameAttr(SwFrameFormat& rShape, SfxItemSet& rSet);
 
+    /**
+     * If we have an associated TextFrame, then return that.
+     *
+     * @param nType Expected frame format type.
+     *              Valid types are RES_DRAWFRMFMT and RES_FLYFRMFMT.
+     *
+     * @see isTextBox
+     */
+    static SwFrameFormat* getOtherTextBoxFormat(const SwFrameFormat* pFormat, 
sal_uInt16 nType);
     /// If we have an associated TextFrame, then return that.
+    static SwFrameFormat* 
getOtherTextBoxFormat(css::uno::Reference<css::drawing::XShape> xShape);
     static SwFrameFormat* findTextBox(const SwFrameFormat* pShape);
     static SwFrameFormat* findTextBox(const 
css::uno::Reference<css::drawing::XShape>& xShape);
     /// Return the textbox rectangle of a draw shape (in twips).
diff --git a/sw/source/core/doc/DocumentLayoutManager.cxx 
b/sw/source/core/doc/DocumentLayoutManager.cxx
index 5fc0d4c..254a4ee 100644
--- a/sw/source/core/doc/DocumentLayoutManager.cxx
+++ b/sw/source/core/doc/DocumentLayoutManager.cxx
@@ -494,7 +494,7 @@ SwFrameFormat *DocumentLayoutManager::CopyLayoutFormat(
         pDest->MakeFrames();
 
     // If the draw format has a TextBox, then copy its fly format as well.
-    if (SwFrameFormat* pSourceTextBox = SwTextBoxHelper::findTextBox(&rSource))
+    if (SwFrameFormat* pSourceTextBox = 
SwTextBoxHelper::getOtherTextBoxFormat(&rSource, RES_DRAWFRMFMT))
     {
         SwFormatAnchor boxAnchor(rNewAnchor);
         if (FLY_AS_CHAR == boxAnchor.GetAnchorId())
diff --git a/sw/source/core/doc/textboxhelper.cxx 
b/sw/source/core/doc/textboxhelper.cxx
index b180366..5049f10 100644
--- a/sw/source/core/doc/textboxhelper.cxx
+++ b/sw/source/core/doc/textboxhelper.cxx
@@ -115,7 +115,7 @@ void SwTextBoxHelper::destroy(SwFrameFormat* pShape)
     // If a TextBox was enabled previously
     if (pShape->GetAttrSet().HasItem(RES_CNTNT))
     {
-        SwFrameFormat* pFormat = findTextBox(pShape);
+        SwFrameFormat* pFormat = pShape->GetOtherTextBoxFormat();
 
         // Unlink the TextBox's text range from the original shape.
         pShape->ResetFormatAttr(RES_CNTNT);
@@ -129,7 +129,6 @@ void SwTextBoxHelper::destroy(SwFrameFormat* pShape)
 std::set<const SwFrameFormat*> SwTextBoxHelper::findTextBoxes(const SwDoc* 
pDoc)
 {
     std::set<const SwFrameFormat*> aTextBoxes;
-    std::map<SwNodeIndex, const SwFrameFormat*> aFlyFormats, aDrawFormats;
 
     const SwFrameFormats& rSpzFrameFormats = *pDoc->GetSpzFrameFormats();
     for (const SwFrameFormat* pFormat : rSpzFrameFormats)
@@ -139,22 +138,8 @@ std::set<const SwFrameFormat*> 
SwTextBoxHelper::findTextBoxes(const SwDoc* pDoc)
         if (!pFormat->GetAttrSet().HasItem(RES_CNTNT) || 
!pFormat->GetContent().GetContentIdx())
             continue;
 
-        const SwNodeIndex& rIndex = *pFormat->GetContent().GetContentIdx();
-
-        if (pFormat->Which() == RES_FLYFRMFMT)
-        {
-            if (aDrawFormats.find(rIndex) != aDrawFormats.end())
-                aTextBoxes.insert(pFormat);
-            else
-                aFlyFormats[rIndex] = pFormat;
-        }
-        else if (pFormat->Which() == RES_DRAWFRMFMT)
-        {
-            if (aFlyFormats.find(rIndex) != aFlyFormats.end())
-                aTextBoxes.insert(aFlyFormats[rIndex]);
-            else
-                aDrawFormats[rIndex] = pFormat;
-        }
+        if (pFormat->Which() == RES_FLYFRMFMT && nullptr != 
pFormat->GetOtherTextBoxFormat())
+            aTextBoxes.insert(pFormat);
     }
 
     return aTextBoxes;
@@ -197,7 +182,7 @@ std::set<const SwFrameFormat*> 
SwTextBoxHelper::findTextBoxes(const SwNode& rNod
         {
             for (SwAnchoredObject* pAnchoredObject : *pSortedObjs)
             {
-                SwFrameFormat* pTextBox = 
findTextBox(&pAnchoredObject->GetFrameFormat());
+                SwFrameFormat* pTextBox = 
getOtherTextBoxFormat(&pAnchoredObject->GetFrameFormat(), RES_DRAWFRMFMT);
                 if (pTextBox)
                     aRet.insert(pTextBox);
             }
@@ -217,7 +202,7 @@ std::map<SwFrameFormat*, SwFrameFormat*> 
SwTextBoxHelper::findShapes(const SwDoc
     const SwFrameFormats& rSpzFrameFormats = *pDoc->GetSpzFrameFormats();
     for (SwFrameFormat* pFormat : rSpzFrameFormats)
     {
-        SwFrameFormat* pTextBox = findTextBox(pFormat);
+        SwFrameFormat* pTextBox = getOtherTextBoxFormat(pFormat, 
RES_DRAWFRMFMT);
         if (pTextBox)
             aRet[pTextBox] = pFormat;
     }
@@ -303,11 +288,26 @@ sal_Int32 SwTextBoxHelper::getOrdNum(const SdrObject* 
pObject)
 
 void SwTextBoxHelper::getShapeWrapThrough(const SwFrameFormat* pTextBox, bool& 
rWrapThrough)
 {
-    std::map<SwFrameFormat*, SwFrameFormat*> aMap = 
findShapes(pTextBox->GetDoc());
-    auto it = aMap.find(const_cast<SwFrameFormat*>(pTextBox));
-    if (it != aMap.end())
-        // pTextBox is indeed a TextBox, it->second is its shape.
-        rWrapThrough = it->second->GetSurround().GetSurround() == 
SURROUND_THROUGHT;
+    SwFrameFormat *pShape = SwTextBoxHelper::getOtherTextBoxFormat(pTextBox, 
RES_FLYFRMFMT);
+    if (pShape)
+        rWrapThrough = pShape->GetSurround().GetSurround() == 
SURROUND_THROUGHT;
+}
+
+SwFrameFormat* SwTextBoxHelper::getOtherTextBoxFormat(const SwFrameFormat* 
pFormat, sal_uInt16 nType)
+{
+    if (!isTextBox(pFormat, nType))
+        return nullptr;
+    return pFormat->GetOtherTextBoxFormat();
+}
+
+SwFrameFormat* 
SwTextBoxHelper::getOtherTextBoxFormat(uno::Reference<drawing::XShape> xShape)
+{
+    SwXShape* pShape = dynamic_cast<SwXShape*>(xShape.get());
+    if (!pShape)
+        return nullptr;
+
+    SwFrameFormat *pFormat = pShape->GetFrameFormat();
+    return getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT);
 }
 
 SwFrameFormat* SwTextBoxHelper::findTextBox(const 
uno::Reference<drawing::XShape>& xShape)
@@ -345,7 +345,7 @@ SwFrameFormat* SwTextBoxHelper::findTextBox(const 
SwFrameFormat* pShape)
 template < typename T >
 void lcl_queryInterface(SwFrameFormat* pShape, uno::Any& rAny)
 {
-    if (SwFrameFormat* pFormat = SwTextBoxHelper::findTextBox(pShape))
+    if (SwFrameFormat* pFormat = 
SwTextBoxHelper::getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT))
     {
         uno::Reference<T> const xInterface(
             SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat),
@@ -423,7 +423,7 @@ void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, 
const OUString& rPrope
             syncProperty(pShape, RES_VERT_ORIENT, MID_VERTORIENT_POSITION, 
uno::makeAny(static_cast<sal_Int32>(convertTwipToMm100(aRectangle.Top()))));
         }
 
-        if (SwFrameFormat* pFormat = findTextBox(pShape))
+        if (SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, 
RES_DRAWFRMFMT))
         {
             comphelper::SequenceAsHashMap aCustomShapeGeometry(rValue);
             // That would be the btLr text direction which we don't support at 
a frame level, so do it at a character level.
@@ -457,7 +457,7 @@ void SwTextBoxHelper::getProperty(SwFrameFormat* pShape, 
sal_uInt16 nWID, sal_uI
 
     nMemberId &= ~CONVERT_TWIPS;
 
-    if (SwFrameFormat* pFormat = findTextBox(pShape))
+    if (SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT))
     {
         if (nWID == RES_CHAIN)
         {
@@ -487,7 +487,7 @@ void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, 
sal_uInt16 nWID, sal_u
     uno::Any aValue(rValue);
     nMemberId &= ~CONVERT_TWIPS;
 
-    if (SwFrameFormat* pFormat = findTextBox(pShape))
+    if (SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT))
     {
         OUString aPropertyName;
         bool bAdjustX = false;
@@ -628,9 +628,7 @@ void SwTextBoxHelper::saveLinks(const SwFrameFormats& 
rFormats, std::map<const S
     for (std::size_t i = 0; i < rFormats.size(); ++i)
     {
         const SwFrameFormat* pFormat = rFormats[i];
-        if (pFormat->Which() != RES_DRAWFRMFMT)
-            continue;
-        if (SwFrameFormat* pTextBox = findTextBox(pFormat))
+        if (SwFrameFormat* pTextBox = getOtherTextBoxFormat(pFormat, 
RES_DRAWFRMFMT))
             rLinks[pFormat] = pTextBox;
     }
 }
@@ -667,7 +665,7 @@ void SwTextBoxHelper::restoreLinks(std::set<ZSortFly>& 
rOld, std::vector<SwFrame
 
 void SwTextBoxHelper::syncFlyFrameAttr(SwFrameFormat& rShape, SfxItemSet& rSet)
 {
-    if (SwFrameFormat* pFormat = findTextBox(&rShape))
+    if (SwFrameFormat* pFormat = getOtherTextBoxFormat(&rShape, 
RES_DRAWFRMFMT))
     {
         SfxItemSet aTextBoxSet(pFormat->GetDoc()->GetAttrPool(), 
aFrameFormatSetRange);
 
diff --git a/sw/source/core/draw/dview.cxx b/sw/source/core/draw/dview.cxx
index 13c5f0c..763652f 100644
--- a/sw/source/core/draw/dview.cxx
+++ b/sw/source/core/draw/dview.cxx
@@ -948,7 +948,7 @@ void SwDrawView::DeleteMarked()
         SdrObject *pObject = rMarkList.GetMark(i)->GetMarkedSdrObj();
         SwDrawContact* pDrawContact = 
static_cast<SwDrawContact*>(GetUserCall(pObject));
         SwFrameFormat* pFormat = pDrawContact->GetFormat();
-        if (SwFrameFormat* pTextBox = SwTextBoxHelper::findTextBox(pFormat))
+        if (SwFrameFormat* pTextBox = 
SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT))
             aTextBoxesToDelete.push_back(pTextBox);
     }
 
diff --git a/sw/source/core/frmedt/feshview.cxx 
b/sw/source/core/frmedt/feshview.cxx
index 7d4b170..66302da 100644
--- a/sw/source/core/frmedt/feshview.cxx
+++ b/sw/source/core/frmedt/feshview.cxx
@@ -235,15 +235,13 @@ bool SwFEShell::SelectObj( const Point& rPt, sal_uInt8 
nFlag, SdrObject *pObj )
     if (!(nFlag & SW_ALLOW_TEXTBOX))
     {
         // If the fly frame is a textbox of a shape, then select the shape 
instead.
-        std::map<SwFrameFormat*, SwFrameFormat*> aTextBoxShapes = 
SwTextBoxHelper::findShapes(mpDoc);
         for (size_t i = 0; i < rMrkList.GetMarkCount(); ++i)
         {
             SdrObject* pObject = rMrkList.GetMark(i)->GetMarkedSdrObj();
-            SwContact* pDrawContact = GetUserCall(pObject);
-            SwFrameFormat* pFormat = pDrawContact->GetFormat();
-            if (aTextBoxShapes.find(pFormat) != aTextBoxShapes.end())
+            SwFrameFormat* pFormat = GetUserCall(pObject)->GetFormat();
+            if (SwFrameFormat* pShapeFormat = 
SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_FLYFRMFMT))
             {
-                SdrObject* pShape = aTextBoxShapes[pFormat]->FindSdrObject();
+                SdrObject* pShape = pShapeFormat->FindSdrObject();
                 pDView->UnmarkAll();
                 pDView->MarkObj(pShape, Imp()->GetPageView(), bAddSelect, 
bEnterGroup);
                 break;
diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx
index 0eff50c..310bf43 100644
--- a/sw/source/core/layout/fly.cxx
+++ b/sw/source/core/layout/fly.cxx
@@ -1288,11 +1288,10 @@ void SwFlyFrame::Format( vcl::RenderContext* 
/*pRenderContext*/, const SwBorderA
             }
             mbValidSize = true;
 
-            std::map<SwFrameFormat*, SwFrameFormat*> aShapes = 
SwTextBoxHelper::findShapes(GetFormat()->GetDoc());
-            if (aShapes.find(GetFormat()) != aShapes.end())
+            if (SwFrameFormat* pShapeFormat = 
SwTextBoxHelper::getOtherTextBoxFormat(GetFormat(), RES_FLYFRMFMT))
             {
                 // This fly is a textbox of a draw shape.
-                SdrObject* pShape = aShapes[GetFormat()]->FindSdrObject();
+                SdrObject* pShape = pShapeFormat->FindSdrObject();
                 if (SdrObjCustomShape* pCustomShape = 
dynamic_cast<SdrObjCustomShape*>( pShape) )
                 {
                     // The shape is a customshape: then inform it about the 
calculated fly size.
diff --git a/sw/source/core/text/porfly.cxx b/sw/source/core/text/porfly.cxx
index e38e99d..5903566 100644
--- a/sw/source/core/text/porfly.cxx
+++ b/sw/source/core/text/porfly.cxx
@@ -359,7 +359,7 @@ void SwFlyCntPortion::SetBase( const SwTextFrame& rFrame, 
const Point &rBase,
     if (rAnchor.GetAnchorId() == FLY_AS_CHAR)
     {
         // This is an inline draw shape, see if it has a textbox.
-        SwFrameFormat* pTextBox = SwTextBoxHelper::findTextBox(pShape);
+        SwFrameFormat* pTextBox = 
SwTextBoxHelper::getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT);
         if (pTextBox)
         {
             // It has, so look up its text rectangle, and adjust the position
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index d12977e..ee0ad84 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -5142,7 +5142,7 @@ void 
DocxAttributeOutput::WriteTextBox(uno::Reference<drawing::XShape> xShape)
     DocxTableExportContext aTableExportContext;
     pushToTableExportContext(aTableExportContext);
 
-    SwFrameFormat* pTextBox = SwTextBoxHelper::findTextBox(xShape);
+    SwFrameFormat* pTextBox = SwTextBoxHelper::getOtherTextBoxFormat(xShape);
     const SwPosition* pAnchor = pTextBox->GetAnchor().GetContentAnchor();
     ww8::Frame aFrame(*pTextBox, *pAnchor);
     m_rExport.SdrExporter().writeDMLTextFrame(&aFrame, m_anchorId++, 
/*bTextBoxOnly=*/true);
@@ -5155,7 +5155,7 @@ void 
DocxAttributeOutput::WriteVMLTextBox(uno::Reference<drawing::XShape> xShape
     DocxTableExportContext aTableExportContext;
     pushToTableExportContext(aTableExportContext);
 
-    SwFrameFormat* pTextBox = SwTextBoxHelper::findTextBox(xShape);
+    SwFrameFormat* pTextBox = SwTextBoxHelper::getOtherTextBoxFormat(xShape);
     const SwPosition* pAnchor = pTextBox->GetAnchor().GetContentAnchor();
     ww8::Frame aFrame(*pTextBox, *pAnchor);
     m_rExport.SdrExporter().writeVMLTextFrame(&aFrame, /*bTextBoxOnly=*/true);
diff --git a/sw/source/filter/ww8/rtfsdrexport.cxx 
b/sw/source/filter/ww8/rtfsdrexport.cxx
index d7a0506..ccaf688 100644
--- a/sw/source/filter/ww8/rtfsdrexport.cxx
+++ b/sw/source/filter/ww8/rtfsdrexport.cxx
@@ -39,8 +39,7 @@ RtfSdrExport::RtfSdrExport(RtfExport& rExport)
       m_nShapeType(ESCHER_ShpInst_Nil),
       m_nShapeFlags(0) ,
       m_aShapeStyle(200),
-      m_pShapeTypeWritten(new bool[ ESCHER_ShpInst_COUNT ]),
-      m_aTextBoxes(SwTextBoxHelper::findTextBoxes(m_rExport.m_pDoc))
+      m_pShapeTypeWritten(new bool[ ESCHER_ShpInst_COUNT ])
 {
     mnGroupLevel = 1;
     memset(m_pShapeTypeWritten, 0, ESCHER_ShpInst_COUNT * sizeof(bool));
@@ -514,7 +513,7 @@ sal_Int32 RtfSdrExport::StartShape()
     const SwFrameFormat* pShape = FindFrameFormat(m_pSdrObject);
     if (pShape)
     {
-        if (SwFrameFormat* pTextBox = SwTextBoxHelper::findTextBox(pShape))
+        if (SwFrameFormat* pTextBox = 
SwTextBoxHelper::getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT))
         {
             ww8::Frame* pFrame = nullptr;
             for (auto& rFrame : m_rExport.m_aFrames)
diff --git a/sw/source/filter/ww8/rtfsdrexport.hxx 
b/sw/source/filter/ww8/rtfsdrexport.hxx
index a5b3273..f62d093 100644
--- a/sw/source/filter/ww8/rtfsdrexport.hxx
+++ b/sw/source/filter/ww8/rtfsdrexport.hxx
@@ -56,9 +56,6 @@ class RtfSdrExport : public EscherEx
     /// Remember which shape types we had already written.
     bool* m_pShapeTypeWritten;
 
-    /// List of TextBoxes in this document: they are exported as part of their 
shape, never alone.
-    std::set<const SwFrameFormat*> m_aTextBoxes;
-
 public:
     explicit RtfSdrExport(RtfExport& rExport);
     virtual             ~RtfSdrExport();
diff --git a/sw/source/uibase/docvw/edtwin.cxx 
b/sw/source/uibase/docvw/edtwin.cxx
index 37e41b1..4990f5c 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -204,7 +204,7 @@ static bool lcl_goIntoTextBox(SwEditWin& rEditWin, 
SwWrtShell& rSh)
 {
     SdrObject* pSdrObject = 
rSh.GetDrawView()->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
     SwFrameFormat* pObjectFormat = ::FindFrameFormat(pSdrObject);
-    if (SwFrameFormat* pTextBoxFormat = 
SwTextBoxHelper::findTextBox(pObjectFormat))
+    if (SwFrameFormat* pTextBoxFormat = 
SwTextBoxHelper::getOtherTextBoxFormat(pObjectFormat, RES_DRAWFRMFMT))
     {
         SdrObject* pTextBox = pTextBoxFormat->FindRealSdrObject();
         SdrView* pSdrView = rSh.GetDrawView();
@@ -4391,10 +4391,9 @@ void SwEditWin::MouseButtonUp(const MouseEvent& rMEvt)
             SdrPageView* pPV;
             if (pSdrView && pSdrView->PickObj(aDocPos, 
pSdrView->getHitTolLog(), pObj, pPV, SdrSearchOptions::ALSOONMASTER ))
             {
-                std::map<SwFrameFormat*, SwFrameFormat*> aTextBoxShapes = 
SwTextBoxHelper::findShapes(rSh.GetDoc());
-                auto pDrawContact = GetUserCall(pObj);
-                SwFrameFormat* pFormat = pDrawContact->GetFormat();
-                if (aTextBoxShapes.find(pFormat) == aTextBoxShapes.end())
+                SwFrameFormat* pFormat = GetUserCall(pObj)->GetFormat();
+                SwFrameFormat* pShapeFormat = 
SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_FLYFRMFMT);
+                if (!pShapeFormat)
                 {
                     pSdrView->UnmarkAllObj();
                     pSdrView->MarkObj(pObj,pPV);
@@ -4402,7 +4401,7 @@ void SwEditWin::MouseButtonUp(const MouseEvent& rMEvt)
                 else
                 {
                     // If the fly frame is a textbox of a shape, then select 
the shape instead.
-                    SdrObject* pShape = 
aTextBoxShapes[pFormat]->FindSdrObject();
+                    SdrObject* pShape = pShapeFormat->FindSdrObject();
                     pSdrView->UnmarkAllObj();
                     pSdrView->MarkObj(pShape, pPV);
                 }
commit 0bcc5b3daebeb2a7d2b5ba132af4745cc6c78cd0
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Fri Jul 22 17:50:52 2016 +0200

    Switch isTextBox to use the format pointers
    
    This replaces all possible occurences of the text box format
    maps, which just want to know, if a SwFrameFormat is part of a
    text box to use the direct lookup via the isTextBox, which is
    now a cheap call.
    
    Change-Id: I3b4e2301f816aead1b719cd70a8ef118e685ccfc

diff --git a/sw/inc/textboxhelper.hxx b/sw/inc/textboxhelper.hxx
index cce1796..eb94bbc 100644
--- a/sw/inc/textboxhelper.hxx
+++ b/sw/inc/textboxhelper.hxx
@@ -68,6 +68,19 @@ public:
     /// Return the textbox rectangle of a draw shape (in twips).
     static Rectangle getTextRectangle(SwFrameFormat* pShape, bool bAbsolute = 
true);
 
+    /**
+     * Is the frame format a text box?
+     *
+     * A text box consists of a coupled fly and draw format. Most times you
+     * just want to check for a single type, otherwise you get duplicate 
results.
+     *
+     * @param nType Expected frame format input type.
+     *              Valid types are RES_DRAWFRMFMT and RES_FLYFRMFMT.
+     */
+    static bool isTextBox(const SwFrameFormat* pFormat, sal_uInt16 nType);
+    /// Is pObject a textbox of a drawinglayer shape?
+    static bool isTextBox(const SdrObject* pObject);
+
     /// Look up TextFrames in a document, which are in fact TextBoxes.
     static std::set<const SwFrameFormat*> findTextBoxes(const SwDoc* pDoc);
     /**
@@ -77,16 +90,16 @@ public:
      * returned.
      */
     static std::set<const SwFrameFormat*> findTextBoxes(const SwNode& rNode);
-    /// Is pObject a textbox of a drawinglayer shape?
-    static bool isTextBox(const SdrObject* pObject);
     /// Build a textbox -> shape format map.
     static std::map<SwFrameFormat*, SwFrameFormat*> findShapes(const SwDoc* 
pDoc);
     /// Count number of shapes in the document, excluding TextBoxes.
-    static sal_Int32 getCount(SdrPage* pPage, std::set<const SwFrameFormat*>& 
rTextBoxes);
+    static sal_Int32 getCount(const SwDoc* pDoc);
+    /// Count number of shapes on the page, excluding TextBoxes.
+    static sal_Int32 getCount(SdrPage* pPage);
     /// Get a shape by index, excluding TextBoxes.
-    static css::uno::Any getByIndex(SdrPage* pPage, sal_Int32 nIndex, 
std::set<const SwFrameFormat*>& rTextBoxes) 
throw(css::lang::IndexOutOfBoundsException);
+    static css::uno::Any getByIndex(SdrPage* pPage, sal_Int32 nIndex) 
throw(css::lang::IndexOutOfBoundsException);
     /// Get the order of the shape, excluding TextBoxes.
-    static sal_Int32 getOrdNum(const SdrObject* pObject, std::set<const 
SwFrameFormat*>& rTextBoxes);
+    static sal_Int32 getOrdNum(const SdrObject* pObject);
     /// If pTextBox is a textbox, then set rWrapThrough to the surround of its 
shape.
     static void getShapeWrapThrough(const SwFrameFormat* pTextBox, bool& 
rWrapThrough);
 
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx 
b/sw/qa/extras/uiwriter/uiwriter.cxx
index e6f851c..6e9341e 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -856,9 +856,8 @@ void SwUiWriterTest::testFdo82191()
 {
     SwDoc* pDoc = createDoc("fdo82191.odt");
     SdrPage* pPage = 
pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
-    std::set<const SwFrameFormat*> aTextBoxes = 
SwTextBoxHelper::findTextBoxes(pDoc);
     // Make sure we have a single draw shape.
-    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), SwTextBoxHelper::getCount(pPage, 
aTextBoxes));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), SwTextBoxHelper::getCount(pPage));
 
     SwDoc aClipboard;
     SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
@@ -868,9 +867,8 @@ void SwUiWriterTest::testFdo82191()
     pWrtShell->Copy(&aClipboard);
     pWrtShell->Paste(&aClipboard);
 
-    aTextBoxes = SwTextBoxHelper::findTextBoxes(pDoc);
     // This was one: the textbox of the shape wasn't copied.
-    CPPUNIT_ASSERT_EQUAL(size_t(2), aTextBoxes.size());
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), SwTextBoxHelper::getCount(pDoc));
 }
 
 void SwUiWriterTest::testCommentedWord()
@@ -3446,15 +3444,20 @@ void SwUiWriterTest::testTdf92648()
 {
     SwDoc* pDoc = createDoc("tdf92648.docx");
     SdrPage* pPage = 
pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
-    std::set<const SwFrameFormat*> aTextBoxes = 
SwTextBoxHelper::findTextBoxes(pDoc);
     // Make sure we have ten draw shapes.
-    CPPUNIT_ASSERT_EQUAL(sal_Int32(10), SwTextBoxHelper::getCount(pPage, 
aTextBoxes));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(10), SwTextBoxHelper::getCount(pPage));
     // and the text boxes haven't got zero height
-    for (std::set<const SwFrameFormat*>::iterator it=aTextBoxes.begin(); 
it!=aTextBoxes.end(); ++it)
+    sal_Int32 nCount = 0;
+    for (const SwFrameFormat* pFormat : *pDoc->GetSpzFrameFormats())
     {
-        SwFormatFrameSize aSize((*it)->GetFrameSize());
+        if (!SwTextBoxHelper::isTextBox(pFormat, RES_FLYFRMFMT))
+            continue;
+        SwFormatFrameSize aSize(pFormat->GetFrameSize());
         CPPUNIT_ASSERT(aSize.GetHeight() != 0);
+        ++nCount;
     }
+    // and we have had five of them.
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(5), nCount);
 }
 
 void SwUiWriterTest::testTdf96515()
diff --git a/sw/source/core/doc/docfly.cxx b/sw/source/core/doc/docfly.cxx
index e1291b6..98ffdae 100644
--- a/sw/source/core/doc/docfly.cxx
+++ b/sw/source/core/doc/docfly.cxx
@@ -79,15 +79,11 @@ size_t SwDoc::GetFlyCount( FlyCntType eType, bool 
bIgnoreTextBoxes ) const
     size_t nCount = 0;
     const SwNodeIndex* pIdx;
 
-    std::set<const SwFrameFormat*> aTextBoxes;
-    if (bIgnoreTextBoxes)
-        aTextBoxes = SwTextBoxHelper::findTextBoxes(this);
-
     for ( size_t i = 0; i < nSize; ++i)
     {
         const SwFrameFormat* pFlyFormat = rFormats[ i ];
 
-        if (bIgnoreTextBoxes && aTextBoxes.find(pFlyFormat) != 
aTextBoxes.end())
+        if (bIgnoreTextBoxes && SwTextBoxHelper::isTextBox(pFlyFormat, 
RES_FLYFRMFMT))
             continue;
 
         if( RES_FLYFRMFMT == pFlyFormat->Which()
@@ -131,15 +127,11 @@ SwFrameFormat* SwDoc::GetFlyNum( size_t nIdx, FlyCntType 
eType, bool bIgnoreText
     const SwNodeIndex* pIdx;
     size_t nCount = 0;
 
-    std::set<const SwFrameFormat*> aTextBoxes;
-    if (bIgnoreTextBoxes)
-        aTextBoxes = SwTextBoxHelper::findTextBoxes(this);
-
     for( size_t i = 0; !pRetFormat && i < nSize; ++i )
     {
         SwFrameFormat* pFlyFormat = rFormats[ i ];
 
-        if (bIgnoreTextBoxes && aTextBoxes.find(pFlyFormat) != 
aTextBoxes.end())
+        if (bIgnoreTextBoxes && SwTextBoxHelper::isTextBox(pFlyFormat, 
RES_FLYFRMFMT))
             continue;
 
         if( RES_FLYFRMFMT == pFlyFormat->Which()
@@ -177,10 +169,6 @@ std::vector<SwFrameFormat const*> 
SwDoc::GetFlyFrameFormats(
     SwFrameFormats& rFormats = *GetSpzFrameFormats();
     const size_t nSize = rFormats.size();
 
-    std::set<const SwFrameFormat*> aTextBoxes;
-    if (bIgnoreTextBoxes)
-        aTextBoxes = SwTextBoxHelper::findTextBoxes(this);
-
     std::vector<SwFrameFormat const*> ret;
     ret.reserve(nSize);
 
@@ -188,7 +176,7 @@ std::vector<SwFrameFormat const*> SwDoc::GetFlyFrameFormats(
     {
         SwFrameFormat const*const pFlyFormat = rFormats[ i ];
 
-        if (bIgnoreTextBoxes && aTextBoxes.find(pFlyFormat) != 
aTextBoxes.end())
+        if (bIgnoreTextBoxes && SwTextBoxHelper::isTextBox(pFlyFormat, 
RES_FLYFRMFMT))
         {
             continue;
         }
diff --git a/sw/source/core/doc/textboxhelper.cxx 
b/sw/source/core/doc/textboxhelper.cxx
index ce18cd0..b180366 100644
--- a/sw/source/core/doc/textboxhelper.cxx
+++ b/sw/source/core/doc/textboxhelper.cxx
@@ -160,6 +160,28 @@ std::set<const SwFrameFormat*> 
SwTextBoxHelper::findTextBoxes(const SwDoc* pDoc)
     return aTextBoxes;
 }
 
+bool SwTextBoxHelper::isTextBox(const SwFrameFormat* pShape, sal_uInt16 nType)
+{
+   assert(nType == RES_FLYFRMFMT || nType == RES_DRAWFRMFMT);
+   if (!pShape || pShape->Which() != nType || 
!pShape->GetAttrSet().HasItem(RES_CNTNT))
+       return false;
+
+   sal_uInt16 nOtherType = (pShape->Which() == RES_FLYFRMFMT) ? RES_DRAWFRMFMT 
: RES_FLYFRMFMT;
+   SwFrameFormat* pFormat = pShape->GetOtherTextBoxFormat();
+   if (!pFormat)
+       return false;
+
+   assert(pFormat->Which() == nOtherType);
+   if (pFormat->Which() != nOtherType)
+       return false;
+
+   const SwFormatContent& rContent = pShape->GetContent();
+   if (!pFormat->GetAttrSet().HasItem(RES_CNTNT) || pFormat->GetContent() != 
rContent)
+       return false;
+
+   return true;
+}
+
 std::set<const SwFrameFormat*> SwTextBoxHelper::findTextBoxes(const SwNode& 
rNode)
 {
     const SwDoc* pDoc = rNode.GetDoc();
@@ -203,35 +225,39 @@ std::map<SwFrameFormat*, SwFrameFormat*> 
SwTextBoxHelper::findShapes(const SwDoc
     return aRet;
 }
 
-/// If the passed SdrObject is in fact a TextFrame, that is used as a TextBox.
-bool lcl_isTextBox(SdrObject* pSdrObject, std::set<const SwFrameFormat*>& 
rTextBoxes)
-{
-    SwVirtFlyDrawObj* pObject = dynamic_cast<SwVirtFlyDrawObj*>(pSdrObject);
-    return pObject && rTextBoxes.find(pObject->GetFormat()) != 
rTextBoxes.end();
-}
-
 bool SwTextBoxHelper::isTextBox(const SdrObject* pObject)
 {
     const SwVirtFlyDrawObj* pVirtFlyDrawObj = dynamic_cast<const 
SwVirtFlyDrawObj*>(pObject);
     if (!pVirtFlyDrawObj)
         return false;
-    std::set<const SwFrameFormat*> aTextBoxes = 
findTextBoxes(pVirtFlyDrawObj->GetFormat()->GetDoc());
-    return aTextBoxes.find(pVirtFlyDrawObj->GetFormat()) != aTextBoxes.end();
+    return isTextBox(pVirtFlyDrawObj->GetFormat(), RES_FLYFRMFMT);
 }
 
-sal_Int32 SwTextBoxHelper::getCount(SdrPage* pPage, std::set<const 
SwFrameFormat*>& rTextBoxes)
+sal_Int32 SwTextBoxHelper::getCount(SdrPage* pPage)
 {
     sal_Int32 nRet = 0;
     for (std::size_t i = 0; i < pPage->GetObjCount(); ++i)
     {
-        if (lcl_isTextBox(pPage->GetObj(i), rTextBoxes))
+        if (isTextBox(pPage->GetObj(i)))
             continue;
         ++nRet;
     }
     return nRet;
 }
 
-uno::Any SwTextBoxHelper::getByIndex(SdrPage* pPage, sal_Int32 nIndex, 
std::set<const SwFrameFormat*>& rTextBoxes) 
throw(lang::IndexOutOfBoundsException)
+sal_Int32 SwTextBoxHelper::getCount(const SwDoc* pDoc)
+{
+    sal_Int32 nRet = 0;
+    const SwFrameFormats& rSpzFrameFormats = *pDoc->GetSpzFrameFormats();
+    for (SwFrameFormats::const_iterator it = rSpzFrameFormats.begin(); it != 
rSpzFrameFormats.end(); ++it)
+    {
+        if (isTextBox(*it, RES_FLYFRMFMT))
+            ++nRet;
+    }
+    return nRet;
+}
+
+uno::Any SwTextBoxHelper::getByIndex(SdrPage* pPage, sal_Int32 nIndex) 
throw(lang::IndexOutOfBoundsException)
 {
     if (nIndex < 0)
         throw lang::IndexOutOfBoundsException();
@@ -240,7 +266,7 @@ uno::Any SwTextBoxHelper::getByIndex(SdrPage* pPage, 
sal_Int32 nIndex, std::set<
     sal_Int32 nCount = 0; // Current logical index.
     for (std::size_t i = 0; i < pPage->GetObjCount(); ++i)
     {
-        if (lcl_isTextBox(pPage->GetObj(i), rTextBoxes))
+        if (isTextBox(pPage->GetObj(i)))
             continue;
         if (nCount == nIndex)
         {
@@ -256,14 +282,14 @@ uno::Any SwTextBoxHelper::getByIndex(SdrPage* pPage, 
sal_Int32 nIndex, std::set<
     return uno::makeAny(uno::Reference<drawing::XShape>(pRet->getUnoShape(), 
uno::UNO_QUERY));
 }
 
-sal_Int32 SwTextBoxHelper::getOrdNum(const SdrObject* pObject, std::set<const 
SwFrameFormat*>& rTextBoxes)
+sal_Int32 SwTextBoxHelper::getOrdNum(const SdrObject* pObject)
 {
     if (const SdrPage* pPage = pObject->GetPage())
     {
         sal_Int32 nOrder = 0; // Current logical order.
         for (std::size_t i = 0; i < pPage->GetObjCount(); ++i)
         {
-            if (lcl_isTextBox(pPage->GetObj(i), rTextBoxes))
+            if (isTextBox(pPage->GetObj(i)))
                 continue;
             if (pPage->GetObj(i) == pObject)
                 return nOrder;
diff --git a/sw/source/core/draw/dcontact.cxx b/sw/source/core/draw/dcontact.cxx
index 7001945..6c60a8b 100644
--- a/sw/source/core/draw/dcontact.cxx
+++ b/sw/source/core/draw/dcontact.cxx
@@ -1151,7 +1151,7 @@ class NestedUserCallHdl
 /// Notify the format's textbox that it should reconsider its position / size.
 void lcl_textBoxSizeNotify(SwFrameFormat* pFormat)
 {
-    if (SwTextBoxHelper::findTextBox(pFormat))
+    if (SwTextBoxHelper::isTextBox(pFormat, RES_DRAWFRMFMT))
     {
         // Just notify the textbox that the size has changed, the actual 
object size is not interesting.
         SfxItemSet aResizeSet(pFormat->GetDoc()->GetAttrPool(), RES_FRM_SIZE, 
RES_FRM_SIZE, 0);
diff --git a/sw/source/core/frmedt/fecopy.cxx b/sw/source/core/frmedt/fecopy.cxx
index 277a0b6..0c65476 100644
--- a/sw/source/core/frmedt/fecopy.cxx
+++ b/sw/source/core/frmedt/fecopy.cxx
@@ -902,7 +902,6 @@ bool SwFEShell::Paste( SwDoc* pClpDoc )
                 if( !Imp()->GetDrawView() )
                     MakeDrawView();
 
-                std::set<const SwFrameFormat*> aTextBoxes = 
SwTextBoxHelper::findTextBoxes(pClpDoc);
                 for ( auto pCpyFormat : *pClpDoc->GetSpzFrameFormats() )
                 {
                     bool bInsWithFormat = true;
@@ -972,7 +971,7 @@ bool SwFEShell::Paste( SwDoc* pClpDoc )
                             }
 
                             // Ignore TextBoxes, they are already handled in 
sw::DocumentLayoutManager::CopyLayoutFormat().
-                            if (aTextBoxes.find(pCpyFormat) != 
aTextBoxes.end())
+                            if (SwTextBoxHelper::isTextBox(pCpyFormat, 
RES_FLYFRMFMT))
                                 continue;
 
                             aAnchor.SetAnchor( pPos );
diff --git a/sw/source/core/objectpositioning/anchoredobjectposition.cxx 
b/sw/source/core/objectpositioning/anchoredobjectposition.cxx
index 1cf2c0f..9488a4b 100644
--- a/sw/source/core/objectpositioning/anchoredobjectposition.cxx
+++ b/sw/source/core/objectpositioning/anchoredobjectposition.cxx
@@ -501,7 +501,7 @@ SwTwips SwAnchoredObjectPosition::ImplAdjustVertRelPos( 
const SwTwips nTopOfAnch
                     pFrameFormat->SetFormatAttr(aSize);
                 }
                 nAdjustedRelPosY = nProposedRelPosY;
-            } else if ( SwTextBoxHelper::findTextBox(pFormat) )
+            } else if ( SwTextBoxHelper::isTextBox(pFormat, RES_DRAWFRMFMT) )
                 // when the shape has a textbox, use only the proposed 
vertical position
                 nAdjustedRelPosY = nProposedRelPosY;
         }
diff --git a/sw/source/core/unocore/unocoll.cxx 
b/sw/source/core/unocore/unocoll.cxx
index 44e7b63..79d3859 100644
--- a/sw/source/core/unocore/unocoll.cxx
+++ b/sw/source/core/unocore/unocoll.cxx
@@ -1088,13 +1088,11 @@ SwXFrameEnumeration<T>::SwXFrameEnumeration(const 
SwDoc* const pDoc)
     // #i104937#
     SwFrameFormat* pFormat( nullptr );
 
-    std::set<const SwFrameFormat*> aTextBoxes = 
SwTextBoxHelper::findTextBoxes(pDoc);
-
     for( size_t i = 0; i < nSize; ++i )
     {
         // #i104937#
         pFormat = (*pFormats)[i];
-        if(pFormat->Which() != RES_FLYFRMFMT || aTextBoxes.find(pFormat) != 
aTextBoxes.end())
+        if(pFormat->Which() != RES_FLYFRMFMT || 
SwTextBoxHelper::isTextBox(pFormat, RES_FLYFRMFMT))
             continue;
         const SwNodeIndex* pIdx =  pFormat->GetContent().GetContentIdx();
         if(!pIdx || !pIdx->GetNodes().IsDocNodes())
diff --git a/sw/source/core/unocore/unodraw.cxx 
b/sw/source/core/unocore/unodraw.cxx
index f3d7cf5..846fe42 100644
--- a/sw/source/core/unocore/unodraw.cxx
+++ b/sw/source/core/unocore/unodraw.cxx
@@ -397,10 +397,9 @@ SwXShapesEnumeration::SwXShapesEnumeration(SwXDrawPage* 
const pDrawPage)
     SolarMutexGuard aGuard;
     std::insert_iterator<shapescontainer_t> pInserter = 
std::insert_iterator<shapescontainer_t>(m_aShapes, m_aShapes.begin());
     sal_Int32 nCount = pDrawPage->getCount();
-    std::set<const SwFrameFormat*> aTextBoxes = 
SwTextBoxHelper::findTextBoxes(pDrawPage->GetDoc());
     for(sal_Int32 nIdx = 0; nIdx < nCount; nIdx++)
     {
-        uno::Reference<drawing::XShape> xShape(pDrawPage->getByIndex(nIdx, 
&aTextBoxes), uno::UNO_QUERY);
+        uno::Reference<drawing::XShape> xShape(pDrawPage->getByIndex(nIdx), 
uno::UNO_QUERY);
         *pInserter++ = uno::makeAny(xShape);
     }
 }
@@ -523,13 +522,7 @@ sal_Int32 SwXDrawPage::getCount() throw( 
uno::RuntimeException, std::exception )
     else
     {
         GetSvxPage();
-
-        std::set<const SwFrameFormat*> aTextBoxes = 
SwTextBoxHelper::findTextBoxes(pDoc);
-
-        if (aTextBoxes.empty())
-            return pDrawPage->getCount();
-        else
-            return SwTextBoxHelper::getCount(pDrawPage->GetSdrPage(), 
aTextBoxes);
+        return SwTextBoxHelper::getCount(pDrawPage->GetSdrPage());
     }
 }
 
@@ -537,12 +530,6 @@ uno::Any SwXDrawPage::getByIndex(sal_Int32 nIndex)
         throw( lang::IndexOutOfBoundsException, lang::WrappedTargetException,
                uno::RuntimeException, std::exception )
 {
-    return getByIndex(nIndex, nullptr);
-}
-
-uno::Any SwXDrawPage::getByIndex(sal_Int32 nIndex, std::set<const 
SwFrameFormat*>* pTextBoxes)
-    throw(lang::IndexOutOfBoundsException, lang::WrappedTargetException, 
uno::RuntimeException, std::exception)
-{
     SolarMutexGuard aGuard;
     if(!pDoc)
         throw uno::RuntimeException();
@@ -550,17 +537,7 @@ uno::Any SwXDrawPage::getByIndex(sal_Int32 nIndex, 
std::set<const SwFrameFormat*
         throw lang::IndexOutOfBoundsException();
 
     GetSvxPage();
-    std::set<const SwFrameFormat*> aTextBoxes;
-    if (!pTextBoxes)
-    {
-        // We got no set, so let's generate one.
-        aTextBoxes = SwTextBoxHelper::findTextBoxes(pDoc);
-        pTextBoxes = &aTextBoxes;
-    }
-    if (pTextBoxes->empty())
-        return pDrawPage->getByIndex( nIndex );
-    else
-        return SwTextBoxHelper::getByIndex(pDrawPage->GetSdrPage(), nIndex, 
*pTextBoxes);
+    return SwTextBoxHelper::getByIndex(pDrawPage->GetSdrPage(), nIndex);
 }
 
 uno::Type  SwXDrawPage::getElementType() throw( uno::RuntimeException, 
std::exception )
@@ -1554,7 +1531,7 @@ uno::Any SwXShape::getPropertyValue(const OUString& 
rPropertyName)
                 }
                 else if (pEntry->nWID == FN_TEXT_BOX)
                 {
-                    bool bValue = SwTextBoxHelper::findTextBox(pFormat);
+                    bool bValue = SwTextBoxHelper::isTextBox(pFormat, 
RES_DRAWFRMFMT);
                     aRet <<= bValue;
                 }
                 else if (pEntry->nWID == RES_CHAIN)
@@ -1759,8 +1736,7 @@ uno::Any SwXShape::getPropertyValue(const OUString& 
rPropertyName)
                                 bConvert = false;
                         if (bConvert)
                         {
-                            std::set<const SwFrameFormat*> aTextBoxes = 
SwTextBoxHelper::findTextBoxes(pFormat->GetDoc());
-                            aRet <<= SwTextBoxHelper::getOrdNum(pObj, 
aTextBoxes);
+                            aRet <<= SwTextBoxHelper::getOrdNum(pObj);
                         }
                     }
                 }
@@ -1840,7 +1816,7 @@ uno::Sequence< beans::PropertyState > 
SwXShape::getPropertyStates(
                 else if (pEntry->nWID == FN_TEXT_BOX)
                 {
                     // The TextBox property is set, if we can find a textbox 
for this shape.
-                    if (pFormat && SwTextBoxHelper::findTextBox(pFormat))
+                    if (pFormat && SwTextBoxHelper::isTextBox(pFormat, 
RES_DRAWFRMFMT))
                         pRet[nProperty] = beans::PropertyState_DIRECT_VALUE;
                     else
                         pRet[nProperty] = beans::PropertyState_DEFAULT_VALUE;
diff --git a/sw/source/core/unocore/unoframe.cxx 
b/sw/source/core/unocore/unoframe.cxx
index cca3207..656d868 100644
--- a/sw/source/core/unocore/unoframe.cxx
+++ b/sw/source/core/unocore/unoframe.cxx
@@ -1751,8 +1751,7 @@ void SwXFrame::setPropertyValue(const OUString& 
rPropertyName, const ::uno::Any&
             aValue >>= nZOrder;
 
             // Don't set an explicit ZOrder on TextBoxes.
-            std::set<const SwFrameFormat*> aTextBoxes = 
SwTextBoxHelper::findTextBoxes(pDoc);
-            if( nZOrder >= 0 && aTextBoxes.find(pFormat) == aTextBoxes.end())
+            if( nZOrder >= 0 && !SwTextBoxHelper::isTextBox(pFormat, 
RES_FLYFRMFMT) )
             {
                 SdrObject* pObject =
                     GetOrCreateSdrObject( 
static_cast<SwFlyFrameFormat&>(*pFormat) );
diff --git a/sw/source/core/unocore/unoobj2.cxx 
b/sw/source/core/unocore/unoobj2.cxx
index 8c43ba7..ee4e4e9 100644
--- a/sw/source/core/unocore/unoobj2.cxx
+++ b/sw/source/core/unocore/unoobj2.cxx
@@ -165,19 +165,18 @@ struct FrameClientSortListLess
 
 namespace
 {
-    void lcl_CollectFrameAtNodeWithLayout(SwDoc* pDoc, const SwContentFrame* 
pCFrame,
+    void lcl_CollectFrameAtNodeWithLayout(const SwContentFrame* pCFrame,
             FrameClientSortList_t& rFrames,
             const sal_uInt16 nAnchorType)
     {
         auto pObjs = pCFrame->GetDrawObjs();
         if(!pObjs)
             return;
-        const auto aTextBoxes = SwTextBoxHelper::findTextBoxes(pDoc);
         for(const auto pAnchoredObj : *pObjs)
         {
             SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat();
             // Filter out textboxes, which are not interesting at an UNO level.
-            if(aTextBoxes.find(&rFormat) != aTextBoxes.end())
+            if(SwTextBoxHelper::isTextBox(&rFormat, RES_FLYFRMFMT))
                 continue;
             if(rFormat.GetAnchor().GetAnchorId() == nAnchorType)
             {
@@ -211,7 +210,7 @@ void CollectFrameAtNode( const SwNodeIndex& rIdx,
         nullptr != (pCNd = rIdx.GetNode().GetContentNode()) &&
         nullptr != (pCFrame = pCNd->getLayoutFrame( 
pDoc->getIDocumentLayoutAccess().GetCurrentLayout())) )
     {
-        lcl_CollectFrameAtNodeWithLayout(pDoc, pCFrame, rFrames, nChkType);
+        lcl_CollectFrameAtNodeWithLayout(pCFrame, rFrames, nChkType);
     }
     else
     {
diff --git a/sw/source/core/unocore/unoportenum.cxx 
b/sw/source/core/unocore/unoportenum.cxx
index 07fe139..eac6691 100644
--- a/sw/source/core/unocore/unoportenum.cxx
+++ b/sw/source/core/unocore/unoportenum.cxx
@@ -716,8 +716,7 @@ lcl_ExportHints(
     const sal_Int32 nCurrentIndex,
     const bool bRightMoveForbidden,
     bool & o_rbCursorMoved,
-    sal_Int32 & o_rNextAttrPosition,
-    std::set<const SwFrameFormat*>& rTextBoxes)
+    sal_Int32 & o_rNextAttrPosition)
 {
     // if the attribute has a dummy character, then xRef is set (except META)
     // otherwise, the portion for the attribute is inserted into rPortions!
@@ -887,7 +886,7 @@ lcl_ExportHints(
                             break; // Robust #i81708 content in covered cells
 
                         // Do not expose inline anchored textboxes.
-                        if 
(rTextBoxes.find(pAttr->GetFlyCnt().GetFrameFormat()) != rTextBoxes.end())
+                        if 
(SwTextBoxHelper::isTextBox(pAttr->GetFlyCnt().GetFrameFormat(), RES_FLYFRMFMT))
                             break;
 
                         pUnoCursor->Exchange();
@@ -1272,8 +1271,6 @@ static void lcl_CreatePortions(
     PortionStack_t PortionStack;
     PortionStack.push( PortionList_t(&i_rPortions, nullptr) );
 
-    std::set<const SwFrameFormat*> aTextBoxes = 
SwTextBoxHelper::findTextBoxes(pUnoCursor->GetNode());
-
     bool bAtEnd( false );
     while (!bAtEnd) // every iteration consumes at least current character!
     {
@@ -1324,7 +1321,7 @@ static void lcl_CreatePortions(
             // N.B.: side-effects nNextAttrIndex, bCursorMoved; may move cursor
             xRef = lcl_ExportHints(PortionStack, i_xParentText, pUnoCursor,
                         pHints, i_nStartPos, i_nEndPos, nCurrentIndex, bAtEnd,

... etc. - the rest is truncated
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to