sw/qa/core/layout/data/page-remove-fly-table.odt |binary
 sw/qa/core/layout/layout.cxx                     |   38 +++++++++++++++++++++++
 sw/qa/uibase/wrtsh/wrtsh.cxx                     |    7 ++++
 sw/source/core/layout/flylay.cxx                 |   11 ++++++
 sw/source/core/txtnode/attrcontentcontrol.cxx    |    1 
 sw/source/uibase/wrtsh/wrtsh1.cxx                |   14 ++++++++
 sw/source/uibase/wrtsh/wrtsh3.cxx                |    4 --
 7 files changed, 70 insertions(+), 5 deletions(-)

New commits:
commit 18f259482782a3b3c44e01ca6ea0e98fe00973a0
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri Dec 9 16:52:48 2022 +0100
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Wed Dec 14 08:48:32 2022 +0000

    sw layout: invalidate margins of body content when moving a fly from page
    
    The (simplified) bugdoc has 9 pages, and once the ToC is updated, the
    two tables below the (only) bookmark in the document has a 5879 twips
    gap between them for no reason. Adding a new paragraph to the second
    table "fixes" the incremental layout.
    
    What seems to happen is that there is an anchored image on page 8, but
    the layout decides that it doesn't fit there so it gets moved to page 9.
    Before this move happens, SwTabFrame::Format() handles the outer of the
    nested table below the unwanted gap and its CalcFlyOffsets() notices
    that a large upper margin is wanted so that the table wraps around the
    anchored image. Later the image gets moved to the next page, but the
    removal doesn't invalidate the print area of the table with the large
    top margin, so the unwanted gap appears.
    
    Fix the problem by looking at the old page in SwPageFrame::MoveFly() and
    walking through the immediate children of the body frame: if the frame
    print area is invalidated, then SetYMargins() is called from
    SwTabFrame::Format(), which also invalidates the size of the outer table
    frame, so it will use Shrink() to have a correct size.
    
    This appears to be a regression from commit
    b9ef71476fd70bc13f50ebe80390e0730d1b7afb (tdf#134298 sw: layout: remove
    left-over page frame without content, 2020-11-13).
    
    Change-Id: I0424d9eea4d8a030959f8534985950c7efad4686
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143881
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins
    (cherry picked from commit cf2c070de2bafeec3b476c6bff7bb4ac87ba46db)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143961
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/sw/qa/core/layout/data/page-remove-fly-table.odt 
b/sw/qa/core/layout/data/page-remove-fly-table.odt
new file mode 100644
index 000000000000..6aaf230966ef
Binary files /dev/null and b/sw/qa/core/layout/data/page-remove-fly-table.odt 
differ
diff --git a/sw/qa/core/layout/layout.cxx b/sw/qa/core/layout/layout.cxx
index 8479a3a075aa..eb197b80b184 100644
--- a/sw/qa/core/layout/layout.cxx
+++ b/sw/qa/core/layout/layout.cxx
@@ -14,6 +14,8 @@
 #include <vcl/gdimtf.hxx>
 #include <svx/svdpage.hxx>
 #include <o3tl/string_view.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/dispatch.hxx>
 
 #include <wrtsh.hxx>
 #include <docsh.hxx>
@@ -29,6 +31,12 @@
 #include <IDocumentContentOperations.hxx>
 #include <fmtfsize.hxx>
 #include <fmtfollowtextflow.hxx>
+#include <view.hxx>
+#include <cmdid.h>
+#include <node.hxx>
+#include <ndtxt.hxx>
+#include <tabfrm.hxx>
+#include <cntfrm.hxx>
 
 /// Covers sw/source/core/layout/ fixes.
 class SwCoreLayoutTest : public SwModelTestBase
@@ -882,6 +890,36 @@ CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, 
testFollowTextFlowWrapInBackground)
     CPPUNIT_ASSERT_GREATER(static_cast<sal_Int32>(1000), nCellHeight);
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, testPageRemoveFlyTable)
+{
+    // Given a document with a ToC and several tables, one table marked with a 
bookmark:
+    createSwDoc("page-remove-fly-table.odt");
+    SwDoc* pDoc = getSwDoc();
+
+    // When updating the ToC and incrementally formatting the document:
+    SwView* pView = pDoc->GetDocShell()->GetView();
+    SfxDispatcher& rDispatcher = *pView->GetViewFrame()->GetDispatcher();
+    rDispatcher.Execute(FN_UPDATE_TOX);
+    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+    pWrtShell->Reformat();
+
+    // Then make sure that the 2nd table below the bookmark has no unwanted 
top margin:
+    pWrtShell->GotoMark("test");
+    pWrtShell->Down(/*bSelect=*/false, /*nCount=*/1, /*bBasicCall=*/false);
+    pWrtShell->Down(/*bSelect=*/false, /*nCount=*/1, /*bBasicCall=*/false);
+    SwCursor* pCursor = pWrtShell->GetCursor();
+    SwTextNode* pTextNode = pCursor->GetPoint()->GetNode().GetTextNode();
+    SwFrame* pTextFrame = pTextNode->getLayoutFrame(nullptr);
+    SwTabFrame* pInnerTable = pTextFrame->FindTabFrame();
+    SwTabFrame* pOuterTable = pInnerTable->GetUpper()->FindTabFrame();
+    tools::Long nActual = pOuterTable->getFramePrintArea().Top();
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 0
+    // - Actual  : 5879
+    // i.e. the problematic table had a large, unwanted/leftover top margin.
+    CPPUNIT_ASSERT_EQUAL(static_cast<tools::Long>(0), nActual);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/flylay.cxx b/sw/source/core/layout/flylay.cxx
index 193c678a2e18..d7c6969a4b6b 100644
--- a/sw/source/core/layout/flylay.cxx
+++ b/sw/source/core/layout/flylay.cxx
@@ -989,6 +989,17 @@ void SwPageFrame::MoveFly( SwFlyFrame *pToMove, 
SwPageFrame *pDest )
         {
             m_pSortedObjs.reset();
         }
+
+        // Removing a fly from the page affects the margin of e.g. tables, so 
update the frame print
+        // area of the lowers of my body frame.
+        SwFrame* pBodyFrame = FindBodyCont();
+        if (pBodyFrame)
+        {
+            for (SwFrame* pFrame = pBodyFrame->GetLower(); pFrame; pFrame = 
pFrame->GetNext())
+            {
+                pFrame->InvalidatePrt();
+            }
+        }
     }
 
     // Register
commit 2b18a3b159b9cbcf7ba620094a5dfb982d4f7f3a
Author:     offtkp <parisop...@gmail.com>
AuthorDate: Mon Dec 12 13:03:43 2022 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Wed Dec 14 08:48:21 2022 +0000

    docx: Do not remove showingPlcHdr until edit
    
    When a placeholder has the showingPlcHdr attribute, the entire text is
    selected upon click. This is no longer removed by selecting it once but
    once the text has been edited.
    
    Change-Id: I9a4d68289c8b95ab0098e55a5fa6edb1606c7df2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143985
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    (cherry picked from commit 618cef756b87f9816d0dcbe04af163ccd06a986e)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144033
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/sw/qa/uibase/wrtsh/wrtsh.cxx b/sw/qa/uibase/wrtsh/wrtsh.cxx
index d2adde32a179..a2d9fdc37514 100644
--- a/sw/qa/uibase/wrtsh/wrtsh.cxx
+++ b/sw/qa/uibase/wrtsh/wrtsh.cxx
@@ -399,6 +399,13 @@ CPPUNIT_TEST_FIXTURE(Test, 
testInsertPlainTextContentControl)
     // Without the accompanying fix in place, this test would have failed, 
there was no special
     // handling for plain text content controls.
     CPPUNIT_ASSERT(pContentControl->GetPlainText());
+
+    CPPUNIT_ASSERT(pContentControl->GetShowingPlaceHolder());
+    pWrtShell->GotoContentControl(rFormatContentControl);
+    CPPUNIT_ASSERT(pContentControl->GetShowingPlaceHolder());
+    pWrtShell->Insert("Foo");
+    // No longer showing placeholder text, as it has been changed
+    CPPUNIT_ASSERT(!pContentControl->GetShowingPlaceHolder());
 }
 
 CPPUNIT_TEST_FIXTURE(Test, testInsertComboBoxContentControl)
diff --git a/sw/source/core/txtnode/attrcontentcontrol.cxx 
b/sw/source/core/txtnode/attrcontentcontrol.cxx
index 890bf20c1376..1db39849fbe6 100644
--- a/sw/source/core/txtnode/attrcontentcontrol.cxx
+++ b/sw/source/core/txtnode/attrcontentcontrol.cxx
@@ -720,7 +720,6 @@ void SwTextContentControl::Invalidate()
     pDocShell->GetWrtShell()->Push();
 
     // visit the control in the text (which makes any necessary visual changes)
-    // NOTE: simply going to a control indicates cancelling 
ShowingPlaceHolder, unless bOnlyRefresh
     // NOTE: simply going to a checkbox causes a toggle, unless bOnlyRefresh
     auto& rFormatContentControl = 
static_cast<SwFormatContentControl&>(GetAttr());
     pDocShell->GetWrtShell()->GotoContentControl(rFormatContentControl, 
/*bOnlyRefresh=*/true);
diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx 
b/sw/source/uibase/wrtsh/wrtsh1.cxx
index adf96052e8fa..b989343266cb 100644
--- a/sw/source/uibase/wrtsh/wrtsh1.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh1.cxx
@@ -117,6 +117,7 @@
 #include <UndoCore.hxx>
 #include <formatlinebreak.hxx>
 #include <formatcontentcontrol.hxx>
+#include <textcontentcontrol.hxx>
 
 using namespace sw::mark;
 using namespace com::sun::star;
@@ -262,6 +263,19 @@ void SwWrtShell::Insert( const OUString &rStr )
     bCallIns ?
         SwEditShell::Insert2( rStr, bDeleted ) : SwEditShell::Overwrite( rStr 
);
 
+    // Check whether node is content control
+    SwTextContentControl* pTextContentControl = CursorInsideContentControl();
+    if (pTextContentControl)
+    {
+        std::shared_ptr<SwContentControl> pContentControl =
+            pTextContentControl->GetContentControl().GetContentControl();
+        if (pContentControl)
+        {
+            // Set showingPlcHdr to false as node has been edited
+            pContentControl->SetShowingPlaceHolder(false);
+        }
+    }
+
     if( bStarted )
     {
         EndUndo();
diff --git a/sw/source/uibase/wrtsh/wrtsh3.cxx 
b/sw/source/uibase/wrtsh/wrtsh3.cxx
index aa170d1374a4..4e80bfc1e3d1 100644
--- a/sw/source/uibase/wrtsh/wrtsh3.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh3.cxx
@@ -125,10 +125,6 @@ bool SwWrtShell::GotoContentControl(const 
SwFormatContentControl& rContentContro
     (this->*m_fnKillSel)(nullptr, false);
 
     bool bRet = SwCursorShell::GotoFormatContentControl(rContentControl);
-    // Assume that once the placeholder is selected, the content is no longer 
the placeholder.
-    if (!bOnlyRefresh && pContentControl)
-        pContentControl->SetShowingPlaceHolder(false);
-
 
     if (bRet && pContentControl && pContentControl->GetCheckbox())
     {

Reply via email to