core.git: Branch 'libreoffice-24-2' - sw/qa sw/source xmloff/qa

2024-05-22 Thread Miklos Vajna (via logerrit)
 sw/qa/core/layout/data/fly-rel-width-rounding.odt |binary
 sw/qa/core/layout/fly.cxx |   25 ++
 sw/source/core/layout/fly.cxx |5 ++--
 xmloff/qa/unit/text.cxx   |4 +--
 4 files changed, 30 insertions(+), 4 deletions(-)

New commits:
commit 3046bd0e30406d37813ce3eaa65f71f5ed10ab13
Author: Miklos Vajna 
AuthorDate: Wed May 22 08:47:32 2024 +0200
Commit: Xisco Fauli 
CommitDate: Wed May 22 13:44:49 2024 +0200

Related: tdf#145972 sw images: fix rounding error in relative size 
calculation

Open the bugdoc, see that the image is roughly half of the page width,
right click, properties, UI shows that the width of the image is 5% of
the width of the entire page. This only happens if tools -> options ->
writer -> general sets the UI units to points, the default cm case is
fine.

This went wrong with commit 9e8712ed6f9fb5dbd971e352a5709bd45fadc74f (sw
image dialog: fix fallback width/height for images with relative sizes,
2022-03-17), because the layout size started to matter more after that
commit. This lead to the nWidth !=
m_xWidthED->get_value(FieldUnit::TWIP) check in SwFramePage::Init() to
be true, because 11906 * 0.48 is 5714.88, so you got 5714 in the layout,
but got 5715 with rounding in SwFramePage::Reset() (which tries to calc
the page width based on the 48% and the fly width). And once we had that
mismatch, we went down the wrong path.

Fix the problem by using rtl::math::round() in SwFlyFrame::CalcRel(), so
the relative width twips value is 5715 everywhere: once we have
consisteny, the UI value is correct, too.

Note that the original bugdoc needs more fixing, this just fixes the
bugdoc where KeepRatio is false.

Change-Id: I1e8782c95a0cf9d97375c36d41134735c01f3e46
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167916
Tested-by: Jenkins
Reviewed-by: Miklos Vajna 
Signed-off-by: Xisco Fauli 
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167926

diff --git a/sw/qa/core/layout/data/fly-rel-width-rounding.odt 
b/sw/qa/core/layout/data/fly-rel-width-rounding.odt
new file mode 100644
index ..b70b9e51a917
Binary files /dev/null and b/sw/qa/core/layout/data/fly-rel-width-rounding.odt 
differ
diff --git a/sw/qa/core/layout/fly.cxx b/sw/qa/core/layout/fly.cxx
index 47cfb40fa6e7..81df20af3b35 100644
--- a/sw/qa/core/layout/fly.cxx
+++ b/sw/qa/core/layout/fly.cxx
@@ -86,6 +86,31 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFlyNegativeHeight)
 }
 }
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testFlyRelWithRounding)
+{
+// Given a document where page width is 21.001cm (11906 twips), and the 
image width is 48% of
+// the page width:
+createSwDoc("fly-rel-width-rounding.odt");
+
+// When laying out that document:
+SwDoc* pDoc = getSwDoc();
+SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+
+// Then make sure that we calculate the width of the fly correctly:
+auto pPage = pLayout->GetLower()->DynCastPageFrame();
+CPPUNIT_ASSERT(pPage->GetSortedObjs());
+SwSortedObjs& rPageObjs = *pPage->GetSortedObjs();
+CPPUNIT_ASSERT_EQUAL(static_cast(1), rPageObjs.size());
+auto pFly = rPageObjs[0]->DynCastFlyFrame()->DynCastFlyAtContentFrame();
+CPPUNIT_ASSERT(pFly);
+tools::Long nFlyWidth = pFly->getFrameArea().Width();
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected: 5715
+// - Actual  : 5714
+// i.e. 5714.88 was truncated, not rounded.
+CPPUNIT_ASSERT_EQUAL(static_cast(5715), nFlyWidth);
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx
index b454bd95917f..fd95ce192cf7 100644
--- a/sw/source/core/layout/fly.cxx
+++ b/sw/source/core/layout/fly.cxx
@@ -70,6 +70,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -2845,9 +2846,9 @@ Size SwFlyFrame::CalcRel( const SwFormatFrameSize  ) 
const
 }
 
 if ( rSz.GetWidthPercent() && rSz.GetWidthPercent() != 
SwFormatFrameSize::SYNCED )
-aRet.setWidth( nRelWidth * rSz.GetWidthPercent() / 100 );
+aRet.setWidth(rtl::math::round(double(nRelWidth) * 
rSz.GetWidthPercent() / 100));
 if ( rSz.GetHeightPercent() && rSz.GetHeightPercent() != 
SwFormatFrameSize::SYNCED )
-aRet.setHeight( nRelHeight * rSz.GetHeightPercent() / 100 );
+aRet.setHeight(rtl::math::round(double(nRelHeight) * 
rSz.GetHeightPercent() / 100));
 
 if ( rSz.GetHeight() && rSz.GetWidthPercent() == 
SwFormatFrameSize::SYNCED )
 {
diff --git a/xmloff/qa/unit/text.cxx b/xmloff/qa/unit/text.cxx
index e6433b2b70f9..2da04387d707 100644
--- a/xmloff/qa/unit/text.cxx
+++ b/xmloff/qa/unit/text.cxx
@@ -505,11 +505,11 @@ 

core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-05-21 Thread Mike Kaganski (via logerrit)
 sw/qa/extras/uiwriter/data/tdf161172.fodt |   35 +
 sw/qa/extras/uiwriter/uiwriter9.cxx   |   42 ++
 sw/source/core/doc/docfmt.cxx |   10 ++-
 3 files changed, 81 insertions(+), 6 deletions(-)

New commits:
commit e9e27cc9a8914e97f5ea28de863e580062e030de
Author: Mike Kaganski 
AuthorDate: Sun May 19 13:40:49 2024 +0500
Commit: Xisco Fauli 
CommitDate: Tue May 21 11:27:26 2024 +0200

tdf#161172: Also record history for !bChangeOfListStyleAtParagraph

Change-Id: I6443d7ef76a27ac3ab75f88edd271a8b36e06c14
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167839
Reviewed-by: Mike Kaganski 
Tested-by: Jenkins
Signed-off-by: Xisco Fauli 
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167818

diff --git a/sw/qa/extras/uiwriter/data/tdf161172.fodt 
b/sw/qa/extras/uiwriter/data/tdf161172.fodt
new file mode 100644
index ..08cea575cc60
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/tdf161172.fodt
@@ -0,0 +1,35 @@
+
+
+
+ 
+  
+  
+  
+   
+
+ 
+
+   
+   
+
+ 
+
+   
+  
+ 
+ 
+  
+ 
+ 
+  
+ 
+ 
+  
+   
+
+ foo
+
+   
+  
+ 
+
\ No newline at end of file
diff --git a/sw/qa/extras/uiwriter/uiwriter9.cxx 
b/sw/qa/extras/uiwriter/uiwriter9.cxx
index fe69b26dd87a..2389aa63714a 100644
--- a/sw/qa/extras/uiwriter/uiwriter9.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter9.cxx
@@ -19,6 +19,7 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 
@@ -214,6 +215,47 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf160898)
 pWrtShell->SelAll();
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf161172)
+{
+// Given a paragraph manually made a member of a list:
+createSwDoc("tdf161172.fodt");
+auto para = getParagraph(1);
+
+// Check initial state: the first paragraph has "No_list" para style, 
"Num_1" numbering style,
+// numbering level 0, and "Num1_lvl1_1" numbering label.
+CPPUNIT_ASSERT_EQUAL(u"No_list"_ustr, getProperty(para, 
u"ParaStyleName"_ustr));
+CPPUNIT_ASSERT_EQUAL(u"Num_1"_ustr, getProperty(para, 
u"NumberingStyleName"_ustr));
+CPPUNIT_ASSERT_EQUAL(u"Num1_lvl1_1"_ustr, getProperty(para, 
u"ListLabelString"_ustr));
+CPPUNIT_ASSERT_EQUAL(sal_Int16(0), getProperty(para, 
u"NumberingLevel"_ustr));
+
+// Assign "Num_1_lvl2" paragraph style to the first paragraph. The style 
is associated with
+// "Num_1" numbering style, level 1.
+dispatchCommand(mxComponent, u".uno:StyleApply"_ustr,
+{ comphelper::makePropertyValue(u"FamilyName"_ustr, 
u"ParagraphStyles"_ustr),
+  comphelper::makePropertyValue(u"Style"_ustr, 
u"Num_1_lvl2"_ustr) });
+
+// Check that the respective properties got correctly applied
+CPPUNIT_ASSERT_EQUAL(u"Num_1_lvl2"_ustr, getProperty(para, 
u"ParaStyleName"_ustr));
+CPPUNIT_ASSERT_EQUAL(u"Num_1"_ustr, getProperty(para, 
u"NumberingStyleName"_ustr));
+CPPUNIT_ASSERT_EQUAL(u"Num1_lvl2_1"_ustr, getProperty(para, 
u"ListLabelString"_ustr));
+CPPUNIT_ASSERT_EQUAL(sal_Int16(1), getProperty(para, 
u"NumberingLevel"_ustr));
+
+// Undo
+dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
+
+// Check that the numbering properties got correctly restored
+CPPUNIT_ASSERT_EQUAL(u"No_list"_ustr, getProperty(para, 
u"ParaStyleName"_ustr));
+CPPUNIT_ASSERT_EQUAL(u"Num_1"_ustr, getProperty(para, 
u"NumberingStyleName"_ustr));
+// Without the fix, this would fail with
+// - Expected: Num1_lvl1_1
+// - Actual  : Num1_lvl2_1
+CPPUNIT_ASSERT_EQUAL(u"Num1_lvl1_1"_ustr, getProperty(para, 
u"ListLabelString"_ustr));
+// Without the fix, this would fail with
+// - Expected: 0
+// - Actual  : 1
+CPPUNIT_ASSERT_EQUAL(sal_Int16(0), getProperty(para, 
u"NumberingLevel"_ustr));
+}
+
 } // end of anonymous namespace
 CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx
index 1c696bebb6a0..3390a506052c 100644
--- a/sw/source/core/doc/docfmt.cxx
+++ b/sw/source/core/doc/docfmt.cxx
@@ -1040,14 +1040,12 @@ static bool lcl_SetTextFormatColl( SwNode* pNode, void* 
pArgs )
 }
 }
 
+std::optional oRegH;
+if (pPara->pHistory)
+oRegH.emplace(, rTNd, pPara->pHistory);
+
 if ( bChangeOfListStyleAtParagraph )
 {
-std::unique_ptr< SwRegHistory > pRegH;
-if ( pPara->pHistory )
-{
-pRegH.reset(new SwRegHistory(, rTNd, 
pPara->pHistory));
-}
-
 pCNd->ResetAttr( RES_PARATR_NUMRULE );
 
 // reset all list attributes


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-05-17 Thread Miklos Vajna (via logerrit)
 sw/qa/core/layout/calcmove.cxx   |   24 +++
 sw/qa/core/layout/data/ignore-top-margin-fly.odt |binary
 sw/source/core/layout/calcmove.cxx   |6 +
 3 files changed, 30 insertions(+)

New commits:
commit 9b508c45a7c30a5c1847b7d93f2a26a653102588
Author: Miklos Vajna 
AuthorDate: Fri May 17 08:07:23 2024 +0200
Commit: Miklos Vajna 
CommitDate: Fri May 17 11:00:10 2024 +0200

tdf#160952 sw: ignore top margin only at page top, not in fly

See

,
multi-column shape text can't appear in DOCX files, so collapsing upper
spacing in that case is not correct, avoid it.

Change-Id: Icf69c8d84fdd15d6e3289ff614b2f6ba7cee1e0e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167758
Reviewed-by: Miklos Vajna 
Tested-by: Jenkins
(cherry picked from commit b969e692000f50aafacc2eb577f545b8836dcc26)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167683
Reviewed-by: Michael Stahl 

diff --git a/sw/qa/core/layout/calcmove.cxx b/sw/qa/core/layout/calcmove.cxx
index a44dc1256b83..ad53df9bd0f4 100644
--- a/sw/qa/core/layout/calcmove.cxx
+++ b/sw/qa/core/layout/calcmove.cxx
@@ -58,6 +58,30 @@ CPPUNIT_TEST_FIXTURE(Test, testIgnoreTopMarginTable)
 // i.e. the top margin in B1's first paragraph was ignored, but not in 
Word.
 CPPUNIT_ASSERT_EQUAL(static_cast(2000), nParaTopMargin);
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testIgnoreTopMarginFly)
+{
+// Given a document with compat flags like DOCX (>= Word 2013), 2 pages, 
multi-col fly frame on
+// page 2:
+createSwDoc("ignore-top-margin-fly.odt");
+
+// When laying out that document:
+xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+// Then make sure that the top margin is not ignored inside shape text:
+sal_Int32 nParaTopMargin
+= getXPath(
+  pXmlDoc,
+  
"/root/page[2]/body/section/column[2]/body/txt/anchored/fly/column/body/txt/infos/prtBounds"_ostr,
+  "top"_ostr)
+  .toInt32();
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected: 4000
+// - Actual  : 0
+// i.e. the top margin was ignored inside shape text for Word compat, 
while multi-col shape text
+// is a Writer feature.
+CPPUNIT_ASSERT_EQUAL(static_cast(4000), nParaTopMargin);
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/core/layout/data/ignore-top-margin-fly.odt 
b/sw/qa/core/layout/data/ignore-top-margin-fly.odt
new file mode 100644
index ..51bda8fe40a9
Binary files /dev/null and b/sw/qa/core/layout/data/ignore-top-margin-fly.odt 
differ
diff --git a/sw/source/core/layout/calcmove.cxx 
b/sw/source/core/layout/calcmove.cxx
index 63c774c25cd6..f358d74af0bd 100644
--- a/sw/source/core/layout/calcmove.cxx
+++ b/sw/source/core/layout/calcmove.cxx
@@ -1092,6 +1092,12 @@ bool SwFrame::IsCollapseUpper() const
 return false;
 }
 
+if (IsInFly())
+{
+// Not in a page's body.
+return false;
+}
+
 // Word >= 2013 style: when we're at the top of the page's body, but not 
on the first page, then
 // ignore the upper margin for paragraphs.
 if (GetPrev() || !GetUpper() || !GetUpper()->IsBodyFrame())


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-05-16 Thread Mike Kaganski (via logerrit)
 sw/qa/extras/unowriter/data/tdf161035.fodt |9 +
 sw/qa/extras/unowriter/unowriter.cxx   |   27 +++
 sw/source/core/unocore/unoportenum.cxx |4 +++-
 3 files changed, 39 insertions(+), 1 deletion(-)

New commits:
commit 324c1a72961ccc1af1c496689c558aa127ef3d81
Author: Mike Kaganski 
AuthorDate: Thu May 16 11:07:26 2024 +0500
Commit: Adolfo Jayme Barrientos 
CommitDate: Thu May 16 22:41:09 2024 +0200

tdf#161035: The previous bookmarks can legitimately be not processed

The enumeration may be called for a partial paragraph selection, and
then the bookmarks prior to the selection are not processed.

Change-Id: Ib725ffb320ec5a81b39ce77f06392a82bd6d8ee0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167720
Reviewed-by: Mike Kaganski 
Tested-by: Jenkins
Reviewed-by: Patrick Luby 
Signed-off-by: Xisco Fauli 
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167754
Reviewed-by: Adolfo Jayme Barrientos 

diff --git a/sw/qa/extras/unowriter/data/tdf161035.fodt 
b/sw/qa/extras/unowriter/data/tdf161035.fodt
new file mode 100644
index ..8f1d53b083d6
--- /dev/null
+++ b/sw/qa/extras/unowriter/data/tdf161035.fodt
@@ -0,0 +1,9 @@
+
+
+
+ 
+  
+   Lorem ipsum.
+  
+ 
+
\ No newline at end of file
diff --git a/sw/qa/extras/unowriter/unowriter.cxx 
b/sw/qa/extras/unowriter/unowriter.cxx
index 80b9e556f73b..7175e702d709 100644
--- a/sw/qa/extras/unowriter/unowriter.cxx
+++ b/sw/qa/extras/unowriter/unowriter.cxx
@@ -1222,6 +1222,33 @@ CPPUNIT_TEST_FIXTURE(SwUnoWriter, testTdf160278)
 CPPUNIT_ASSERT_EQUAL(u"12test"_ustr, xText->getString());
 }
 
+CPPUNIT_TEST_FIXTURE(SwUnoWriter, testTdf161035)
+{
+// Given a paragraph with a bookmark:
+createSwDoc("tdf161035.fodt");
+auto xModel = mxComponent.queryThrow();
+
+// Create a text view cursor in the paragraph.
+auto xController = 
xModel->getCurrentController().queryThrow();
+auto xViewCursor = xController->getViewCursor();
+CPPUNIT_ASSERT(xViewCursor);
+auto xText = xViewCursor->getText();
+CPPUNIT_ASSERT(xText);
+// Create a text cursor from the text view cursor, and move it to the end 
of the paragraph
+auto xTextCursor = xText->createTextCursorByRange(xViewCursor);
+CPPUNIT_ASSERT(xTextCursor);
+xTextCursor->gotoEnd(false);
+// Get the first paragraph portion from the text cursor
+auto xParaEnum = 
xTextCursor.queryThrow()->createEnumeration();
+CPPUNIT_ASSERT(xParaEnum);
+auto xPara = 
xParaEnum->nextElement().queryThrow();
+// Try to enumerate text portions. Without the fix, it would fail an 
assertion in debug builds,
+// and hang in release builds, because the paragraph portion started after 
the bookmark, and
+// so the bookmark wasn't processed (expectedly):
+auto xRunEnum = xPara->createEnumeration();
+CPPUNIT_ASSERT(!xRunEnum->hasMoreElements()); // Empty enumeration for 
empty selection
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unoportenum.cxx 
b/sw/source/core/unocore/unoportenum.cxx
index 709d79ef4d4b..9177765c0e32 100644
--- a/sw/source/core/unocore/unoportenum.cxx
+++ b/sw/source/core/unocore/unoportenum.cxx
@@ -608,7 +608,9 @@ static void lcl_ExportBookmark(
 const SwXBookmarkPortion_ImplSharedPtr& pPtr = *aIter;
 if ( nIndex > pPtr->getIndex() )
 {
-assert(!"Some bookmarks were not consumed earlier");
+// We may get here, if SwXTextPortionEnumeration ctor was called 
with nStart greater
+// than this bookmark's index. Just drop it.
+aIter = rBkmArr.erase(aIter);
 continue;
 }
 if ( nIndex < pPtr->getIndex() )


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-05-16 Thread Miklos Vajna (via logerrit)
 sw/qa/core/layout/calcmove.cxx  |   19 +++
 sw/qa/core/layout/data/ignore-top-margin-table.docx |binary
 sw/source/core/layout/calcmove.cxx  |6 +++---
 3 files changed, 22 insertions(+), 3 deletions(-)

New commits:
commit ed4316d109841c31de49493092d82b40259e818a
Author: Miklos Vajna 
AuthorDate: Tue May 14 13:49:51 2024 +0200
Commit: Michael Stahl 
CommitDate: Thu May 16 09:40:52 2024 +0200

tdf#160952 sw: ignore top margin only at page top, not e.g. table top

The bugdoc has a table at the top of the 2nd page and we ignored the top
margin inside the table cell (for the first paragraph), while this
doesn't happen in Word.

As mentioned at

,
the old code assumed "top of the page" for all frames not having a
previous frame, while that code was only tested with text frames
directly in the body frame of a page frame.

Fix the problem by limiting this "collapse upper spacing" behavior to
frames directly in body frames. This keeps the old bugdoc working, but
is meant to restore the old, wanted behavior in other cases like e.g. in
table cells.

If later it's discovered that upper spacing collapsing is wanted in
other contexts, those are best added on a case by case basis.

Change-Id: Ieb93facd8b2e7f6412fd20873c10ce6c8b775619
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167631
Reviewed-by: Miklos Vajna 
Tested-by: Jenkins
(cherry picked from commit 6025ac371bd5cd07c0af550d78db323ad394173b)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167671
Reviewed-by: Michael Stahl 

diff --git a/sw/qa/core/layout/calcmove.cxx b/sw/qa/core/layout/calcmove.cxx
index 3e4deec52ae8..a44dc1256b83 100644
--- a/sw/qa/core/layout/calcmove.cxx
+++ b/sw/qa/core/layout/calcmove.cxx
@@ -39,6 +39,25 @@ CPPUNIT_TEST_FIXTURE(Test, testIgnoreTopMargin)
 // i.e. the top margin in the first para of a non-first page wasn't 
ignored, like in Word.
 CPPUNIT_ASSERT_EQUAL(static_cast(0), nParaTopMargin);
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testIgnoreTopMarginTable)
+{
+// Given a DOCX (>= Word 2013) file, with 2 pages:
+// When loading that document:
+createSwDoc("ignore-top-margin-table.docx");
+
+// Then make sure that the paragraph on the 2nd page in B1 has a top 
margin:
+xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+sal_Int32 nParaTopMargin
+= getXPath(pXmlDoc, 
"/root/page[2]/body/tab/row/cell[2]/txt/infos/prtBounds"_ostr,
+   "top"_ostr)
+  .toInt32();
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected: 2000
+// - Actual  : 0
+// i.e. the top margin in B1's first paragraph was ignored, but not in 
Word.
+CPPUNIT_ASSERT_EQUAL(static_cast(2000), nParaTopMargin);
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/core/layout/data/ignore-top-margin-table.docx 
b/sw/qa/core/layout/data/ignore-top-margin-table.docx
new file mode 100644
index ..c82f6d63c13f
Binary files /dev/null and 
b/sw/qa/core/layout/data/ignore-top-margin-table.docx differ
diff --git a/sw/source/core/layout/calcmove.cxx 
b/sw/source/core/layout/calcmove.cxx
index 081472b98ee3..63c774c25cd6 100644
--- a/sw/source/core/layout/calcmove.cxx
+++ b/sw/source/core/layout/calcmove.cxx
@@ -1092,9 +1092,9 @@ bool SwFrame::IsCollapseUpper() const
 return false;
 }
 
-// Word >= 2013 style: when we're at the top of the page, but not on the 
first page, then ignore
-// the upper margin for paragraphs.
-if (GetPrev())
+// Word >= 2013 style: when we're at the top of the page's body, but not 
on the first page, then
+// ignore the upper margin for paragraphs.
+if (GetPrev() || !GetUpper() || !GetUpper()->IsBodyFrame())
 {
 return false;
 }


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-05-14 Thread László Németh (via logerrit)
 sw/qa/extras/uiwriter/uiwriter6.cxx |   50 
 sw/source/uibase/docvw/edtwin.cxx   |   12 +++-
 2 files changed, 60 insertions(+), 2 deletions(-)

New commits:
commit 03d40ad9dea1629f55a1270d425a5995ed229ddb
Author: László Németh 
AuthorDate: Fri Apr 26 22:03:53 2024 +0200
Commit: Michael Stahl 
CommitDate: Tue May 14 11:03:30 2024 +0200

tdf#160836 sw: resize rows at images cropped by row height

Fixed row height can crop cell content, including images
anchored as character. Resizing the row height with mouse
was not possible there, because selection of the cropped
image avoided to drag & drop the horizontal cell border.

Change-Id: I6dde79e77563468059794548b6c058cad61586a0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166795
Reviewed-by: László Németh 
Tested-by: Jenkins
(cherry picked from commit 30de13743f144aced83bc43d310592f82788c910)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167210
Reviewed-by: Michael Stahl 

diff --git a/sw/qa/extras/uiwriter/uiwriter6.cxx 
b/sw/qa/extras/uiwriter/uiwriter6.cxx
index db0c8f6929c7..8e67d26e4652 100644
--- a/sw/qa/extras/uiwriter/uiwriter6.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter6.cxx
@@ -1513,6 +1513,56 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf160842)
 CPPUNIT_ASSERT(pWrtShell->IsCursorInTable());
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf160836)
+{
+createSwDoc("tdf160842.fodt");
+SwDoc* pDoc = getSwDoc();
+CPPUNIT_ASSERT(pDoc);
+SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+CPPUNIT_ASSERT(pWrtShell);
+
+// set table row height by drag & drop at images cropped by the fixed row 
height
+SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+auto pPage = dynamic_cast(pLayout->Lower());
+CPPUNIT_ASSERT(pPage);
+const SwSortedObjs& rPageObjs = *pPage->GetSortedObjs();
+CPPUNIT_ASSERT_EQUAL(static_cast(1), rPageObjs.size());
+auto pPageFly = dynamic_cast(rPageObjs[0]);
+CPPUNIT_ASSERT(pPageFly);
+auto pTable = dynamic_cast(pPageFly->GetLower());
+CPPUNIT_ASSERT(pTable);
+auto pRow1 = pTable->GetLower();
+CPPUNIT_ASSERT(pRow1->IsRowFrame());
+auto pCellA1 = pRow1->GetLower();
+CPPUNIT_ASSERT(pCellA1);
+const SwRect& rCellA1Rect = pCellA1->getFrameArea();
+auto nRowHeight = rCellA1Rect.Height();
+// select center of the bottom border of the first table cell
+Point ptFrom(rCellA1Rect.Left() + rCellA1Rect.Width() / 2, 
rCellA1Rect.Top() + nRowHeight);
+// halve the row height
+Point ptTo(rCellA1Rect.Left() + rCellA1Rect.Width() / 2, rCellA1Rect.Top() 
+ 0.5 * nRowHeight);
+vcl::Window& rEditWin = pDoc->GetDocShell()->GetView()->GetEditWin();
+Point aFrom = rEditWin.LogicToPixel(ptFrom);
+MouseEvent aClickEvent(aFrom, 1, MouseEventModifiers::SIMPLECLICK | 
MouseEventModifiers::SELECT,
+   MOUSE_LEFT);
+rEditWin.MouseButtonDown(aClickEvent);
+Point aTo = rEditWin.LogicToPixel(ptTo);
+MouseEvent aMoveEvent(aTo, 1, MouseEventModifiers::SIMPLECLICK | 
MouseEventModifiers::SELECT,
+  MOUSE_LEFT);
+TrackingEvent aTEvt(aMoveEvent, TrackingEventFlags::Repeat);
+// drag & drop of cell border inside the document (and outside the table)
+// still based on the ruler code, use that to simulate dragging
+pDoc->GetDocShell()->GetView()->GetVRuler().Tracking(aTEvt);
+TrackingEvent aTEvt2(aMoveEvent, TrackingEventFlags::End);
+pDoc->GetDocShell()->GetView()->GetVRuler().Tracking(aTEvt2);
+Scheduler::ProcessEventsToIdle();
+rEditWin.CaptureMouse();
+rEditWin.ReleaseMouse();
+
+// this was 3910 (not modified row height previously)
+CPPUNIT_ASSERT_EQUAL(tools::Long(1980), pCellA1->getFrameArea().Height());
+}
+
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf115132)
 {
 createSwDoc();
diff --git a/sw/source/uibase/docvw/edtwin.cxx 
b/sw/source/uibase/docvw/edtwin.cxx
index 073b6b59649e..9aa4862a43a4 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -3113,9 +3113,13 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt)
 SwTab nMouseTabCol = SwTab::COL_NONE;
 const bool bTmp = !rSh.IsDrawCreate() && !m_pApplyTempl && 
!rSh.IsInSelect()
   && aMEvt.GetClicks() == 1 && MOUSE_LEFT == 
aMEvt.GetButtons();
+
 if (  bTmp &&
  SwTab::COL_NONE != (nMouseTabCol = rSh.WhichMouseTabCol( aDocPos ) ) 
&&
- !rSh.IsObjSelectable( aDocPos ) )
+ ( !rSh.IsObjSelectable( aDocPos ) ||
+ // allow resizing row height, if the image is anchored as 
character in the cell
+ ( rSh.ShouldObjectBeSelected(aDocPos) &&
+ !( SwTab::COL_VERT == nMouseTabCol || SwTab::COL_HORI == 
nMouseTabCol ) ) ) )
 {
 // Enhanced table selection
 if ( SwTab::SEL_HORI <= nMouseTabCol && 

core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-05-13 Thread László Németh (via logerrit)
 sw/qa/extras/uiwriter/data/tdf160842.fodt |   75 ++
 sw/qa/extras/uiwriter/uiwriter6.cxx   |   41 
 sw/source/core/frmedt/feshview.cxx|   22 
 3 files changed, 138 insertions(+)

New commits:
commit 5ad48954250b9235f4381a756445c318d2d69f6c
Author: László Németh 
AuthorDate: Sat Apr 27 00:26:54 2024 +0200
Commit: Michael Stahl 
CommitDate: Mon May 13 11:56:35 2024 +0200

tdf#160842 sw: select cell content instead of cropped part of image

It was not possible to select and edit the content of the bottom
cell, if an image cropped by the fixed row height "covered" it,
i.e. the image was in the previous row, anchored as character.

Note: table cells with fixed row height are usable to crop images
easily, with a single drag & drop, according to the requirement of
the text layout, while the cell above or bottom of the cell with
image is for the caption of the image. This is very useful to
adjust a book layout with sections with multiple columns and
illustrations.

Change-Id: I8683b4066db6ce43549ec3aa69b0e639a59e3681
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166794
Tested-by: Jenkins
Reviewed-by: László Németh 
(cherry picked from commit f3b899655018397e71300dbb32cdf4f82940a68b)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167089
Reviewed-by: Michael Stahl 

diff --git a/sw/qa/extras/uiwriter/data/tdf160842.fodt 
b/sw/qa/extras/uiwriter/data/tdf160842.fodt
new file mode 100644
index ..217b9c1a9570
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/tdf160842.fodt
@@ -0,0 +1,75 @@
+
+
+http://www.w3.org/TR/css3-text/; 
xmlns:grddl="http://www.w3.org/2003/g/data-view#; 
xmlns:xhtml="http://www.w3.org/1999/xhtml; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance; 
xmlns:xsd="http://www.w3.org/2001/XMLSchema; 
xmlns:xforms="http://www.w3.org/2002/xforms; 
xmlns:dom="http://www.w3.org/2001/xml-events; 
xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" 
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" 
xmlns:math="http://www.w3.org/1998/Math/MathML; 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:ooo="http://openoffice.org/2004/office; 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" 
xmlns:ooow="http://openoffice.org/2004/writer; 
xmlns:xlink="http://www.w3.org/1999/xlink; 
xmlns:drawooo="http://openoffice.org/2010/draw; 
xmlns:oooc="http://openoffice.org/2004/calc; 
xmlns:dc="http://purl.org/dc/elements/1.1/; xmlns:c
 alcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" 
xmlns:tableooo="http://openoffice.org/2009/table; 
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" 
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" 
xmlns:rpt="http://openoffice.org/2005/report; 
xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0"
 xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" 
xmlns:officeooo="http://openoffice.org/2009/office; 
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" 
xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" 
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" 
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:
 meta:1.0" 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"
 office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ 
+  
+   
+   
+
+   
+   
+  
+  
+  
+   
+  
+  
+   
+  
+ 
+ 
+  
+   
+  
+  
+   
+  
+  
+   
+  
+  
+   
+  
+  
+   
+  
+  
+   
+  
+  
+   
+  
+  
+   
+  
+ 
+ 
+  
+ 
+ 
+  
+   
+ 
+  
+   
+   
+
+ 
+
iVBORw0KGgoNSUhEUgICCAIAAAD91JpzFklEQVQI12P2Ytilf46NeWX3
+ a804HgAg7QTAqXPBTwBJRU5ErkJggg==
+
+   
+  
+
+   
+   
+
+ Lorem ipsum dolor sit amet, consectetur 
adipiscing.
+
+   
+  
+ 
+
+  
+ 
+
diff --git a/sw/qa/extras/uiwriter/uiwriter6.cxx 
b/sw/qa/extras/uiwriter/uiwriter6.cxx
index 9b8ae0244efe..db0c8f6929c7 100644
--- a/sw/qa/extras/uiwriter/uiwriter6.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter6.cxx
@@ -55,6 +55,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -1472,6 +1476,43 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf44773)
 CPPUNIT_ASSERT_EQUAL(tools::Long(810), pCellA1->getFrameArea().Height());
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf160842)
+{
+ 

core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-05-13 Thread László Németh (via logerrit)
 sw/qa/extras/uiwriter/uiwriter6.cxx |   66 
 sw/source/uibase/uiview/viewtab.cxx |2 -
 2 files changed, 67 insertions(+), 1 deletion(-)

New commits:
commit 5b3037e2caa5dc857f51dd0dd7f38646535ee232
Author: László Németh 
AuthorDate: Tue Apr 23 16:04:47 2024 +0200
Commit: Michael Stahl 
CommitDate: Mon May 13 11:54:01 2024 +0200

tdf#44773 sw: allow resizing table rows, if cursor outside the table

If the cursor wasn't in the table, only column width of text
tables was resizeable by dragging the horizontal cell borders:
It was possible to drag the horizontal border, showing its
preview, but the drop cancelled the operation instead of
resizing the table row according to the selected position.

Now it's possible to resize the height of the table rows
without moving the text cursor inside the table.

Note: This is important for floating tables containing images:
here it's not possible to put the cursor inside the table, if
the image is cropped only by the cell borders: so it was not
possible to resize the row height.

Change-Id: I181d79a28cdeefabb796b7b978ee1368a937
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166793
Tested-by: Jenkins
Reviewed-by: László Németh 
(cherry picked from commit 6c00a73348511b688be214439941e128fc430a34)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167088
Reviewed-by: Michael Stahl 

diff --git a/sw/qa/extras/uiwriter/uiwriter6.cxx 
b/sw/qa/extras/uiwriter/uiwriter6.cxx
index 5b4140e02967..9b8ae0244efe 100644
--- a/sw/qa/extras/uiwriter/uiwriter6.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter6.cxx
@@ -13,6 +13,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1406,6 +1407,71 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, 
testTdf154771_MovingMultipleColumns)
 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable1->getColumns()->getCount());
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf44773)
+{
+// allow resizing table rows, if cursor outside the table
+createSwDoc();
+SwDoc* pDoc = getSwDoc();
+CPPUNIT_ASSERT(pDoc);
+SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+CPPUNIT_ASSERT(pWrtShell);
+
+// insert an empty paragraph
+pWrtShell->SplitNode();
+
+// create a table
+SwInsertTableOptions TableOpt(SwInsertTableFlags::DefaultBorder, 0);
+(void)>InsertTable(TableOpt, 2, 1);
+
+// the cursor is not inside the table
+CPPUNIT_ASSERT(!pWrtShell->IsCursorInTable());
+
+uno::Reference xTablesSupplier(mxComponent, 
uno::UNO_QUERY);
+uno::Reference xTableNames = 
xTablesSupplier->getTextTables();
+CPPUNIT_ASSERT(xTableNames->hasByName("Table1"));
+uno::Reference xTable1(xTableNames->getByName("Table1"), 
uno::UNO_QUERY);
+CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTable1->getRows()->getCount());
+CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTable1->getColumns()->getCount());
+
+Scheduler::ProcessEventsToIdle();
+
+// set table row height by drag & drop
+SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+
+SwFrame* pPage = pLayout->Lower();
+SwFrame* pBody = pPage->GetLower();
+SwFrame* pTable = pBody->GetLower()->GetNext();
+SwFrame* pRow1 = pTable->GetLower();
+CPPUNIT_ASSERT(pRow1->IsRowFrame());
+SwFrame* pCellA1 = pRow1->GetLower();
+const SwRect& rCellA1Rect = pCellA1->getFrameArea();
+auto nRowHeight = rCellA1Rect.Height();
+// select center of the bottom border of the first table cell
+Point ptFrom(rCellA1Rect.Left() + rCellA1Rect.Width() / 2, 
rCellA1Rect.Top() + nRowHeight);
+// double the row height
+Point ptTo(rCellA1Rect.Left() + rCellA1Rect.Width() / 2, rCellA1Rect.Top() 
+ 2 * nRowHeight);
+vcl::Window& rEditWin = pDoc->GetDocShell()->GetView()->GetEditWin();
+Point aFrom = rEditWin.LogicToPixel(ptFrom);
+MouseEvent aClickEvent(aFrom, 1, MouseEventModifiers::SIMPLECLICK | 
MouseEventModifiers::SELECT,
+   MOUSE_LEFT);
+rEditWin.MouseButtonDown(aClickEvent);
+Point aTo = rEditWin.LogicToPixel(ptTo);
+MouseEvent aMoveEvent(aTo, 1, MouseEventModifiers::SIMPLECLICK | 
MouseEventModifiers::SELECT,
+  MOUSE_LEFT);
+TrackingEvent aTEvt(aMoveEvent, TrackingEventFlags::Repeat);
+// drag & drop of cell border inside the document (and outside the table)
+// still based on the ruler code, use that to simulate dragging
+pDoc->GetDocShell()->GetView()->GetVRuler().Tracking(aTEvt);
+TrackingEvent aTEvt2(aMoveEvent, TrackingEventFlags::End);
+pDoc->GetDocShell()->GetView()->GetVRuler().Tracking(aTEvt2);
+Scheduler::ProcessEventsToIdle();
+rEditWin.CaptureMouse();
+rEditWin.ReleaseMouse();
+
+// this was 396 (not modified row height previously)
+CPPUNIT_ASSERT_EQUAL(tools::Long(810), pCellA1->getFrameArea().Height());
+}
+
 

core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-05-08 Thread Miklos Vajna (via logerrit)
 sw/qa/core/txtnode/data/plain-content-control-copy.docx |binary
 sw/qa/core/txtnode/txtnode.cxx  |   23 
 sw/source/core/txtnode/thints.cxx   |4 ++
 3 files changed, 26 insertions(+), 1 deletion(-)

New commits:
commit 32616609c788aa1cf0837af0f387390a23de1766
Author: Miklos Vajna 
AuthorDate: Tue Apr 30 08:44:59 2024 +0200
Commit: Xisco Fauli 
CommitDate: Wed May 8 10:57:56 2024 +0200

tdf#159683 sw content controls, plain text: fix crash with the clipboard doc

Regression from commit c804c5354855188b5a37219cfe11dc079dc235f4 (sw
content control: fix lost properties on copy, 2023-03-10), select
a plain text content control, copy it to the clipboard, quit: assertion
fails during shutdown because the doc's "placeholder text" char style is
still referenced by a client.

What happens here is that the SwContentControl copy ctor copies the
plain text flag, and that flag is only read in SwTextNode::InsertHint(),
so that causes the problem. Note how that code is inconsistent: we avoid
the creation of dummy characters in the copy case, but we still try to
adjust the start/end of the content control attribute in the copy case,
which makes not much sense.

Fix the problem by not adjusting the content control attribute
boundaries in the copy case, since the original intention was to do
thees corrections only at a UI level, during interactive edit.

It's not clear why this inconsistency had an influence on the clients of
the char style, though.

Change-Id: I86b0516464f24fc453dcd97588dafb8afd010a9e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166882
Reviewed-by: Miklos Vajna 
Tested-by: Jenkins
(cherry picked from commit 06aeb9c61d50bba7edafe17f9d3513af26b0782f)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167311
Reviewed-by: Xisco Fauli 

diff --git a/sw/qa/core/txtnode/data/plain-content-control-copy.docx 
b/sw/qa/core/txtnode/data/plain-content-control-copy.docx
new file mode 100644
index ..80fecae26d5b
Binary files /dev/null and 
b/sw/qa/core/txtnode/data/plain-content-control-copy.docx differ
diff --git a/sw/qa/core/txtnode/txtnode.cxx b/sw/qa/core/txtnode/txtnode.cxx
index c2df8a407e69..be4d97190251 100644
--- a/sw/qa/core/txtnode/txtnode.cxx
+++ b/sw/qa/core/txtnode/txtnode.cxx
@@ -539,6 +539,29 @@ CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, 
testSplitFlyAnchorSplit)
 CPPUNIT_ASSERT_EQUAL(OUString("PortionType::Fly"), aPortionType);
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, testPlainContentControlCopy)
+{
+// Given a document with a plain text content control, all text selected 
and copied to the
+// clipboard:
+createSwDoc("plain-content-control-copy.docx");
+SwDocShell* pDocShell = getSwDocShell();
+SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
+pWrtShell->SelAll();
+{
+rtl::Reference xTransfer = new 
SwTransferable(*pWrtShell);
+xTransfer->Copy();
+}
+
+// When closing that document, then make sure we don't crash on shutdown:
+uno::Reference xModel(mxComponent, uno::UNO_QUERY);
+uno::Reference 
xFrame(xModel->getCurrentController()->getFrame(),
+uno::UNO_QUERY);
+// Without the accompanying fix in place, this resulted in an assertion 
failure, a char style
+// still had clients by the time it was deleted.
+xFrame->close(false);
+mxComponent.clear();
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/txtnode/thints.cxx 
b/sw/source/core/txtnode/thints.cxx
index cf5e1ff1cccf..c499294f4f26 100644
--- a/sw/source/core/txtnode/thints.cxx
+++ b/sw/source/core/txtnode/thints.cxx
@@ -1700,7 +1700,9 @@ bool SwTextNode::InsertHint( SwTextAttr * const pAttr, 
const SetAttrMode nMode )
 // for all of its content.
 auto* pTextContentControl = static_txtattr_cast(
 GetTextAttrAt(pAttr->GetStart(), RES_TXTATR_CONTENTCONTROL, 
::sw::GetTextAttrMode::Parent));
-if (pTextContentControl)
+// If the caller is SwTextNode::CopyText, we just copy an existing 
attribute, no need to
+// correct it.
+if (pTextContentControl && !(nMode & SetAttrMode::NOTXTATRCHR))
 {
 auto& rFormatContentControl
 = 
static_cast(pTextContentControl->GetAttr());


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-05-08 Thread Miklos Vajna (via logerrit)
 sw/qa/extras/ww8export/data/draw-obj-rtl-no-mirror-vml.docx |binary
 sw/qa/extras/ww8export/ww8export4.cxx   |   24 
 sw/source/filter/ww8/wrtw8esh.cxx   |6 +++
 3 files changed, 30 insertions(+)

New commits:
commit fe9395164bc4130c83ab75e0c471516f9da61bee
Author: Miklos Vajna 
AuthorDate: Fri May 3 13:54:02 2024 +0200
Commit: Xisco Fauli 
CommitDate: Wed May 8 09:34:09 2024 +0200

Related: tdf#160833 teach DOC export about DoNotMirrorRtlDrawObjs

See

,
no need to undo the import-time mapping in case we know that the
mirroring is avoided at a layout level.

Change-Id: Idbdc10ad327540dc5045e9b19dd42160b5139470
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167049
Reviewed-by: Miklos Vajna 
Tested-by: Jenkins
(cherry picked from commit 9d95eb980ef12678f6fb978badcbe1cacbe0c4dc)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167084
Reviewed-by: Xisco Fauli 

diff --git a/sw/qa/extras/ww8export/data/draw-obj-rtl-no-mirror-vml.docx 
b/sw/qa/extras/ww8export/data/draw-obj-rtl-no-mirror-vml.docx
new file mode 100644
index ..3b291901f72d
Binary files /dev/null and 
b/sw/qa/extras/ww8export/data/draw-obj-rtl-no-mirror-vml.docx differ
diff --git a/sw/qa/extras/ww8export/ww8export4.cxx 
b/sw/qa/extras/ww8export/ww8export4.cxx
index d31bf17a31f6..3fb0ae7b03a4 100644
--- a/sw/qa/extras/ww8export/ww8export4.cxx
+++ b/sw/qa/extras/ww8export/ww8export4.cxx
@@ -252,6 +252,30 @@ CPPUNIT_TEST_FIXTURE(Test, testLegalNumbering)
 verify();
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testDOCExportDoNotMirrorRtlDrawObjs)
+{
+// Given a document with a shape, anchored in an RTL paragraph, loaded 
from DOCX:
+createSwDoc("draw-obj-rtl-no-mirror-vml.docx");
+
+// When saving that to DOC:
+saveAndReload(mpFilter);
+
+// Then make sure the shape is on the right margin:
+xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+sal_Int32 nPageRight = getXPath(pXmlDoc, "//page/infos/bounds"_ostr, 
"right"_ostr).toInt32();
+sal_Int32 nBodyRight = getXPath(pXmlDoc, "//body/infos/bounds"_ostr, 
"right"_ostr).toInt32();
+sal_Int32 nShapeLeft
+= getXPath(pXmlDoc, "//SwAnchoredDrawObject/bounds"_ostr, 
"left"_ostr).toInt32();
+CPPUNIT_ASSERT_GREATER(nBodyRight, nShapeLeft);
+sal_Int32 nShapeRight
+= getXPath(pXmlDoc, "//SwAnchoredDrawObject/bounds"_ostr, 
"right"_ostr).toInt32();
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected less than: 12523
+// - Actual  : 12536
+// i.e. the shape was outside of the page right margin area, due to an 
unwanted mapping.
+CPPUNIT_ASSERT_LESS(nPageRight, nShapeRight);
+}
+
 DECLARE_WW8EXPORT_TEST(testNonInlinePageBreakFirstLine, 
"nonInlinePageBreakFirstLine.doc")
 {
 SwDoc* pDoc = getSwDoc();
diff --git a/sw/source/filter/ww8/wrtw8esh.cxx 
b/sw/source/filter/ww8/wrtw8esh.cxx
index 19ac50ccf5c9..272e3bd27735 100644
--- a/sw/source/filter/ww8/wrtw8esh.cxx
+++ b/sw/source/filter/ww8/wrtw8esh.cxx
@@ -577,6 +577,12 @@ void WW8Export::MiserableRTLFrameFormatHack(SwTwips 
, SwTwips ,
 if (SvxFrameDirection::Horizontal_RL_TB != 
m_rDoc.GetTextDirection(rFrameFormat.GetPosition()))
 return;
 
+if 
(m_rDoc.getIDocumentSettingAccess().get(DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS))
+{
+// Swap is handled at a layout-level, no need to compensate for it at 
export time.
+return;
+}
+
 SwTwips nWidth = rRight - rLeft;
 SwTwips nPageLeft, nPageRight;
 SwTwips nPageSize = CurrentPageWidth(nPageLeft, nPageRight);


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source writerfilter/source

2024-05-07 Thread Michael Stahl (via logerrit)
 sw/qa/extras/ooxmlexport/ooxmlexport17.cxx  |4 -
 sw/source/core/fields/reffld.cxx|   66 +++-
 writerfilter/source/dmapper/StyleSheetTable.cxx |   14 +
 3 files changed, 58 insertions(+), 26 deletions(-)

New commits:
commit 74f859b5525da0760a70ab660bd912dabfd608ca
Author: Michael Stahl 
AuthorDate: Fri May 3 19:31:20 2024 +0200
Commit: Adolfo Jayme Barrientos 
CommitDate: Tue May 7 10:05:17 2024 +0200

tdf#160402 writerfilter,sw: STYLEREF field can refer to character style

Adapt SwGetRefFieldType::FindAnchor() to search for SwTextCharFormat,
and ApplyClonedTOCStylesToXText() to replace "CharStyleName".

Works for the "Intensive Hervorhebung" field in bugdoc.

Change-Id: Iee126eeb4cc2ff1c570941e3beefd93527c56fee
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167098
Reviewed-by: Michael Stahl 
Tested-by: Jenkins
(cherry picked from commit d4fdafa103bfea94a279d7069ddc50ba92f67d01)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167244
Reviewed-by: Adolfo Jayme Barrientos 

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
index f0d5004f73b5..dee26b595c08 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
@@ -746,9 +746,9 @@ DECLARE_OOXMLEXPORT_TEST(testTdf160402, "StyleRef-DE.docx")
 xmlDocUniquePtr pLayout = parseLayoutDump();
 assertXPath(pLayout, 
"/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, 
"expand"_ostr, "Heading 1");
 assertXPath(pLayout, 
"/root/page[2]/header/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, 
"expand"_ostr, "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.");
-assertXPath(pLayout, 
"/root/page[3]/header/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, 
"expand"_ostr, "Error: Reference source not found"); // TODO
+assertXPath(pLayout, 
"/root/page[3]/header/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, 
"expand"_ostr, "Cras faucibus condimentum odio. Sed ac ligula. Aliquam at 
eros.");
 assertXPath(pLayout, 
"/root/page[4]/header/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, 
"expand"_ostr, "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.");
-assertXPath(pLayout, 
"/root/page[5]/header/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, 
"expand"_ostr, "Error: Reference source not found"); // TODO
+assertXPath(pLayout, 
"/root/page[5]/header/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, 
"expand"_ostr, "Aenean nec lorem. In porttitor. Donec laoreet nonummy augue.");
 }
 
 DECLARE_OOXMLEXPORT_TEST(testTdf142407, "tdf142407.docx")
diff --git a/sw/source/core/fields/reffld.cxx b/sw/source/core/fields/reffld.cxx
index 0ee26771bb2c..85a18c78927f 100644
--- a/sw/source/core/fields/reffld.cxx
+++ b/sw/source/core/fields/reffld.cxx
@@ -1220,7 +1220,9 @@ namespace
 /// Picks the first text node with a matching style from a double ended 
queue, starting at the front
 /// This allows us to use the deque either as a stack or as a queue 
depending on whether we want to search up or down
 SwTextNode* SearchForStyleAnchor(SwTextNode* pSelf, const 
std::deque& pToSearch,
-std::u16string_view rStyleName, bool 
bCaseSensitive = true)
+std::u16string_view rStyleName,
+sal_Int32 *const pStart, sal_Int32 *const 
pEnd,
+bool bCaseSensitive = true)
 {
 std::deque pSearching(pToSearch);
 while (!pSearching.empty())
@@ -1235,15 +1237,38 @@ namespace
 if (!pTextNode)
 continue;
 
-if (bCaseSensitive)
+if (bCaseSensitive
+? pTextNode->GetFormatColl()->GetName() == rStyleName
+: 
pTextNode->GetFormatColl()->GetName().equalsIgnoreAsciiCase(rStyleName))
 {
-if (pTextNode->GetFormatColl()->GetName() == rStyleName)
-return pTextNode;
+*pStart = 0;
+if (pEnd)
+{
+*pEnd = pTextNode->GetText().getLength();
+}
+return pTextNode;
 }
-else
+
+if (auto const pHints = pTextNode->GetpSwpHints())
 {
-if 
(pTextNode->GetFormatColl()->GetName().equalsIgnoreAsciiCase(rStyleName))
-return pTextNode;
+for (size_t i = 0; i < pHints->Count(); ++i)
+{
+auto const*const pHint(pHints->Get(i));
+if (pHint->Which() == RES_TXTATR_CHARFMT)
+{
+if (bCaseSensitive
+? 
pHint->GetCharFormat().GetCharFormat()->HasName(rStyleName)
+: 

core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-05-02 Thread Mike Kaganski (via logerrit)
 sw/qa/extras/uiwriter/data/table-in-table.fodt |   29 +
 sw/qa/extras/uiwriter/uiwriter9.cxx|   14 
 sw/source/core/crsr/crsrsh.cxx |   12 +++---
 3 files changed, 52 insertions(+), 3 deletions(-)

New commits:
commit e7803234b5609d6ff66ebe79b7409d0fc822b067
Author: Mike Kaganski 
AuthorDate: Thu May 2 09:11:25 2024 +0500
Commit: Xisco Fauli 
CommitDate: Thu May 2 19:10:37 2024 +0200

tdf#160898: check for nullptr

Regression after commit d81379db730a163c5ff75d4f3a3cddbd7b5eddda
(tdf#154877 sw: generalise ExtendedSelectAll(), 2023-05-09)

Change-Id: I9289171647fca8bd1b696399ff7c43a2ac7b8b30
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166990
Reviewed-by: Mike Kaganski 
Tested-by: Jenkins
Signed-off-by: Xisco Fauli 
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166997
Reviewed-by: Michael Stahl 

diff --git a/sw/qa/extras/uiwriter/data/table-in-table.fodt 
b/sw/qa/extras/uiwriter/data/table-in-table.fodt
new file mode 100644
index ..e055d343b847
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/table-in-table.fodt
@@ -0,0 +1,29 @@
+
+
+
+ 
+  
+   
+  
+ 
+ 
+  
+   
+   
+
+
+ 
+  
+   
+   
+
+   
+  
+  
+ 
+
+   
+   
+  
+ 
+
\ No newline at end of file
diff --git a/sw/qa/extras/uiwriter/uiwriter9.cxx 
b/sw/qa/extras/uiwriter/uiwriter9.cxx
index 3772955dd9c1..fe69b26dd87a 100644
--- a/sw/qa/extras/uiwriter/uiwriter9.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter9.cxx
@@ -200,6 +200,20 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf159816)
 xTransfer->PrivateDrop(*pWrtShell, ptTo, /*bMove=*/true, 
/*bXSelection=*/true);
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf160898)
+{
+// Given a document with a 1-cell table in another 1-cell table:
+createSwDoc("table-in-table.fodt");
+SwXTextDocument* pXTextDocument = 
dynamic_cast(mxComponent.get());
+SwDocShell* pDocShell = pXTextDocument->GetDocShell();
+SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
+
+// Move to the normally hidden paragraph inside the outer table cell, 
following the inner table
+pWrtShell->Down(false, 2);
+// Without the fix, this would crash:
+pWrtShell->SelAll();
+}
+
 } // end of anonymous namespace
 CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index b7f6962982b5..33f11e9a282b 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -738,9 +738,15 @@ bool SwCursorShell::MoveStartText()
 SwTableNode const*const pTable(pStartNode->FindTableNode());
 m_pCurrentCursor->GetPoint()->Assign(*pStartNode);
 GetDoc()->GetNodes().GoNext(m_pCurrentCursor->GetPoint());
-while (m_pCurrentCursor->GetPoint()->GetNode().FindTableNode() != pTable
-&& (!pTable || pTable->GetIndex() < 
m_pCurrentCursor->GetPoint()->GetNode().FindTableNode()->GetIndex())
-&& MoveOutOfTable());
+while (auto* pFoundTable = 
m_pCurrentCursor->GetPoint()->GetNode().FindTableNode())
+{
+if (pFoundTable == pTable)
+break;
+if (pTable && pTable->GetIndex() >= pFoundTable->GetIndex())
+break;
+if (!MoveOutOfTable())
+break;
+}
 
UpdateCursor(SwCursorShell::SCROLLWIN|SwCursorShell::CHKRANGE|SwCursorShell::READONLY);
 return old != *m_pCurrentCursor->GetPoint();
 }


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-04-29 Thread Miklos Vajna (via logerrit)
 sw/qa/core/frmedt/frmedt.cxx |   35 +
 sw/source/core/frmedt/fefly1.cxx |   47 ++-
 2 files changed, 81 insertions(+), 1 deletion(-)

New commits:
commit 008b1c3a8652b33b9b42ca0794a21ce9754e96f2
Author: Miklos Vajna 
AuthorDate: Tue Apr 23 08:29:07 2024 +0200
Commit: Xisco Fauli 
CommitDate: Mon Apr 29 20:51:21 2024 +0200

tdf#159379 sw: fix crash on dropping multiple as-char images

Have an empty Writer document, set preferences so images created via
drag are anchored as-char, drop 2 images from a file manager,
crash.

The root of the problem is that the first image gets dropped fine, but
the second one would be anchored to the currently selected graphic node,
since commit 651527b4efe9700c8c8dff58ce5aa86ad5681f16 (sw: fix
double-click opening frame dialog, not graphic dialog on images,
2022-04-26).

The new SwTextCursor::GetModelPositionForViewPoint() returning a graphic
node for a point inside the image looks correct, so fix the problem by
extending SwFEShell::Insert() to take the anchor position as the anchor
for the new image, in case a graphic node is selected.

The original use-case would use SwEditWin::ExecuteDrop(), but keep the
test simple and invoke the underlying SwFEShell::Insert() instead, that
also triggers the problem.

Change-Id: Ibba57aa28d0616ded16b4abb314f04974f1b8f9a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166499
Tested-by: Jenkins
Reviewed-by: Miklos Vajna 
(cherry picked from commit f9f2b7590bb7b3334d499b6884cc7f3e80843b8c)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166511
Reviewed-by: Xisco Fauli 

diff --git a/sw/qa/core/frmedt/frmedt.cxx b/sw/qa/core/frmedt/frmedt.cxx
index b2a53e60db27..37425c13060e 100644
--- a/sw/qa/core/frmedt/frmedt.cxx
+++ b/sw/qa/core/frmedt/frmedt.cxx
@@ -250,6 +250,41 @@ CPPUNIT_TEST_FIXTURE(SwCoreFrmedtTest, testSplitFlyUnfloat)
 CPPUNIT_ASSERT_EQUAL(static_cast(1), 
pDoc->GetTableFrameFormatCount(/*bUsed=*/true));
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreFrmedtTest, testInsertOnGrfNodeAsChar)
+{
+// Given a selected as-char image:
+createSwDoc();
+SwDoc* pDoc = getSwDocShell()->GetDoc();
+SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
+{
+SfxItemSet aFrameSet(pDoc->GetAttrPool(), svl::Items);
+SwFormatAnchor aAnchor(RndStdIds::FLY_AS_CHAR);
+aFrameSet.Put(aAnchor);
+Graphic aGrf;
+pWrtShell->SwFEShell::Insert(OUString(), OUString(), , 
);
+}
+
+// When inserting another as-char image:
+SfxItemSet aFrameSet(pDoc->GetAttrPool(), svl::Items);
+SwFormatAnchor aAnchor(RndStdIds::FLY_AS_CHAR);
+aFrameSet.Put(aAnchor);
+Graphic aGrf;
+// Without the accompanying fix in place, this call crashed, we try to set 
a graphic node as an
+// anchor of an as-char image (which should be a text node).
+pWrtShell->SwFEShell::Insert(OUString(), OUString(), , );
+
+// Then make sure that the anchor of the second image is next to the first 
anchor:
+CPPUNIT_ASSERT(pDoc->GetSpzFrameFormats());
+sw::FrameFormats& rFormats = 
*pDoc->GetSpzFrameFormats();
+CPPUNIT_ASSERT_EQUAL(static_cast(2), rFormats.size());
+const sw::SpzFrameFormat& rFormat1 = *rFormats[0];
+const SwPosition* pAnchor1 = rFormat1.GetAnchor().GetContentAnchor();
+const sw::SpzFrameFormat& rFormat2 = *rFormats[1];
+const SwPosition* pAnchor2 = rFormat2.GetAnchor().GetContentAnchor();
+CPPUNIT_ASSERT_EQUAL(pAnchor1->nNode, pAnchor2->nNode);
+CPPUNIT_ASSERT_EQUAL(pAnchor1->GetContentIndex() + 1, 
pAnchor2->GetContentIndex());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/frmedt/fefly1.cxx b/sw/source/core/frmedt/fefly1.cxx
index 93ad4212cf65..2e5b8bf53d15 100644
--- a/sw/source/core/frmedt/fefly1.cxx
+++ b/sw/source/core/frmedt/fefly1.cxx
@@ -890,6 +890,43 @@ const SwFrameFormat *SwFEShell::NewFlyFrame( const 
SfxItemSet& rSet, bool bAnchV
 return pRet;
 }
 
+namespace
+{
+/// If pCursor points to an as-char anchored graphic node, then set the node's 
anchor position on
+/// pAnchor and rPam.
+bool SetAnchorOnGrfNodeForAsChar(SwShellCursor *pCursor, SwFormatAnchor* 
pAnchor, std::optional& rPam)
+{
+const SwPosition* pPoint = pCursor->GetPoint();
+if (pAnchor->GetAnchorId() != RndStdIds::FLY_AS_CHAR)
+{
+return false;
+}
+
+if (!pPoint->GetNode().IsGrfNode())
+{
+return false;
+}
+
+SwFrameFormat* pFrameFormat = pPoint->GetNode().GetFlyFormat();
+if (!pFrameFormat)
+{
+return false;
+}
+
+const SwPosition* pContentAnchor = 
pFrameFormat->GetAnchor().GetContentAnchor();
+if (!pContentAnchor)
+{
+return false;
+}
+
+SwPosition aPosition(*pContentAnchor);
+++aPosition.nContent;
+

core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-04-22 Thread Michael Stahl (via logerrit)
 sw/qa/core/text/data/Broken indent demo.odt |binary
 sw/qa/core/text/data/tdf156146.fodt |  281 
 sw/qa/core/text/text.cxx|   62 ++
 sw/source/core/text/inftxt.hxx  |6 
 sw/source/core/text/itratr.hxx  |2 
 sw/source/core/text/itrtxt.hxx  |2 
 6 files changed, 348 insertions(+), 5 deletions(-)

New commits:
commit bd3519a67250550e8b793ca11b1b620feb988dfe
Author: Michael Stahl 
AuthorDate: Thu Apr 18 18:23:29 2024 +0200
Commit: Adolfo Jayme Barrientos 
CommitDate: Mon Apr 22 17:50:10 2024 +0200

tdf#156146 tdf#159903 sw: add unit tests

Unfortunately the actual computed margins are not stored in text
formatting data structures so are only available directly from
SwTextMargin.

Change-Id: Ia7ce5e148194a55b5d9874ed112aaa977ed16c7b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166258
Tested-by: Jenkins
Reviewed-by: Michael Stahl 
(cherry picked from commit 0c7ae3bd96130eaa400d55a3ba9bf1e2fe6600de)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166221
Reviewed-by: Adolfo Jayme Barrientos 

diff --git a/sw/qa/core/text/data/Broken indent demo.odt 
b/sw/qa/core/text/data/Broken indent demo.odt
new file mode 100644
index ..af5928bfa556
Binary files /dev/null and b/sw/qa/core/text/data/Broken indent demo.odt differ
diff --git a/sw/qa/core/text/data/tdf156146.fodt 
b/sw/qa/core/text/data/tdf156146.fodt
new file mode 100644
index ..1587cd945e49
--- /dev/null
+++ b/sw/qa/core/text/data/tdf156146.fodt
@@ -0,0 +1,281 @@
+
+http://www.w3.org/TR/css3-text/; 
xmlns:grddl="http://www.w3.org/2003/g/data-view#; 
xmlns:xhtml="http://www.w3.org/1999/xhtml; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance; 
xmlns:xsd="http://www.w3.org/2001/XMLSchema; 
xmlns:xforms="http://www.w3.org/2002/xforms; 
xmlns:dom="http://www.w3.org/2001/xml-events; 
xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" 
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" 
xmlns:math="http://www.w3.org/1998/Math/MathML; 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:ooo="http://openoffice.org/2004/office; 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" 
xmlns:ooow="http://openoffice.org/2004/writer; 
xmlns:xlink="http://www.w3.org/1999/xlink; 
xmlns:drawooo="http://openoffice.org/2010/draw; 
xmlns:oooc="http://openoffice.org/2004/calc; 
xmlns:dc="http://purl.org/dc/elements/1.1/; xmlns:c
 alcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" 
xmlns:tableooo="http://openoffice.org/2009/table; 
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" 
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" 
xmlns:rpt="http://openoffice.org/2005/report; 
xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0"
 xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" 
xmlns:officeooo="http://openoffice.org/2009/office; 
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" 
xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" 
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" 
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:
 meta:1.0" 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"
 office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ 
2023-06-14T01:10:01.4975110772024-04-18T18:00:26.359273842PT14M47S2ZetaOffice/7.4.8.0.0$Linux_X86_64
 
LibreOffice_project/b82f1163cc2fc696cf86209d94d838d04998350f
+ 
+  
+   false
+   false
+   false
+   true
+   true
+   true
+   true
+   true
+   false
+   0
+   false
+   false
+   false
+   true
+   false
+   false
+   true
+   false
+   false
+   false
+   false
+   true
+   true
+   true
+   false
+   false
+   false
+   false
+   false
+   false
+   false
+   false
+   true
+   false
+   false
+   true
+   false
+   false
+   false
+   true
+   0
+   1
+   true
+   false
+   
+   high-resolution
+   true
+   
+   
+   false
+   false
+   true
+   false
+   true
+   true
+   true
+   false
+   true
+   
+   true
+   910346
+   
+   true
+   false
+   true
+   true
+   0
+   
+   false
+   false
+   false
+   true
+   false
+   true
+   0
+   false
+   false
+   false
+   false
+   true
+   false
+   false
+   false
+   
+   false
+   false
+   true
+   false
+   false
+   false
+   false
+   false
+   false
+   false
+   false
+   false
+   811422
+   false
+   false
+   false
+   false
+   false
+   true
+   false
+   true
+   true
+  
+ 
+ 
+  
+  
+  
+ 

core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-04-19 Thread Mike Kaganski (via logerrit)
 sw/qa/extras/odfexport/data/tdf160700.odt |binary
 sw/qa/extras/odfexport/odfexport2.cxx |   30 ++
 sw/source/core/unocore/unoportenum.cxx|3 +++
 3 files changed, 33 insertions(+)

New commits:
commit 028feacd6a459d613e7a0d12788bf05b0e4c778c
Author: Mike Kaganski 
AuthorDate: Fri Apr 19 00:34:28 2024 +0500
Commit: Xisco Fauli 
CommitDate: Fri Apr 19 10:59:56 2024 +0200

tdf#160700: Avoid both bookmark-start and bookmark-end at the same index

There is a special handling of CrossRefBookmark, which has no end position
in the document model, but must span the whole paragraph, and end position
is generated explicitly.

Since commit 1d7ce421480d9170316533de03feb8d04eb5c767 (tdf#159438: when
there's no frame, close previous bookmark first, 2024-01-30), end marks
of an index are sorted before start marks of the same index, with the
expectation that start / end marks represent non-empty span. Dun in case
of empty paragraphs with a CrossRefBookmark, both start and end mark were
emitted into the same index, and the new sorting resulted in the wrong
order of the elements.

Fix this by checking if the start index is less than node end, and don't
handle CrossRefBookmark specially, if the check is negative. This writes
a single text:bookmark, instead of a text:bookmark-start, followed by a
text:bookmark-end.

Change-Id: I533c4f7814edddc3cf24b1213490f251d60b2273
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166266
Tested-by: Jenkins
Reviewed-by: Mike Kaganski 
Signed-off-by: Xisco Fauli 
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166280

diff --git a/sw/qa/extras/odfexport/data/tdf160700.odt 
b/sw/qa/extras/odfexport/data/tdf160700.odt
new file mode 100644
index ..bc1515da3f82
Binary files /dev/null and b/sw/qa/extras/odfexport/data/tdf160700.odt differ
diff --git a/sw/qa/extras/odfexport/odfexport2.cxx 
b/sw/qa/extras/odfexport/odfexport2.cxx
index 49836082907c..f654821acf6a 100644
--- a/sw/qa/extras/odfexport/odfexport2.cxx
+++ b/sw/qa/extras/odfexport/odfexport2.cxx
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1343,6 +1344,35 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf159438)
 u"bookmark3"_ustr);
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testTdf160700)
+{
+// Given a document with an empty numbered paragraph, and a 
cross-reference to it
+loadAndReload("tdf160700.odt");
+
+// Refresh fields and ensure cross-reference to numbered para is okay
+auto 
xTextFieldsSupplier(mxComponent.queryThrow());
+auto xFieldsAccess(xTextFieldsSupplier->getTextFields());
+
+xFieldsAccess.queryThrow()->refresh();
+
+auto xFields(xFieldsAccess->createEnumeration());
+CPPUNIT_ASSERT(xFields->hasMoreElements());
+auto xTextField(xFields->nextElement().queryThrow());
+// Save must not create markup with text:bookmark-end element before 
text:bookmark-start
+// Withoud the fix, this would fail with
+// - Expected: 1
+// - Actual  : Error: Reference source not found
+// i.e., the bookmark wasn't imported, and the field had no proper source
+CPPUNIT_ASSERT_EQUAL(u"1"_ustr, xTextField->getPresentation(false));
+
+xmlDocUniquePtr pXmlDoc = parseExport("content.xml");
+// Check that we export the bookmark in the empty paragraph as a single 
text:bookmark
+// element. Another walid markup is text:bookmark-start followed by 
text:bookmark-end
+// (in that order). The problem was, that text:bookmark-end was before 
text:bookmark-start.
+assertXPathChildren(pXmlDoc, 
"//office:text/text:list/text:list-item/text:p"_ostr, 1);
+assertXPath(pXmlDoc, 
"//office:text/text:list/text:list-item/text:p/text:bookmark"_ostr);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unoportenum.cxx 
b/sw/source/core/unocore/unoportenum.cxx
index 494cec746865..709d79ef4d4b 100644
--- a/sw/source/core/unocore/unoportenum.cxx
+++ b/sw/source/core/unocore/unoportenum.cxx
@@ -150,8 +150,11 @@ namespace
 bool const hasOther = isExpanded && rStartPos != rEndPos;
 bool const bStartPosInNode = rStartPos.GetNode() == rOwnNode;
 bool const bEndPosInNode = rEndPos.GetNode() == rOwnNode;
+// tdf#160700: Crossrefbookmarks only need separate start and end, 
when the start
+// isn't in the end position (so in empty nodes, no need to handle 
them specially)
 sw::mark::CrossRefBookmark* const pCrossRefMark
 = !isExpanded && bStartPosInNode
+  && rStartPos.GetContentIndex() < 
rStartPos.GetContentNode()->Len()
   ? dynamic_cast(pBkmk)
   : nullptr;
 


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-04-15 Thread Miklos Vajna (via logerrit)
 sw/qa/core/layout/data/bad-split-section.odt |binary
 sw/qa/core/layout/layact.cxx |   22 ++
 sw/source/core/inc/sectfrm.hxx   |2 +-
 sw/source/core/layout/layact.cxx |4 ++--
 4 files changed, 25 insertions(+), 3 deletions(-)

New commits:
commit f9a08c15e3a8fb078c1707d67a998f8c4d670e5a
Author: Miklos Vajna 
AuthorDate: Mon Apr 8 06:36:37 2024 +0200
Commit: Michael Stahl 
CommitDate: Mon Apr 15 09:41:17 2024 +0200

tdf#160067 sw floattable: fix missing move bwd of paras in split section 
frame

The last (5th) paragraph in the index was on page 2, even if page 1
still had space for it.

This is a regression from commit
397d72e582c725d162c7e0b819dc6c0bb62e42b0 (Related: tdf#158986 sw
floattable: fix unexpected page break with sections, 2024-02-23), in
case SwLayAction::FormatLayout() doesn't calc its lower content frames
then this bugdoc is good, but the old bugdoc moves its floating table to
the next page, which would be bad.

Fix the problem by making the condition for this "calc lower in
FormatLayout()" action more strict: only do this for content frames
which are in sections, followed by sections.

Note that probably a cleaner way would be to completely stop calculating
content frames in SwLayAction::FormatLayout() and only do that in
FormatContent(), but then it's not clear how to re-fix tdf#158986, and
at least this resolves the regression.

Change-Id: Id671b3b68d8af8ad1cca3399a9aa028de58df3a0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165878
Reviewed-by: Miklos Vajna 
Tested-by: Jenkins
(cherry picked from commit 607fcac441c7f3a7d3c169c19039e581d707f2bb)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165841
Reviewed-by: Michael Stahl 

diff --git a/sw/qa/core/layout/data/bad-split-section.odt 
b/sw/qa/core/layout/data/bad-split-section.odt
new file mode 100644
index ..6dbd07802dfd
Binary files /dev/null and b/sw/qa/core/layout/data/bad-split-section.odt differ
diff --git a/sw/qa/core/layout/layact.cxx b/sw/qa/core/layout/layact.cxx
index 8923d6b0e89a..9de0c9ebfa43 100644
--- a/sw/qa/core/layout/layact.cxx
+++ b/sw/qa/core/layout/layact.cxx
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 
 namespace
 {
@@ -108,6 +109,27 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFlyInSection)
 CPPUNIT_ASSERT(pPage2);
 CPPUNIT_ASSERT(!pPage2->GetSortedObjs());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testBadSplitSection)
+{
+// Given a document with a section, containing 5 paragraphs:
+createSwDoc("bad-split-section.odt");
+
+// When laying out that document:
+SwDoc* pDoc = getSwDoc();
+SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+
+// Then make sure the entire section is on page 1:
+auto pPage = pLayout->Lower()->DynCastPageFrame();
+CPPUNIT_ASSERT(pPage);
+auto pBody = pPage->FindBodyCont();
+CPPUNIT_ASSERT(pBody);
+auto pSection = dynamic_cast(pBody->GetLastLower());
+CPPUNIT_ASSERT(pSection);
+// Without the fix in place, it would have failed, the section was split 
between page 1 and page
+// 2.
+CPPUNIT_ASSERT(!pSection->GetFollow());
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/inc/sectfrm.hxx b/sw/source/core/inc/sectfrm.hxx
index 69158b335863..3debf367f05a 100644
--- a/sw/source/core/inc/sectfrm.hxx
+++ b/sw/source/core/inc/sectfrm.hxx
@@ -46,7 +46,7 @@ namespace o3tl {
 template<> struct typed_flags : 
is_typed_flags {};
 }
 
-class SwSectionFrame final: public SwLayoutFrame, public SwFlowFrame
+class SW_DLLPUBLIC SwSectionFrame final: public SwLayoutFrame, public 
SwFlowFrame
 , public SvtListener // TODO?
 {
 SwSection* m_pSection;
diff --git a/sw/source/core/layout/layact.cxx b/sw/source/core/layout/layact.cxx
index 1a0a1260a135..ad437f98527f 100644
--- a/sw/source/core/layout/layact.cxx
+++ b/sw/source/core/layout/layact.cxx
@@ -1439,9 +1439,9 @@ bool SwLayAction::FormatLayout( OutputDevice 
*pRenderContext, SwLayoutFrame *pLa
 PopFormatLayout();
 }
 }
-else if (pLay->IsSctFrame() && pLow->IsTextFrame() && pLow == 
pLay->GetLastLower())
+else if (pLay->IsSctFrame() && pLay->GetNext() && 
pLay->GetNext()->IsSctFrame() && pLow->IsTextFrame() && pLow == 
pLay->GetLastLower())
 {
-// else: only calc the last text lower of sections
+// else: only calc the last text lower of sections, followed by 
sections
 pLow->OptCalc();
 }
 


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-04-12 Thread Michael Stahl (via logerrit)
 sw/qa/extras/uiwriter/data/pagebreak-source.fodt |   12 ++--
 sw/qa/extras/uiwriter/data/pagebreak-target.fodt |   12 ++--
 sw/qa/extras/uiwriter/uiwriter.cxx   |   22 +-
 sw/source/core/layout/pagechg.cxx|6 +-
 4 files changed, 42 insertions(+), 10 deletions(-)

New commits:
commit 51dda113fd893fb879c0e8a345bc2b6b99e00771
Author: Michael Stahl 
AuthorDate: Wed Mar 13 09:38:00 2024 +0100
Commit: Caolán McNamara 
CommitDate: Fri Apr 12 09:25:39 2024 +0200

sw: layout: use page style set on hidden paragraph

SwPageFrame::FindPageDesc() now ignores paragraphs hidden for any
reason, but to maintain layout compatibility it should only ignore
paragraphs in a hidden section, not paragraphs hidden by fields.

(regression from commit 0c96119895b347f8eb5bb89f393351bd3c02b9f1)

Change-Id: Iad5e76f5cc437d35b4ae9bde6bc9b73dbe32bf3d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164761
Tested-by: Jenkins
Reviewed-by: Michael Stahl 
(cherry picked from commit 7335babda93974104a39202c434e9499b8086f3a)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164742
Reviewed-by: Caolán McNamara 

diff --git a/sw/qa/extras/uiwriter/data/pagebreak-source.fodt 
b/sw/qa/extras/uiwriter/data/pagebreak-source.fodt
index e09c1b447cfd..cb72fea62a85 100644
--- a/sw/qa/extras/uiwriter/data/pagebreak-source.fodt
+++ b/sw/qa/extras/uiwriter/data/pagebreak-source.fodt
@@ -85,7 +85,7 @@
   

   
-  
+  

   
   
@@ -101,9 +101,17 @@


   
+  
+   
+
+   
+   
+   
+  
  
  
   
+  
  
  
   
@@ -120,4 +128,4 @@

   
  
-
\ No newline at end of file
+
diff --git a/sw/qa/extras/uiwriter/data/pagebreak-target.fodt 
b/sw/qa/extras/uiwriter/data/pagebreak-target.fodt
index f059e33f1514..1219cdd95e25 100644
--- a/sw/qa/extras/uiwriter/data/pagebreak-target.fodt
+++ b/sw/qa/extras/uiwriter/data/pagebreak-target.fodt
@@ -86,7 +86,7 @@
   
  
  
-  
+  

   
   
@@ -104,9 +104,17 @@


   
+  
+   
+
+   
+   
+   
+  
  
  
   
+  
  
  
   
@@ -126,4 +134,4 @@

   
  
-
\ No newline at end of file
+
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx 
b/sw/qa/extras/uiwriter/uiwriter.cxx
index 1fd0ac7cf713..b6913d4f6b53 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -383,6 +383,8 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testCopyPastePageBreak)
 SwDoc* pDoc = getSwDoc();
 
 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+CPPUNIT_ASSERT_EQUAL(tools::Long(5669), 
pWrtShell->GetLayout()->GetLower()->getFramePrintArea().Top());
+
 pWrtShell->SelAll();
 dispatchCommand(mxComponent, ".uno:Copy", {});
 
@@ -395,36 +397,46 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest, 
testCopyPastePageBreak)
 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
 
 CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
-CPPUNIT_ASSERT_EQUAL(OUString("Standard"), 
getProperty(getParagraph(1), "PageDescName"));
+CPPUNIT_ASSERT_EQUAL(OUString("WithMargin"), 
getProperty(getParagraph(1), "PageDescName"));
 CPPUNIT_ASSERT_EQUAL(OUString("TargetSection"), 
pWrtShell->GetCurrSection()->GetSectionName());
+// page style WithMargin is used
+CPPUNIT_ASSERT_EQUAL(tools::Long(5669), 
pWrtShell->GetLayout()->GetLower()->getFramePrintArea().Top());
 
 dispatchCommand(mxComponent, ".uno:Paste", {});
 
 CPPUNIT_ASSERT_EQUAL(2, getParagraphs());
-CPPUNIT_ASSERT_EQUAL(OUString("Standard"), 
getProperty(getParagraph(1), "PageDescName"));
+CPPUNIT_ASSERT_EQUAL(OUString("WithMargin"), 
getProperty(getParagraph(1), "PageDescName"));
 CPPUNIT_ASSERT_EQUAL(size_t(2), pDoc->GetSections().size());
 CPPUNIT_ASSERT_EQUAL(OUString("SourceSection"), 
pWrtShell->GetCurrSection()->GetSectionName());
 // the problem was that there was a page break now
 CPPUNIT_ASSERT_EQUAL(1, getPages());
+// page style WithMargin is used
+CPPUNIT_ASSERT_EQUAL(tools::Long(5669), 
pWrtShell->GetLayout()->GetLower()->getFramePrintArea().Top());
 
 pWrtShell->Undo();
 CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
-CPPUNIT_ASSERT_EQUAL(OUString("Standard"), 
getProperty(getParagraph(1), "PageDescName"));
+CPPUNIT_ASSERT_EQUAL(OUString("WithMargin"), 
getProperty(getParagraph(1), "PageDescName"));
 CPPUNIT_ASSERT_EQUAL(OUString("TargetSection"), 
pWrtShell->GetCurrSection()->GetSectionName());
 CPPUNIT_ASSERT_EQUAL(1, getPages());
+// page style WithMargin is used
+CPPUNIT_ASSERT_EQUAL(tools::Long(5669), 
pWrtShell->GetLayout()->GetLower()->getFramePrintArea().Top());
 
 pWrtShell->Redo();
 CPPUNIT_ASSERT_EQUAL(2, getParagraphs());
-CPPUNIT_ASSERT_EQUAL(OUString("Standard"), 
getProperty(getParagraph(1), "PageDescName"));
+CPPUNIT_ASSERT_EQUAL(OUString("WithMargin"), 
getProperty(getParagraph(1), "PageDescName"));
 CPPUNIT_ASSERT_EQUAL(size_t(2), 

core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-04-12 Thread Michael Stahl (via logerrit)
 sw/qa/extras/uiwriter/data/pagebreak-source.fodt|  123 +++
 sw/qa/extras/uiwriter/data/pagebreak-target.fodt|  129 
 sw/qa/extras/uiwriter/uiwriter.cxx  |  109 +
 sw/qa/extras/uiwriter/uiwriter2.cxx |6 
 sw/qa/extras/uiwriter/uiwriter3.cxx |3 
 sw/source/core/doc/DocumentContentOperationsManager.cxx |   73 -
 sw/source/core/docnode/nodes.cxx|2 
 sw/source/core/edit/edglss.cxx  |8 
 sw/source/core/frmedt/fecopy.cxx|   15 +
 sw/source/core/undo/untblk.cxx  |6 
 sw/source/core/unocore/unotext.cxx  |6 
 11 files changed, 434 insertions(+), 46 deletions(-)

New commits:
commit 6d3b6db240a826113a40df8cb6168816aef3441c
Author: Michael Stahl 
AuthorDate: Mon Mar 4 15:45:07 2024 +0100
Commit: Caolán McNamara 
CommitDate: Fri Apr 12 09:24:54 2024 +0200

sw: SelectAll of section with RES_PAGEDESC corner-case

The main problem here is that if a document has a RES_PAGEDESC on its
first body text node, and you paste a section whose first text node also
has a RES_PAGEDESC, the result inevitably has a page break that wasn't
there before, and which is unwanted.

SwEditShell::CopySelToDoc() needs a change to include the end node of a
section at the start, so it is copied.

Change CopyImplImpl() to insert a non-textnode *before* a text node at
the insert position, instead of after it.  This simplifies the
implementation: only SwFEShell::Paste() needs to care about removing an
empty trailing paragraph, but SwEditShell::CopySelToDoc() needs no
changes; both functions would need to delete the empty paragraph when
inserting after.

Several tests such as CppunitTest_sw_ooxmlexport3 testCrashWhileSave
fail because of this, which can be solved by removing the DelFullPara()
call in SwXText::copyText() that is now unnecessary.

Generalise and simplify the "bAfterTable" code in CopyImplImpl(): it
doesn't really matter what is before the insert position, what matters
is if the pasted text starts with a table or section.

Also, the fly-anchor-correction code (both here and in
SwUndoInserts::RedoImpl()) needs to move to the first text node also in
case a section was inserted (but the equal-looking code *before*
inserting remains as is!), in the situation where the last node will be
deleted.

Now there are some test failures:

  unowriter.cxx:430:Assertion
  Test name: (anonymous 
namespace)::testSectionAnchorCopyTableAtStart::TestBody
  equality assertion failed
  - Expected: quux
  foo
  bar
  - Actual  : quux
  foo

This is because the end position was created from SwNodeIndex aInsPos
only, it needs to take also the aDestIdx from the "if (pEndTextNd)"
branch.

  testTdf134250::TestBody finished in: 867ms
  uiwriter2.cxx:462:Assertion
  Test name: testTdf134250::TestBody
  equality assertion failed
  - Expected: 1
  - Actual  : 2

The section is pasted now, so there are 2.

  uiwriter3.cxx:1519:Assertion
  Test name: testTdf135733::TestBody
  equality assertion failed
  - Expected: 1
  - Actual  : 2

Table is now inserted before the first paragraph, which has a
RES_PAGEDESC.

(presumably regression from commit 9667e5ffd18d6167344e102b89a393bc981644ec)

Change-Id: I820e381113fee90a81249afbc2280bfc3ddb7647
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164401
Tested-by: Jenkins
Reviewed-by: Michael Stahl 
(cherry picked from commit fcd4222d36e1864452163e5c94976eea353bbaf0)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164741
Reviewed-by: Caolán McNamara 

diff --git a/sw/qa/extras/uiwriter/data/pagebreak-source.fodt 
b/sw/qa/extras/uiwriter/data/pagebreak-source.fodt
new file mode 100644
index ..e09c1b447cfd
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/pagebreak-source.fodt
@@ -0,0 +1,123 @@
+
+http://openoffice.org/2009/office; 
xmlns:css3t="http://www.w3.org/TR/css3-text/; 
xmlns:grddl="http://www.w3.org/2003/g/data-view#; 
xmlns:xhtml="http://www.w3.org/1999/xhtml; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance; 
xmlns:xsd="http://www.w3.org/2001/XMLSchema; 
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" 
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" 
xmlns:rpt="http://openoffice.org/2005/report; 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" 
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" 

core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-04-11 Thread Mike Kaganski (via logerrit)
 sw/qa/extras/layout/data/tdf160526.fodt |   47 ++
 sw/qa/extras/layout/data/tdf160549.fodt |   60 +++
 sw/qa/extras/layout/layout3.cxx |   21 ++
 sw/source/core/text/frmform.cxx |  101 +++-
 4 files changed, 216 insertions(+), 13 deletions(-)

New commits:
commit 167be9363ea505b334aa595b273707d7d9217863
Author: Mike Kaganski 
AuthorDate: Sun Apr 7 18:23:52 2024 +0500
Commit: Xisco Fauli 
CommitDate: Thu Apr 11 11:40:45 2024 +0200

tdf#160526, tdf#160549: fix split conditions at page start

A single large object in a paragraph must be moved down, when the page
has other content before this. On the other hand, there must not be
moving down, when an unsuccessful attempt to move was already done (so
the master frame is empty), or even the first time, when the frame is
at the page body start.

Change-Id: Ib8e2fe7b77c622d9cfac22722ca6b55dba7ad8ae
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165869
Tested-by: Jenkins
Reviewed-by: Mike Kaganski 
Signed-off-by: Xisco Fauli 
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165889

diff --git a/sw/qa/extras/layout/data/tdf160526.fodt 
b/sw/qa/extras/layout/data/tdf160526.fodt
new file mode 100644
index ..37cf73fb8e18
--- /dev/null
+++ b/sw/qa/extras/layout/data/tdf160526.fodt
@@ -0,0 +1,47 @@
+
+
+
+ 
+  
+ 
+ 
+  
+   
+   
+  
+  
+   
+   
+  
+  
+ 
+ 
+  
+   
+  
+  
+   
+   
+  
+  
+   
+  
+  
+   
+  
+  
+ 
+ 
+  
+ 
+ 
+  
+   
+ 
+Foo
+   
+ 
+
+  
+ 
+
\ No newline at end of file
diff --git a/sw/qa/extras/layout/data/tdf160549.fodt 
b/sw/qa/extras/layout/data/tdf160549.fodt
new file mode 100644
index ..fd8425eedd86
--- /dev/null
+++ b/sw/qa/extras/layout/data/tdf160549.fodt
@@ -0,0 +1,60 @@
+
+
+
+ 
+  
+ 
+ 
+  
+   
+   
+   
+  
+  
+   
+   
+  
+  
+  
+   
+  
+  
+   
+  
+  
+   
+  
+ 
+ 
+  
+   
+  
+  
+   
+  
+  
+   
+   
+
+   
+  
+ 
+ 
+  
+   
+
+  
+   foobar
+  
+ 
+   
+  
+ 
+ 
+  
+   
+ 
+
+  
+ 
+
\ No newline at end of file
diff --git a/sw/qa/extras/layout/layout3.cxx b/sw/qa/extras/layout/layout3.cxx
index a074a35dc61b..98c77b18ecdf 100644
--- a/sw/qa/extras/layout/layout3.cxx
+++ b/sw/qa/extras/layout/layout3.cxx
@@ -2353,6 +2353,27 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, 
testPageBreakInHiddenSection)
 assertXPath(pXmlDoc, "//page[4]/body/section/infos/bounds"_ostr, 
"height"_ostr, u"0"_ustr);
 }
 
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf160549)
+{
+// Given a document with a large as-char object, alone in its paragraph, 
shifted down by a
+// header object: it must not hang in a layout loop on import (similar to 
i84870, but not
+// fixed by its fix)
+createSwDoc("tdf160549.fodt");
+// The object is the first in the document; it must not move to the next 
page
+CPPUNIT_ASSERT_EQUAL(1, getPages());
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf160526)
+{
+// Given a document with a large as-char object, alone in its paragraph, 
shifted down by
+// another body object
+createSwDoc("tdf160526.fodt");
+// It must move to the next page
+CPPUNIT_ASSERT_EQUAL(2, getPages());
+auto pExportDump = parseLayoutDump();
+assertXPath(pExportDump, 
"//page[2]/body/txt/anchored/SwAnchoredDrawObject"_ostr);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/frmform.cxx b/sw/source/core/text/frmform.cxx
index e19b834a5618..97eff3e607ec 100644
--- a/sw/source/core/text/frmform.cxx
+++ b/sw/source/core/text/frmform.cxx
@@ -1081,6 +1081,54 @@ void SwTextFrame::ChangeOffset( SwTextFrame* pFrame, 
TextFrameIndex nNew )
 MoveFlyInCnt( pFrame, nNew, TextFrameIndex(COMPLETE_STRING) );
 }
 
+static bool isFirstVisibleFrameInBody(const SwTextFrame* pFrame)
+{
+const SwFrame* pBodyFrame = pFrame->FindBodyFrame();
+if (!pBodyFrame)
+return false;
+for (const SwFrame* pCur = pFrame;;)
+{
+for (const SwFrame* pPrev = pCur->GetPrev(); pPrev; pPrev = 
pPrev->GetPrev())
+if (!pPrev->IsHiddenNow())
+return false;
+pCur = pCur->GetUpper();
+assert(pCur); // We found pBodyFrame, right?
+if (pCur->IsBodyFrame())
+return true;
+}
+}
+
+static bool hasFly(const SwTextFrame* pFrame)
+{
+if (auto pDrawObjs = pFrame->GetDrawObjs(); pDrawObjs && pDrawObjs->size())
+{
+auto anchorId = 
(*pDrawObjs)[0]->GetFrameFormat()->GetAnchor().GetAnchorId();
+if (anchorId == RndStdIds::FLY_AT_PARA || anchorId == 
RndStdIds::FLY_AT_CHAR)
+return true;
+}
+return false;
+}
+
+static bool hasAtPageFly(const SwFrame* pFrame)
+{
+auto pPageFrame = pFrame->FindPageFrame();
+if (!pPageFrame)
+return false;
+auto pPageDrawObjs = pPageFrame->GetDrawObjs();
+

core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-04-04 Thread Miklos Vajna (via logerrit)
 sw/qa/core/layout/data/floattable-header.docx |binary
 sw/qa/core/layout/tabfrm.cxx  |   21 +
 sw/source/core/layout/tabfrm.cxx  |   12 +++-
 3 files changed, 32 insertions(+), 1 deletion(-)

New commits:
commit 20de432fa4e6f59476e17c4ced216825f6bbeb80
Author: Miklos Vajna 
AuthorDate: Thu Feb 29 08:17:41 2024 +0100
Commit: Xisco Fauli 
CommitDate: Thu Apr 4 10:34:17 2024 +0200

tdf#158801 sw floattable: fix crash with headers and interactive editing

Regression from commit ce2fc5eb29b4e252993b549dee002fa8948c8386
(tdf#158341 sw floattable: fix layout loop when fly is below the body
frame, 2023-11-29), open the bugdoc, add an empty paragraph at the
start, Writer layout crashes. The immediate problem is that
SwTabFrame::MakeAll() assumes that in case HasFollowFlowLine() is true,
then GetFollow()->GetFirstNonHeadlineRow() is always non-nullptr,
similar to the situation in commit
223d2fac61e061478721a7a4a89b1362f5037d8f (sw floattable: fix crash by
trying harder to split tables, 2023-11-22).

The deeper problem is that the bugdoc has a repeated table header row,
the fly frame temporarily gets shifted down, so nominally the header
doesn't fit anymore, and this leads to a modification of the doc model,
which creates inconsistency: the model now says we have no header rows
but the layout still contains table row frames where the header bit is
true. This is problematic in theory, but in practice caused no problem
so far.

Fix the problem by disabling this mechanism for floating tables: trying
to have a table header that doesn't fit the table is asking for trouble
anyway, and this way at least we have a layout that is consistent with
the model, which also avoids the crash, now that nobody violates the
"HasFollowFlowLine -> follow's FirstNonHeadlineRow != nullptr"
invariant.

Also extend the layout dump, so it's easier to see when the master's
flag and the follow's row list gets out of sync.

Change-Id: I52b51f6d86ab4e0bab560f892e9cceb183aecd5f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164136
Reviewed-by: Miklos Vajna 
Tested-by: Jenkins
(cherry picked from commit 186de7178c6065e1de13fd216b46ac9b716e44c5)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164119
Reviewed-by: Xisco Fauli 

diff --git a/sw/qa/core/layout/data/floattable-header.docx 
b/sw/qa/core/layout/data/floattable-header.docx
new file mode 100644
index ..baddd365ce37
Binary files /dev/null and b/sw/qa/core/layout/data/floattable-header.docx 
differ
diff --git a/sw/qa/core/layout/tabfrm.cxx b/sw/qa/core/layout/tabfrm.cxx
index e0d099c77102..9bfbd1b82e2a 100644
--- a/sw/qa/core/layout/tabfrm.cxx
+++ b/sw/qa/core/layout/tabfrm.cxx
@@ -17,6 +17,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 namespace
 {
@@ -235,6 +237,25 @@ CPPUNIT_TEST_FIXTURE(Test, 
testSplitFlyWrappedByTableNested)
 CPPUNIT_ASSERT_EQUAL(static_cast(3), 
pDoc->GetTableFrameFormats()->GetFormatCount());
 CPPUNIT_ASSERT_EQUAL(static_cast(1), 
pDoc->GetSpzFrameFormats()->GetFormatCount());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testSplitFlyHeader)
+{
+// Given a document with 8 pages: a first page ending in a manual page 
break, then a multi-page
+// floating table on pages 2..8:
+createSwDoc("floattable-header.docx");
+CPPUNIT_ASSERT_EQUAL(8, getPages());
+
+// When creating a new paragraph at doc start:
+SwDocShell* pDocShell = getSwDocShell();
+SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
+pWrtShell->SttEndDoc(/*bStt=*/true);
+pWrtShell->SplitNode();
+// Without the accompanying fix in place, this test would have crashed 
here.
+pWrtShell->CalcLayout();
+
+// Then make sure we get one more page, since the first page is now 2 
pages:
+CPPUNIT_ASSERT_EQUAL(9, getPages());
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index c4a742c0373d..fe3a5232356e 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -1165,7 +1165,13 @@ bool SwTabFrame::Split(const SwTwips nCutPos, bool 
bTryToSplit,
 OSL_ENSURE( !GetIndPrev(), "Table is supposed to be at beginning" );
 if ( !IsInSct() )
 {
-m_pTable->SetRowsToRepeat(0);
+// This would mean the layout modifies the doc model, so 
RowsToRepeat drops to 0 while
+// there are existing row frames with RepeatedHeadline == true. 
Avoid this at least
+// inside split flys, it would lead to a crash in 
SwTabFrame::MakeAll().
+if (!pFly || !pFly->IsFlySplitAllowed())
+{
+m_pTable->SetRowsToRepeat(0);
+}
 return false;
 }
 else
@@ -6371,6 +6377,10 @@ void 

core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-03-31 Thread Samuel Mehrbrodt (via logerrit)
 sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx |   11 +++
 sw/qa/core/accessibilitycheck/data/Tabs-in-TOC.odt   |binary
 sw/source/core/access/AccessibilityCheck.cxx |5 +
 3 files changed, 16 insertions(+)

New commits:
commit 7a61065bb8ccf33fb1918218bf2febd30e786bf4
Author: Samuel Mehrbrodt 
AuthorDate: Mon Mar 18 15:19:42 2024 +0100
Commit: Caolán McNamara 
CommitDate: Sun Mar 31 22:37:34 2024 +0200

tdf#159918 a11y check: Don't warn about tabs in ToC

Change-Id: Ifde41deb66c8dcb72842e18e539609ff351be832
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164972
Tested-by: Jenkins
Reviewed-by: Samuel Mehrbrodt 
(cherry picked from commit c6075e716200e9c6bae1b10be2cf10013958e83a)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165424
Reviewed-by: Caolán McNamara 

diff --git a/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx 
b/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx
index 117b48d01661..bfe2e08d8543 100644
--- a/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx
+++ b/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx
@@ -251,6 +251,17 @@ scanAccessibilityIssuesOnNodes(SwDoc* pDocument)
 return aIssues;
 }
 
+CPPUNIT_TEST_FIXTURE(AccessibilityCheckTest, testCheckTabsinTOC)
+{
+createSwDoc("Tabs-in-TOC.odt");
+SwDoc* pDoc = getSwDoc();
+CPPUNIT_ASSERT(pDoc);
+sw::AccessibilityCheck aCheck(pDoc);
+aCheck.check();
+auto& aIssues = aCheck.getIssueCollection().getIssues();
+CPPUNIT_ASSERT_EQUAL(size_t(0), aIssues.size());
+}
+
 void checkIssuePosition(std::shared_ptr const& 
pIssue, int nLine,
 sal_Int32 nStart, sal_Int32 nEnd, SwNodeOffset nIndex)
 {
diff --git a/sw/qa/core/accessibilitycheck/data/Tabs-in-TOC.odt 
b/sw/qa/core/accessibilitycheck/data/Tabs-in-TOC.odt
new file mode 100644
index ..2b3ce54cc5a3
Binary files /dev/null and b/sw/qa/core/accessibilitycheck/data/Tabs-in-TOC.odt 
differ
diff --git a/sw/source/core/access/AccessibilityCheck.cxx 
b/sw/source/core/access/AccessibilityCheck.cxx
index e515b5cae7ed..dfa94c3ed9ab 100644
--- a/sw/source/core/access/AccessibilityCheck.cxx
+++ b/sw/source/core/access/AccessibilityCheck.cxx
@@ -901,6 +901,11 @@ public:
 }
 case ' ':
 {
+// Don't warn about tabs in ToC
+auto pSection = 
SwDoc::GetCurrSection(SwPosition(*pTextNode, 0));
+if (pSection && pSection->GetTOXBase())
+continue;
+
 if (bPreviousWasChar)
 {
 ++nTabCount;


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-03-27 Thread Mike Kaganski (via logerrit)
 sw/qa/extras/htmlexport/data/tdf160390.fodt |   17 +++
 sw/qa/extras/htmlexport/htmlexport.cxx  |7 
 sw/source/filter/html/htmlatr.cxx   |   40 +---
 3 files changed, 43 insertions(+), 21 deletions(-)

New commits:
commit 832fb1ab9abf94f4074e0cc20d846c1536931cf3
Author: Mike Kaganski 
AuthorDate: Wed Mar 27 16:01:51 2024 +0500
Commit: Xisco Fauli 
CommitDate: Wed Mar 27 22:03:48 2024 +0100

tdf#160390: make sure to forward the iterator

Change-Id: I302cc4303f083a1024175ce4ba00ce8021c6d4c9
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165390
Tested-by: Jenkins
Reviewed-by: Mike Kaganski 
Signed-off-by: Xisco Fauli 
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165404

diff --git a/sw/qa/extras/htmlexport/data/tdf160390.fodt 
b/sw/qa/extras/htmlexport/data/tdf160390.fodt
new file mode 100644
index ..53d6144ff19b
--- /dev/null
+++ b/sw/qa/extras/htmlexport/data/tdf160390.fodt
@@ -0,0 +1,17 @@
+
+
+
+ 
+  
+   
+  
+  
+   
+  
+ 
+ 
+  
+   foo 

+  
+ 
+
\ No newline at end of file
diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx 
b/sw/qa/extras/htmlexport/htmlexport.cxx
index de2e9da4c678..42099f3bc44f 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -3053,6 +3053,13 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, 
testHTML_Tdf160017_spanClosingOrder)
 CPPUNIT_ASSERT(parseXml(maTempFile));
 }
 
+CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testHTML_Tdf160390)
+{
+// This document must not hang infinitely on HTML export
+createSwDoc("tdf160390.fodt");
+ExportToHTML();
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/html/htmlatr.cxx 
b/sw/source/filter/html/htmlatr.cxx
index c880082018f1..f298f93dc5b2 100644
--- a/sw/source/filter/html/htmlatr.cxx
+++ b/sw/source/filter/html/htmlatr.cxx
@@ -1524,8 +1524,9 @@ void HTMLEndPosLst::SplitItem( const SfxPoolItem& rItem, 
sal_Int32 nStart,
 
 for (auto it = items.begin(); it != items.end();)
 {
-HTMLStartEndPos* pTest = *it;
-sal_Int32 nTestEnd = pTest->GetEnd();
+auto itTest = it++; // forward early, allow 'continue', and keep a 
copy for 'erase'
+HTMLStartEndPos* pTest = *itTest;
+const sal_Int32 nTestEnd = pTest->GetEnd();
 if (nTestEnd <= nStart)
 continue;
 
@@ -1533,28 +1534,25 @@ void HTMLEndPosLst::SplitItem( const SfxPoolItem& 
rItem, sal_Int32 nStart,
 const SfxPoolItem& rTestItem = pTest->GetItem();
 
 // only the corresponding OnTag attributes have to be considered
-if (rTestItem.Which() == nWhich && HTML_ON_VALUE == 
GetHTMLItemState(rTestItem))
-{
-// if necessary, insert the second part of the split
-// attribute
-if (nTestEnd > nEnd)
-InsertItem(pTest->GetItem(), nEnd, nTestEnd);
+if (rTestItem.Which() != nWhich || HTML_ON_VALUE != 
GetHTMLItemState(rTestItem))
+continue;
 
-if (nTestStart >= nStart)
-{
-// the Test item only starts after the new end of the
-// attribute. Therefore, it can be completely erased.
-it = items.erase(it);
-std::erase(m_aEndLst[pTest->GetEnd()], pTest);
-delete pTest;
-continue;
-}
+// if necessary, insert the second part of the split attribute
+if (nTestEnd > nEnd)
+InsertItem(rTestItem, nEnd, nTestEnd);
 
-// the start of the new attribute corresponds to the new
-// end of the attribute
-FixSplittedItem(pTest, nStart);
+if (nTestStart >= nStart)
+{
+// the Test item only starts after the new end of the
+// attribute. Therefore, it can be completely erased.
+it = items.erase(itTest);
+std::erase(m_aEndLst[nTestEnd], pTest);
+delete pTest;
+continue;
 }
-++it;
+
+// the start of the new attribute corresponds to the new end of 
the attribute
+FixSplittedItem(pTest, nStart);
 }
 }
 }


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-03-22 Thread Michael Stahl (via logerrit)
 sw/qa/extras/uiwriter/uiwriter5.cxx |2 --
 sw/source/core/undo/untbl.cxx   |   15 ++-
 2 files changed, 14 insertions(+), 3 deletions(-)

New commits:
commit 36757ace36a5bcb0acd9ba5c4ee6cceed3c14b67
Author: Michael Stahl 
AuthorDate: Thu Mar 14 12:14:28 2024 +0100
Commit: Xisco Fauli 
CommitDate: Fri Mar 22 20:49:16 2024 +0100

sw: fix ~SwIndexReg assert in testTdf149498

The problem is that a SwNavigationMgr thingy has a cursor in one of the
table cells, and the text node is moved to the undo nodes array in
SwUndoTableCpyTable::AddBoxBefore() and deleted in
SwUndoTableCpyTable::UndoImpl().

SwUndoTableCpyTable needs to move the cursors out of the way because
SwUndoDelete doesn't do it.

Change-Id: I75e271c84a6624ffb0df151b171acb1e1f743928
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164807
Tested-by: Jenkins
Reviewed-by: Michael Stahl 
(cherry picked from commit 873af30a36504751c6923d4235abd4de040e0001)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164820
Reviewed-by: Xisco Fauli 

diff --git a/sw/qa/extras/uiwriter/uiwriter5.cxx 
b/sw/qa/extras/uiwriter/uiwriter5.cxx
index c6353f980d29..702f6d7dd30e 100644
--- a/sw/qa/extras/uiwriter/uiwriter5.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter5.cxx
@@ -3007,7 +3007,6 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest5, testTdf156487)
 assertXPath(pXmlDoc, "/metafile/push/push/push/textarray/text"_ostr, 1);
 }
 
-#ifndef DBG_UTIL
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5, testTdf149498)
 {
 // load a table, and delete the first column with enabled change tracking:
@@ -3023,7 +3022,6 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest5, testTdf149498)
 // this would crash due to bookmark over cell boundary
 dispatchCommand(mxComponent, ".uno:Undo", {});
 }
-#endif
 
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest5, 
testTdf150673_RedlineTableColumnDeletionWithExport)
 {
diff --git a/sw/source/core/undo/untbl.cxx b/sw/source/core/undo/untbl.cxx
index 72f1c809e227..52157df0cae1 100644
--- a/sw/source/core/undo/untbl.cxx
+++ b/sw/source/core/undo/untbl.cxx
@@ -2599,11 +2599,17 @@ void SwUndoTableCpyTable::AddBoxBefore( const 
SwTableBox& rBox, bool bDelContent
 if( bDelContent )
 {
 SwNodeIndex aInsIdx( *rBox.GetSttNd(), 1 );
-pDoc->GetNodes().MakeTextNode( aInsIdx.GetNode(), 
pDoc->GetDfltTextFormatColl() );
+SwTextNode *const 
pNewNode(pDoc->GetNodes().MakeTextNode(aInsIdx.GetNode(), 
pDoc->GetDfltTextFormatColl()));
 SwPaM aPam( aInsIdx.GetNode(), *rBox.GetSttNd()->EndOfSectionNode() );
 
 if( !pDoc->getIDocumentRedlineAccess().IsRedlineOn() )
+{
+{   // move cursors to new node which precedes aPam
+SwPosition const pos(*pNewNode, 0);
+::PaMCorrAbs(aPam, pos);
+}
 pEntry->pUndo = std::make_unique(aPam, 
SwDeleteFlags::Default, true);
+}
 }
 
 pEntry->pBoxNumAttr = std::make_uniqueGetDoc();
 DEBUG_REDLINE( pDoc )
 
+{   // move cursors to first node which was inserted
+SwPaM pam(SwNodeIndex(*rBox.GetSttNd(), 1));
+assert(pam.GetPoint()->GetNode().IsTextNode());
+pam.SetMark();
+pam.Move(fnMoveForward, GoInContent);
+::PaMCorrAbs(pam, *pam.GetPoint());
+}
 if( pDoc->getIDocumentRedlineAccess().IsRedlineOn() )
 {
 SwPosition aTmpPos( rIdx );


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-03-22 Thread Michael Stahl (via logerrit)
 sw/qa/core/unocore/unocore.cxx   |   27 +++
 sw/source/core/unocore/unocrsrhelper.cxx |2 +-
 2 files changed, 28 insertions(+), 1 deletion(-)

New commits:
commit 0398d6900835ff29767f7ac39bc7fb57917d8ccd
Author: Michael Stahl 
AuthorDate: Fri Mar 22 12:28:43 2024 +0100
Commit: Christian Lohmaier 
CommitDate: Fri Mar 22 19:47:40 2024 +0100

sw: GetSelectableFromAny() broken for SwXTextRange

The function unnecessarily uses an intermediate XUnoTunnel variable to
handle SwXTextRange, but the implementation of XUnoTunnel was removed.

(regression from commit 635448a996714a81cb15b41ac4bb0c73cabfb74f)

Change-Id: I90dd7acbd259e8ca562a534ad0bc9a5b85356553
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165162
Reviewed-by: Noel Grandin 
Tested-by: Jenkins
Reviewed-by: Michael Stahl 
(cherry picked from commit 8f2de92b3da99346f7282e623d47912f40f92b7b)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165170
Reviewed-by: Christian Lohmaier 

diff --git a/sw/qa/core/unocore/unocore.cxx b/sw/qa/core/unocore/unocore.cxx
index 381fe0dab3e2..3e52b12a363c 100644
--- a/sw/qa/core/unocore/unocore.cxx
+++ b/sw/qa/core/unocore/unocore.cxx
@@ -78,6 +78,33 @@ CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, testTdf119081)
 CPPUNIT_ASSERT_EQUAL(OUString("x"), 
pWrtShell->GetCurrentShellCursor().GetText());
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, selectTextRange)
+{
+createSwDoc();
+uno::Reference const xTD(mxComponent, 
uno::UNO_QUERY_THROW);
+uno::Reference const xText(xTD->getText());
+uno::Reference const xCursor(xText->createTextCursor());
+xText->insertString(xCursor, "test", /*bAbsorb=*/false);
+xCursor->gotoStart(false);
+xCursor->gotoEnd(true);
+CPPUNIT_ASSERT_EQUAL(OUString("test"), xCursor->getString());
+uno::Reference const xMSF(mxComponent, 
uno::UNO_QUERY_THROW);
+uno::Reference const xSection(
+xMSF->createInstance("com.sun.star.text.TextSection"), 
uno::UNO_QUERY_THROW);
+xText->insertTextContent(xCursor, xSection, true);
+uno::Reference const xAnchor(xSection->getAnchor());
+uno::Reference const 
xView(xTD->getCurrentController(),
+ uno::UNO_QUERY);
+CPPUNIT_ASSERT_EQUAL(OUString("test"), xAnchor->getString());
+CPPUNIT_ASSERT(xView->select(uno::Any(xAnchor)));
+uno::Reference xSel;
+CPPUNIT_ASSERT(xView->getSelection() >>= xSel);
+CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSel->getCount());
+uno::Reference xSelRange;
+CPPUNIT_ASSERT(xSel->getByIndex(0) >>= xSelRange);
+CPPUNIT_ASSERT_EQUAL(OUString("test"), xSelRange->getString());
+}
+
 CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, flyAtParaAnchor)
 {
 createSwDoc();
diff --git a/sw/source/core/unocore/unocrsrhelper.cxx 
b/sw/source/core/unocore/unocrsrhelper.cxx
index 70a724814cc6..30f6d6e6190e 100644
--- a/sw/source/core/unocore/unocrsrhelper.cxx
+++ b/sw/source/core/unocore/unocrsrhelper.cxx
@@ -225,7 +225,7 @@ void GetSelectableFromAny(uno::Reference 
const& xIfc,
 return;
 }
 
-uno::Reference const xTextRange(xTunnel, UNO_QUERY);
+uno::Reference const xTextRange(xIfc, UNO_QUERY);
 if (xTextRange.is())
 {
 SwUnoInternalPaM aPam(rTargetDoc);


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-03-22 Thread Mike Kaganski (via logerrit)
 sw/qa/extras/unowriter/unowriter.cxx |   21 +
 sw/source/core/unocore/unoobj.cxx|   12 +---
 2 files changed, 30 insertions(+), 3 deletions(-)

New commits:
commit 41586f2f417a2d55d6baa07d3885d2d117a16d1d
Author: Mike Kaganski 
AuthorDate: Wed Mar 20 16:24:07 2024 +0500
Commit: Xisco Fauli 
CommitDate: Fri Mar 22 08:35:46 2024 +0100

tdf#160278: restore cursor bounds properly

The passed string length is not a correct measure of how many steps
should the selection expand in the resulting text: the cursor goes
over glyphs, not over UTF-16 code units. Thus, it's easier to store
the position prior to insertion, and restore it from the indexes.

Change-Id: I1d592ff30199007ba3a99d7e1a6d2db2da35f1cb
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165056
Tested-by: Jenkins
Reviewed-by: Mike Kaganski 
Signed-off-by: Xisco Fauli 
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165145

diff --git a/sw/qa/extras/unowriter/unowriter.cxx 
b/sw/qa/extras/unowriter/unowriter.cxx
index 8bcadbaf4227..80b9e556f73b 100644
--- a/sw/qa/extras/unowriter/unowriter.cxx
+++ b/sw/qa/extras/unowriter/unowriter.cxx
@@ -1201,6 +1201,27 @@ CPPUNIT_TEST_FIXTURE(SwUnoWriter, testTdf129841)
 CPPUNIT_ASSERT_EQUAL(aRefColor, aColor);
 }
 
+CPPUNIT_TEST_FIXTURE(SwUnoWriter, testTdf160278)
+{
+createSwDoc();
+auto xTextDocument(mxComponent.queryThrow());
+auto xText(xTextDocument->getText());
+xText->setString(u"123"_ustr);
+CPPUNIT_ASSERT_EQUAL(u"123"_ustr, xText->getString());
+auto xCursor = xText->createTextCursorByRange(xText->getEnd());
+xCursor->goLeft(1, true);
+CPPUNIT_ASSERT_EQUAL(u"3"_ustr, xCursor->getString());
+// Insert an SMP character U+1f702 (so it's two UTF-16 code units, 0xd83d 
0xdf02):
+xCursor->setString(u""_ustr);
+// Without the fix, the replacement would expand the cursor one too many 
characters to the left,
+// and the cursor text would become "2", failing the next test:
+CPPUNIT_ASSERT_EQUAL(u""_ustr, xCursor->getString());
+xCursor->setString(u"test"_ustr);
+CPPUNIT_ASSERT_EQUAL(u"test"_ustr, xCursor->getString());
+// This test would fail, too; the text would be "1test":
+CPPUNIT_ASSERT_EQUAL(u"12test"_ustr, xText->getString());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unoobj.cxx 
b/sw/source/core/unocore/unoobj.cxx
index 49562c1d0284..df02c4773a15 100644
--- a/sw/source/core/unocore/unoobj.cxx
+++ b/sw/source/core/unocore/unoobj.cxx
@@ -752,13 +752,19 @@ void SwXTextCursor::DeleteAndInsert(std::u16string_view 
aText,
 }
 if(nTextLen)
 {
+// Store node and content indexes prior to insertion: to select 
the inserted text,
+// we need to account for possible surrogate pairs, combining 
characters, etc.; it
+// is easier to just restore the correct position from the indexes.
+const auto start = pCurrent->Start();
+const auto nodeIndex = start->GetNodeIndex();
+const auto contentIndex = start->GetContentIndex();
 const bool bSuccess(
 SwUnoCursorHelper::DocInsertStringSplitCR(
-rDoc, *pCurrent, aText, bool(eMode & 
::sw::DeleteAndInsertMode::ForceExpandHints)));
+rDoc, SwPaM(*start, pCurrent), aText, bool(eMode & 
::sw::DeleteAndInsertMode::ForceExpandHints)));
 OSL_ENSURE( bSuccess, "Doc->Insert(Str) failed." );
 
-SwUnoCursorHelper::SelectPam(*pUnoCursor, true);
-pCurrent->Left(aText.size());
+pCurrent->SetMark();
+pCurrent->GetPoint()->Assign(nodeIndex, contentIndex);
 }
 pCurrent = pCurrent->GetNext();
 } while (pCurrent != pUnoCursor);


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-03-08 Thread Miklos Vajna (via logerrit)
 sw/qa/core/layout/data/floattable-in-section.docx |binary
 sw/qa/core/layout/layact.cxx  |   22 ++
 sw/source/core/layout/layact.cxx  |6 +-
 3 files changed, 27 insertions(+), 1 deletion(-)

New commits:
commit a85bd1bc9305af059d880ee422a656a3d9ce1b0b
Author: Miklos Vajna 
AuthorDate: Fri Feb 23 09:12:17 2024 +0100
Commit: Michael Stahl 
CommitDate: Fri Mar 8 20:57:51 2024 +0100

Related: tdf#158986 sw floattable: fix unexpected page break with sections

Regression from commit c303981cfd95ce1c3881366023d5495ae2edce97
(tdf#156724 sw: layout: fix tables not splitting due to footnotes
differently, 2023-08-24), the floating table in the DOCX version of the
bugdoc went from page 1 to page 2.

It seems what happens is that the first page has 2 section frames, and
we used to directly recalc the last lower of the first section frame,
which triggered a recalc of the second section frame, so the table moved
from page 2 to page 1 once the top of the second section frame was
reduced (so the table could fit on page 1). But this direct recalc was
removed because it caused problems for split tables and footnotes in
tdf#156724.

Fix the problem by conditionally restoring the OptCalc() call in
SwLayAction::FormatLayout(): only do it for the last lower of section
frames, which is enough for the DOCX version of tdf#158986, but it keeps
the old tdf#156724 use-case working (the layout of that bugdoc doesn't
modify with this change).

The RTF version of the bugdoc (which was the originally reported
problem) still needs more work, but that's hopefully not a layout
problem but an RTF import one.

Change-Id: I1134ec3a27aec8ee871b535d81dedf9d27bd6bd5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163805
Reviewed-by: Miklos Vajna 
Tested-by: Jenkins
(cherry picked from commit 397d72e582c725d162c7e0b819dc6c0bb62e42b0)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163768
Reviewed-by: Michael Stahl 

diff --git a/sw/qa/core/layout/data/floattable-in-section.docx 
b/sw/qa/core/layout/data/floattable-in-section.docx
index a0e9090bcccf..9aab264867f0 100644
Binary files a/sw/qa/core/layout/data/floattable-in-section.docx and 
b/sw/qa/core/layout/data/floattable-in-section.docx differ
diff --git a/sw/qa/core/layout/layact.cxx b/sw/qa/core/layout/layact.cxx
index d432ae52b7c5..8923d6b0e89a 100644
--- a/sw/qa/core/layout/layact.cxx
+++ b/sw/qa/core/layout/layact.cxx
@@ -86,6 +86,28 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf157096)
 
 CPPUNIT_ASSERT_EQUAL(1, getPages());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testSplitFlyInSection)
+{
+// Given a document with multiple sections, the 2nd section on page 1 has 
a one-page floating
+// table:
+createSwDoc("floattable-in-section.docx");
+
+// When laying out that document:
+SwDoc* pDoc = getSwDoc();
+SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+
+// Then make sure the table is on page 1, not on page 2:
+auto pPage1 = pLayout->Lower()->DynCastPageFrame();
+CPPUNIT_ASSERT(pPage1);
+// Without the fix in place, it would have failed, the table was on page 
2, not on page 1.
+CPPUNIT_ASSERT(pPage1->GetSortedObjs());
+SwSortedObjs& rPage1Objs = *pPage1->GetSortedObjs();
+CPPUNIT_ASSERT_EQUAL(static_cast(1), rPage1Objs.size());
+auto pPage2 = pPage1->GetNext()->DynCastPageFrame();
+CPPUNIT_ASSERT(pPage2);
+CPPUNIT_ASSERT(!pPage2->GetSortedObjs());
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/layact.cxx b/sw/source/core/layout/layact.cxx
index a705ef251176..06c3027bebc5 100644
--- a/sw/source/core/layout/layact.cxx
+++ b/sw/source/core/layout/layact.cxx
@@ -1433,7 +1433,11 @@ bool SwLayAction::FormatLayout( OutputDevice 
*pRenderContext, SwLayoutFrame *pLa
 PopFormatLayout();
 }
 }
-// else: don't calc content frames any more
+else if (pLay->IsSctFrame() && pLow->IsTextFrame() && pLow == 
pLay->GetLastLower())
+{
+// else: only calc the last text lower of sections
+pLow->OptCalc();
+}
 
 if ( IsAgain() )
 return false;


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-03-07 Thread Miklos Vajna (via logerrit)
 sw/qa/extras/ww8export/data/listWithLgl.doc |binary
 sw/qa/extras/ww8export/ww8export4.cxx   |   24 
 sw/source/filter/ww8/wrtw8num.cxx   |9 -
 sw/source/filter/ww8/ww8par3.cxx|   11 +++
 4 files changed, 43 insertions(+), 1 deletion(-)

New commits:
commit 58b5f3399e1c4ce56180cb49c5d228ca92ccc8d3
Author: Miklos Vajna 
AuthorDate: Tue Feb 27 08:29:31 2024 +0100
Commit: Christian Lohmaier 
CommitDate: Thu Mar 7 12:07:26 2024 +0100

Related: tdf#150408 DOC filter: handle legal numbering

The bugdoc's 2nd para started with 'Sect I.01', while Word rendered this
as 'Sect 1.01'.

The reason for this difference is that there is an "is legal" boolean
property on the numbering that we ignored from [MS-DOC] during
import/export.

Fix the problem by WW8ListManager::ReadLVL() and
WW8AttributeOutput::NumberingLevel() to handle this, building on top of
the existing DOCX work.

RTF still needs doing.

Change-Id: I57ec402c1dd829251afa639ddfa7fc6620da1125
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164000
Reviewed-by: Miklos Vajna 
Tested-by: Jenkins
(cherry picked from commit a73b3994fb6a2cc10b2d65cbaad201762610cecc)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163973
Reviewed-by: Christian Lohmaier 

diff --git a/sw/qa/extras/ww8export/data/listWithLgl.doc 
b/sw/qa/extras/ww8export/data/listWithLgl.doc
new file mode 100644
index ..94de2967febc
Binary files /dev/null and b/sw/qa/extras/ww8export/data/listWithLgl.doc differ
diff --git a/sw/qa/extras/ww8export/ww8export4.cxx 
b/sw/qa/extras/ww8export/ww8export4.cxx
index d47c934d9dd6..d31bf17a31f6 100644
--- a/sw/qa/extras/ww8export/ww8export4.cxx
+++ b/sw/qa/extras/ww8export/ww8export4.cxx
@@ -228,6 +228,30 @@ DECLARE_WW8EXPORT_TEST(testInlinePageBreakFirstLine, 
"inlinePageBreakFirstLine.d
 CPPUNIT_ASSERT(IsFirstLine(aTextNodes[2]));
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testLegalNumbering)
+{
+auto verify = [this]() {
+// Second level's numbering should use Arabic numbers for first level 
reference
+auto xPara = getParagraph(1);
+CPPUNIT_ASSERT_EQUAL(OUString("CH I"), getProperty(xPara, 
"ListLabelString"));
+xPara = getParagraph(2);
+// Without the accompanying fix in place, this test would have failed 
with:
+// - Expected: Sect 1.01
+// - Actual  : Sect I.01
+// i.e. fLegal was ignored on import/export.
+CPPUNIT_ASSERT_EQUAL(OUString("Sect 1.01"), 
getProperty(xPara, "ListLabelString"));
+xPara = getParagraph(3);
+CPPUNIT_ASSERT_EQUAL(OUString("CH II"), getProperty(xPara, 
"ListLabelString"));
+xPara = getParagraph(4);
+CPPUNIT_ASSERT_EQUAL(OUString("Sect 2.01"), 
getProperty(xPara, "ListLabelString"));
+};
+
+createSwDoc("listWithLgl.doc");
+verify();
+saveAndReload(mpFilter);
+verify();
+}
+
 DECLARE_WW8EXPORT_TEST(testNonInlinePageBreakFirstLine, 
"nonInlinePageBreakFirstLine.doc")
 {
 SwDoc* pDoc = getSwDoc();
diff --git a/sw/source/filter/ww8/wrtw8num.cxx 
b/sw/source/filter/ww8/wrtw8num.cxx
index 8d59434db652..681961a3770c 100644
--- a/sw/source/filter/ww8/wrtw8num.cxx
+++ b/sw/source/filter/ww8/wrtw8num.cxx
@@ -279,7 +279,7 @@ void WW8AttributeOutput::NumberingLevel( sal_uInt8 
/*nLevel*/,
 sal_Int16 nListTabPos,
 const OUString ,
 const SvxBrushItem* pBrush, //For i120928,to transfer graphic of bullet
-bool /*isLegal*/
+bool isLegal
 )
 {
 // Start value
@@ -303,6 +303,13 @@ void WW8AttributeOutput::NumberingLevel( sal_uInt8 
/*nLevel*/,
 nAlign = 0;
 break;
 }
+
+if (isLegal)
+{
+// 3rd bit.
+nAlign |= 0x04;
+}
+
 m_rWW8Export.m_pTableStrm->WriteUChar( nAlign );
 
 // Write the rgbxchNums[9], positions of placeholders for paragraph
diff --git a/sw/source/filter/ww8/ww8par3.cxx b/sw/source/filter/ww8/ww8par3.cxx
index d0a294b14450..41b203f92496 100644
--- a/sw/source/filter/ww8/ww8par3.cxx
+++ b/sw/source/filter/ww8/ww8par3.cxx
@@ -368,6 +368,8 @@ struct WW8LVL   // only THE entries, WE need!
 short   nDxaLeft1;  // first line indent
 
 sal_uInt8   nNFC;   // number format code
+/// Legal numbering: whether this level overrides the nfc of all inherited 
level numbers.
+bool fLegal;
 // Offset of fieldcodes in Num-X-String
 sal_uInt8   aOfsNumsXCH[WW8ListManager::nMaxLevel];
 sal_uInt8   nLenGrpprlChpx; // length, in bytes, of the LVL's grpprlChpx
@@ -662,7 +664,15 @@ bool WW8ListManager::ReadLVL(SwNumFormat& rNumFormat, 
std::unique_ptr(aLVL.nStartAt));
 rNumFormat.SetNumberingType( nType );
+rNumFormat.SetIsLegal(aLVL.fLegal);
 rNumFormat.SetNumAdjust( eAdj );
 
 if( style::NumberingType::CHAR_SPECIAL == nType )


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-02-23 Thread Justin Luth (via logerrit)
 sw/qa/extras/rtfexport/data/tdf159824_axialGradient.odt |binary
 sw/qa/extras/rtfexport/rtfexport8.cxx   |   34 
 sw/source/filter/ww8/rtfattributeoutput.cxx |6 ++
 3 files changed, 40 insertions(+)

New commits:
commit bb207d7816c2d32d02ee11ff784d405d2bb5de0f
Author: Justin Luth 
AuthorDate: Wed Feb 21 11:52:36 2024 -0500
Commit: Michael Stahl 
CommitDate: Fri Feb 23 17:41:15 2024 +0100

tdf#159824 MCGR rtf export: don't lose gradient's axial-ness

This fixes alg's 7.6 regression from
commit bb198176684c3d9377e26c04a29ec66deb811949

Found when trying to import these strung-out-linears
as real axials.

make CppunitTest_sw_rtfexport \
CPPUNIT_TEST_NAME=testTdf159824_axialGradient

Change-Id: I220f1bf689b4b219bc0ae187e95aedb1a29a7233
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163705
Tested-by: Jenkins
Reviewed-by: Justin Luth 
Reviewed-by: Miklos Vajna 
(cherry picked from commit 9ba68c769d41d1075152a22bf37e78fb9320317b)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163769
Reviewed-by: Michael Stahl 

diff --git a/sw/qa/extras/rtfexport/data/tdf159824_axialGradient.odt 
b/sw/qa/extras/rtfexport/data/tdf159824_axialGradient.odt
new file mode 100644
index ..c1ce5cd31d2a
Binary files /dev/null and 
b/sw/qa/extras/rtfexport/data/tdf159824_axialGradient.odt differ
diff --git a/sw/qa/extras/rtfexport/rtfexport8.cxx 
b/sw/qa/extras/rtfexport/rtfexport8.cxx
index c78298c0..ab787919dfa9 100644
--- a/sw/qa/extras/rtfexport/rtfexport8.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport8.cxx
@@ -10,6 +10,8 @@
 #include 
 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -21,7 +23,9 @@
 #include 
 #include 
 
+#include 
 #include 
+#include 
 #include 
 #include 
 
@@ -178,6 +182,36 @@ DECLARE_RTFEXPORT_TEST(testTdf158826_extraCR, 
"tdf158826_extraCR.rtf")
 uno::Reference xTable(getParagraphOrTable(1), 
uno::UNO_QUERY_THROW);
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testTdf159824_axialGradient)
+{
+// given a frame with an axial gradient (white - green - white)
+loadAndReload("tdf159824_axialGradient.odt");
+
+uno::Reference xTextFramesSupplier(mxComponent, 
uno::UNO_QUERY);
+uno::Reference 
xIndexAccess(xTextFramesSupplier->getTextFrames(),
+ uno::UNO_QUERY);
+uno::Reference xFrame(xIndexAccess->getByIndex(0), 
uno::UNO_QUERY);
+CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT,
+ getProperty(xFrame, "FillStyle"));
+awt::Gradient2 aGradient = getProperty(xFrame, 
"FillGradient");
+
+//const Color aColA(0x127622); // green
+//const Color aColB(0xff); // white
+
+// MCGR: Use the completely imported transparency gradient to check for 
correctness
+basegfx::BColorStops aColorStops = 
model::gradient::getColorStopsFromUno(aGradient.ColorStops);
+
+// expected: a 3-color linear gradient (or better yet a 2-color AXIAL 
gradient)
+CPPUNIT_ASSERT_EQUAL(size_t(3), aColorStops.size());
+CPPUNIT_ASSERT_EQUAL(awt::GradientStyle_LINEAR, aGradient.Style);
+CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[0].getStopOffset(), 
0.0));
+//CPPUNIT_ASSERT_EQUAL(aColB, Color(aColorStops[0].getStopColor()));
+// CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[1].getStopOffset(), 
0.5));
+// CPPUNIT_ASSERT_EQUAL(aColA, Color(aColorStops[1].getStopColor()));
+// CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[2].getStopOffset(), 
1.0));
+// CPPUNIT_ASSERT_EQUAL(aColB, Color(aColorStops[2].getStopColor()));
+}
+
 DECLARE_RTFEXPORT_TEST(testTdf158830, "tdf158830.rtf")
 {
 //check centered text in table
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx 
b/sw/source/filter/ww8/rtfattributeoutput.cxx
index 8635022bad24..7dcda8f73fb2 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -3754,6 +3754,12 @@ void RtfAttributeOutput::FormatFillGradient(const 
XFillGradientItem& rFillGradie
 const Color aEndColor(rColorStops.back().getStopColor());
 m_aFlyProperties.push_back(std::make_pair(
 "fillBackColor"_ostr, 
OString::number(wwUtility::RGBToBGR(aEndColor;
+
+if (rGradient.GetGradientStyle() == awt::GradientStyle_AXIAL)
+{
+m_aFlyProperties.push_back(
+std::make_pair("fillFocus"_ostr, 
OString::number(50)));
+}
 }
 else
 {


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-02-21 Thread Mike Kaganski (via logerrit)
 sw/qa/extras/uiwriter/uiwriter9.cxx |   41 
 sw/source/core/doc/DocumentContentOperationsManager.cxx |   14 -
 2 files changed, 52 insertions(+), 3 deletions(-)

New commits:
commit 344c18c8e54a4382f7b990b58ed4c083d0568f74
Author: Mike Kaganski 
AuthorDate: Wed Feb 21 16:20:08 2024 +0600
Commit: Xisco Fauli 
CommitDate: Wed Feb 21 21:16:15 2024 +0100

tdf#159813, tdf#159816: Use correct copied PaM

This fixes both the assertion in CopyFlyInFlyImpl (tdf#159813) and
crash in BigPtrArray::operator[] (tdf#159816).

Change-Id: Ia3424e3a58c7d8fb3e1257dcdbf062fb893da8db
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163683
Tested-by: Jenkins
Reviewed-by: Mike Kaganski 
Signed-off-by: Xisco Fauli 
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163698

diff --git a/sw/qa/extras/uiwriter/uiwriter9.cxx 
b/sw/qa/extras/uiwriter/uiwriter9.cxx
index 58c95f21d03d..3772955dd9c1 100644
--- a/sw/qa/extras/uiwriter/uiwriter9.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter9.cxx
@@ -28,8 +28,10 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
+#include 
 
 namespace
 {
@@ -159,6 +161,45 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf159565)
  xSelection->getString());
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf159816)
+{
+createSwDoc();
+
+SwDoc* pDoc = getSwDoc();
+CPPUNIT_ASSERT(pDoc);
+SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+CPPUNIT_ASSERT(pWrtShell);
+
+// Add 5 empty paragraphs
+pWrtShell->SplitNode();
+pWrtShell->SplitNode();
+pWrtShell->SplitNode();
+pWrtShell->SplitNode();
+pWrtShell->SplitNode();
+
+// Add a bookmark at the very end
+IDocumentMarkAccess& rIDMA(*pDoc->getIDocumentMarkAccess());
+rIDMA.makeMark(*pWrtShell->GetCursor(), "Mark", 
IDocumentMarkAccess::MarkType::BOOKMARK,
+   sw::mark::InsertMode::New);
+
+// Get coordinates of the end point in the document
+SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+SwFrame* pPage = pLayout->Lower();
+SwFrame* pBody = pPage->GetLower();
+SwFrame* pLastPara = 
pBody->GetLower()->GetNext()->GetNext()->GetNext()->GetNext()->GetNext();
+Point ptTo = pLastPara->getFrameArea().BottomRight();
+
+pWrtShell->SelAll();
+
+// Drag-n-drop to its own end
+rtl::Reference xTransfer = new SwTransferable(*pWrtShell);
+// Without the fix, this would crash: either in CopyFlyInFlyImpl 
(tdf#159813):
+// Assertion failed: !pCopiedPaM || pCopiedPaM->End()->GetNode() == 
rRg.aEnd.GetNode()
+// or in BigPtrArray::operator[] (tdf#159816):
+// Assertion failed: idx < m_nSize
+xTransfer->PrivateDrop(*pWrtShell, ptTo, /*bMove=*/true, 
/*bXSelection=*/true);
+}
+
 } // end of anonymous namespace
 CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx 
b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index 09e0a1233e5d..57b8e58310d9 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -3788,11 +3788,16 @@ void DocumentContentOperationsManager::CopyWithFlyInFly(
 SwDoc& rDest = rInsPos.GetDoc();
 SwNodeIndex aSavePos( rInsPos );
 
+SwPaM aCopiedPaM(rRg.aStart, rRg.aEnd);
+if (pCopiedPaM)
+aCopiedPaM = pCopiedPaM->first;
+
 if (rRg.aStart != rRg.aEnd)
 {
 bool bEndIsEqualEndPos = rInsPos == rRg.aEnd.GetNode();
 --aSavePos;
 SaveRedlEndPosForRestore aRedlRest( rInsPos, 0 );
+auto savedEndContentIndex = aCopiedPaM.End()->GetContentIndex();
 
 // insert behind the already copied start node
 m_rDoc.GetNodes().CopyNodes( rRg, rInsPos, false, true );
@@ -3801,6 +3806,10 @@ void DocumentContentOperationsManager::CopyWithFlyInFly(
 if (bEndIsEqualEndPos)
 {
 const_cast(rRg.aEnd).Assign(aSavePos.GetNode(), +1);
+// pCopiedPaM->first now spans a range from the start of the 
original selection
+// to the end of newly added text, and the insertion point is in 
the middle of
+// that range. Adjust the local copy to cover the original copied 
PaM.
+aCopiedPaM.End()->Assign(rRg.aEnd, savedEndContentIndex);
 }
 }
 
@@ -3810,7 +3819,6 @@ void DocumentContentOperationsManager::CopyWithFlyInFly(
 // sw_fieldmarkhide: also needs to be done before making frames
 if (m_rDoc.getIDocumentMarkAccess()->getAllMarksCount())
 {
-SwPaM aRgTmp( rRg.aStart, rRg.aEnd );
 SwPosition targetPos(aSavePos, SwNodeOffset(rRg.aStart != rRg.aEnd ? 
+1 : 0));
 if (pCopiedPaM && rRg.aStart != pCopiedPaM->first.Start()->GetNode())
 {
@@ -3823,7 +3831,7 @@ void DocumentContentOperationsManager::CopyWithFlyInFly(
 targetPos = pCopiedPaM->second;
 }
 
-

core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-02-20 Thread Miklos Vajna (via logerrit)
 sw/qa/core/layout/data/floattable-wrapped-by-table-nested.docx |binary
 sw/qa/core/layout/tabfrm.cxx   |   14 
++
 sw/source/core/layout/tabfrm.cxx   |   10 ++-
 3 files changed, 23 insertions(+), 1 deletion(-)

New commits:
commit 287d13d643bb98416baaf52179c1b32e70f2d269
Author: Miklos Vajna 
AuthorDate: Tue Feb 20 08:06:08 2024 +0100
Commit: Michael Stahl 
CommitDate: Tue Feb 20 19:12:52 2024 +0100

tdf#159285 sw floattable: fix loop with inner table wrapped by inner table

Regression from 868140fcc1311259b9d5f37b33d226511a53 (tdf#60558 sw
floattable: allow wrap of table on the right of a floattable,
2023-12-05), the bugdoc layout looped on load.

Somehow the big while() loop in SwTabFrame::MakeAll() never finishes: it
always tries again but can't reach a state where all of frame area
position, frame area size and frame print area is valid.

Fix the problem by going back to the old behavior (floating table is
wrapped by text frames, not by table frames) for the nested table case:
that keeps the old tdf#60558 use-case working and fixes the new
tdf#159285 use-case.

At some point it would be useful to support the combination of nested
floating tables and the "floating table wrapped by table" combination,
but that will be a new layout feature.

Change-Id: Ia3fdbd08de87e13ddef086ae1339e79a8833674d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163630
Reviewed-by: Miklos Vajna 
Tested-by: Jenkins
(cherry picked from commit 2da4acdbf8c5a8ba3ef51e5f5dc3439716e71a91)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163612
Reviewed-by: Michael Stahl 

diff --git a/sw/qa/core/layout/data/floattable-wrapped-by-table-nested.docx 
b/sw/qa/core/layout/data/floattable-wrapped-by-table-nested.docx
new file mode 100644
index ..d6950a6c8e04
Binary files /dev/null and 
b/sw/qa/core/layout/data/floattable-wrapped-by-table-nested.docx differ
diff --git a/sw/qa/core/layout/tabfrm.cxx b/sw/qa/core/layout/tabfrm.cxx
index 61b1a25109f5..e0d099c77102 100644
--- a/sw/qa/core/layout/tabfrm.cxx
+++ b/sw/qa/core/layout/tabfrm.cxx
@@ -221,6 +221,20 @@ CPPUNIT_TEST_FIXTURE(Test, testInlineTableThenSplitFly)
 // large positive one.
 CPPUNIT_ASSERT_LESS(static_cast(0), nInlineLeft);
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testSplitFlyWrappedByTableNested)
+{
+// Given a document with 3 tables, one inline toplevel and two inner ones 
(one inline, one
+// floating):
+// When laying out that document:
+// Without the accompanying fix in place, this test would have failed here 
with a layout loop.
+createSwDoc("floattable-wrapped-by-table-nested.docx");
+
+// Than make sure we have 3 tables, but only one of them is floating:
+SwDoc* pDoc = getSwDoc();
+CPPUNIT_ASSERT_EQUAL(static_cast(3), 
pDoc->GetTableFrameFormats()->GetFormatCount());
+CPPUNIT_ASSERT_EQUAL(static_cast(1), 
pDoc->GetSpzFrameFormats()->GetFormatCount());
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index a04f9a14a7b3..8c49106364dc 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -3373,7 +3373,15 @@ bool SwTabFrame::CalcFlyOffsets( SwTwips& rUpper,
 }
 
 bool bFlyHoriOrientLeft = text::HoriOrientation::LEFT == 
rHori.GetHoriOrient();
-if (bSplitFly && !bFlyHoriOrientLeft)
+
+bool bToplevelSplitFly = false;
+if (bSplitFly)
+{
+// Floating table wrapped by table: avoid this in the nested case.
+bToplevelSplitFly = !pFly->GetAnchorFrame()->IsInTab();
+}
+
+if (bToplevelSplitFly && !bFlyHoriOrientLeft)
 {
 // Only shift to the right if we don't have enough space on the 
left.
 SwTwips nTabWidth = getFramePrintArea().Width();


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source writerfilter/source

2024-02-12 Thread Michael Stahl (via logerrit)
 sw/qa/extras/rtfexport/data/fdo55504-1-min.rtf   |   49 +++
 sw/qa/extras/rtfexport/rtfexport2.cxx|3 -
 sw/qa/extras/rtfexport/rtfexport8.cxx|   25 ++-
 sw/source/core/unocore/unotext.cxx   |3 +
 writerfilter/source/rtftok/rtfdispatchsymbol.cxx |3 -
 writerfilter/source/rtftok/rtfdocumentimpl.cxx   |6 ++
 writerfilter/source/rtftok/rtfsdrimport.hxx  |1 
 7 files changed, 85 insertions(+), 5 deletions(-)

New commits:
commit 14d1ec9a26248f2023a697fc4458ec6422a2ae71
Author: Michael Stahl 
AuthorDate: Fri Feb 9 17:51:03 2024 +0100
Commit: Xisco Fauli 
CommitDate: Mon Feb 12 14:07:29 2024 +0100

tdf#158983 writerfilter: RTF import: fix page breaks and shape anchors

Somehow, not sure why, the added import of \wrapdefault in commit
86c0f58b6f9f392865196606173d1b98a6897f32 caused the page break in
fdo55504-1.rtf to get lost.

The first problem is that there is a \sbknone before the first \sect -
this should not have any effect before \sect because \sbk* affect the
*previous* section break, but it's not an option to simply ignore it
(even if it works for this bugdoc) because it may be that there is no
\sectd after \sect and then it will have an effect for the later
section.

The problem was in handling \page: here the premature \sbknone caused a
sectBreak() which ate the page break; ignore it here by checking
m_bHadSect.

The second problem then was that now all but the first shape were
anchored on page 2.

This was because RTFDocumentImpl::beforePopState() for \shape of the 1st
shape called parBreak() and that set the bIsFirstParaInSection flag.

This flag prevented DomainMapper::lcl_utext() in the
"if (m_pImpl->isBreakDeferred(PAGE_BREAK)) if 
(GetSplitPgBreakAndParaMark())"
branch from inserting another paragraph break that is necessary to
preserve the already inserted shapes anchored to the 2nd paragraph on
page 1.

(This is how it works for the equivalent DOCX document, with settings.xml
edited to add w:splitPgBreakAndParaMark and remove "compatibilityMode"
etc. because Word 2013 doesn't set these correctly.)

The consequence is that when the second SwTextNode is converted to a
text frame, all the shape anchors move to the next paragraph, the one
with the RES_BREAK on it.

Fix this by limiting the parBreak() handling in
RTFDocumentImpl::beforePopState() to when the shape is a SwGrfNode,
which is the scenario in the commit 0d9132c5046e15540abc20e45d64080708626441
"fdo#47036 fix RTF import of shapes inside text frames at the start of the 
doc"
- the testFdo47036 fails if the block is removed completely.

This caused 2 test failures, but both cases look the same as in Word
2013 now:

  Test name: (anonymous 
namespace)::testTdf158826_extraCR::Load_Verify_Reload_Verify
  An uncaught exception of type com.sun.star.uno.RuntimeException
  - unsatisfied query for interface of type com.sun.star.text.XTextTable!

  rtfexport2.cxx:537:Assertion
  Test name: (anonymous namespace)::testFdo47495::Load_Verify_Reload_Verify
  equality assertion failed
  - Expected: 2
  - Actual  : 1

Change-Id: I43fa9431721650a6d748d1f4bda9aeaa7a9c6b45
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163200
Tested-by: Jenkins
Reviewed-by: Michael Stahl 
(cherry picked from commit 582ef812702413dbe7fb0f132bca3e3e4c2e1d40)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163181
Reviewed-by: Xisco Fauli 

diff --git a/sw/qa/extras/rtfexport/data/fdo55504-1-min.rtf 
b/sw/qa/extras/rtfexport/data/fdo55504-1-min.rtf
new file mode 100644
index ..6e7667629969
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/fdo55504-1-min.rtf
@@ -0,0 +1,49 @@
+{ 
tf1deflang1025nsinsicpg1251\uc1deff0\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang1049\deflangfe1049{
onttbl{0romancharset204prq2{\*\panose 02020603050405020304}Times New 
Roman;}{1swisscharset204prq2{\*\panose 020b0604020202020204}Arial;}{39
romancharset0prq2 Times New Roman;}
+{37romancharset238prq2 Times New Roman CE;}{40romancharset161prq2 
Times New Roman Greek;}{41romancharset162prq2 Times New Roman Tur;}{42
bidi romancharset177prq2 Times New Roman (Hebrew);}
+{43bidi romancharset178prq2 Times New Roman (Arabic);}{44roman
charset186prq2 Times New Roman Baltic;}{45romancharset163prq2 Times New 
Roman (Vietnamese);}{49swisscharset0prq2 Arial;}
+{47swisscharset238prq2 Arial CE;}{50swisscharset161prq2 Arial Greek;}{
51swisscharset162prq2 Arial Tur;}{52bidi swisscharset177prq2 Arial 
(Hebrew);}{53bidi swisscharset178prq2 Arial (Arabic);}
+{54swisscharset186prq2 Arial Baltic;}{55swisscharset163prq2 Arial 
(Vietnamese);}}{+ ed255\green255lue0; 

core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-01-31 Thread Miklos Vajna (via logerrit)
 sw/qa/core/text/itrform2.cxx |   40 +++
 sw/source/core/text/itrform2.cxx |9 ++--
 2 files changed, 47 insertions(+), 2 deletions(-)

New commits:
commit e5f43ead6411e656f01e22b8e60b3e093cc391b0
Author: Miklos Vajna 
AuthorDate: Tue Jan 30 16:51:49 2024 +0100
Commit: Xisco Fauli 
CommitDate: Wed Jan 31 12:49:26 2024 +0100

tdf#159452 sw content control, PDF export: fix checked checkboxes

Regression from commit 9bad5be0ffdcdee92d40162b598ed2ab2815e5d5 (sw
content controls, checkbox: add PDF export, 2022-09-13), we used to
export checkbox content controls as plain text, but once checkbox
content controls are exported as forms, the state of the checkboxes are
lost.

Writer content control checkboxes support custom values for the checked
and unchecked states, but the PDF export does not. On one hand,
PDFWriterImpl::createDefaultCheckBoxAppearance() assumes that the
checked state should be a checkmark, not the Writer default 'BALLOT BOX
WITH X' (U+2612). On the other hand, the PDF spec section 12.7.4.2.3
"Check Boxes" says that the checked state should be "Yes", which
explains why our checked state is not recognized by PDF readers.

Fix the problem by making the export of checked/unchecked states
conditional in SwContentControlPortion::DescribePDFControl(): the
checked state then shows up as expected.

Leave the unchecked case unchanged, the current markup there doesn't
cause problems.

Change-Id: I9063d8607c8cccfa080921af38b3cbfe40905115
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162765
Reviewed-by: Miklos Vajna 
Tested-by: Jenkins
(cherry picked from commit 256e2c679bcbb3ea446884d0ff4e3f8687b82ede)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162729
Reviewed-by: Xisco Fauli 

diff --git a/sw/qa/core/text/itrform2.cxx b/sw/qa/core/text/itrform2.cxx
index fc8e981dcf5f..6d59140f97f0 100644
--- a/sw/qa/core/text/itrform2.cxx
+++ b/sw/qa/core/text/itrform2.cxx
@@ -16,6 +16,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 
 namespace
 {
@@ -166,6 +170,42 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFlyAnchorLeftMargin)
 // i.e. the left margin was lost.
 CPPUNIT_ASSERT_EQUAL(static_cast(6480), 
pLastPara->getFramePrintArea().Left());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testCheckedCheckboxContentControlPDF)
+{
+std::shared_ptr pPDFium = vcl::pdf::PDFiumLibrary::get();
+if (!pPDFium)
+return;
+
+// Given a file with a checked checkbox content control:
+createSwDoc();
+SwDoc* pDoc = getSwDoc();
+SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+pWrtShell->InsertContentControl(SwContentControlType::CHECKBOX);
+// Toggle it, so we get a checked one:
+SwTextContentControl* pTextContentControl = 
pWrtShell->CursorInsideContentControl();
+const SwFormatContentControl& rFormatContentControl = 
pTextContentControl->GetContentControl();
+pWrtShell->GotoContentControl(rFormatContentControl);
+
+// When exporting to PDF:
+save("writer_pdf_Export");
+
+// Then make sure that a checked checkbox form widget is emitted:
+std::unique_ptr pPdfDocument = parsePDFExport();
+std::unique_ptr pPage = pPdfDocument->openPage(0);
+CPPUNIT_ASSERT_EQUAL(1, pPage->getAnnotationCount());
+std::unique_ptr pAnnotation = 
pPage->getAnnotation(0);
+CPPUNIT_ASSERT_EQUAL(vcl::pdf::PDFAnnotationSubType::Widget, 
pAnnotation->getSubType());
+CPPUNIT_ASSERT_EQUAL(vcl::pdf::PDFFormFieldType::CheckBox,
+ pAnnotation->getFormFieldType(pPdfDocument.get()));
+OUString aActual = pAnnotation->getFormFieldValue(pPdfDocument.get());
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected: Yes
+// - Actual  : Off
+// i.e. the /AP -> /N key of the checkbox widget annotation object didn't 
have a sub-key that
+// would match /V, leading to not showing the checked state.
+CPPUNIT_ASSERT_EQUAL(OUString("Yes"), aActual);
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index f38bba2ef751..6623000c335f 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -1018,8 +1018,13 @@ bool SwContentControlPortion::DescribePDFControl(const 
SwTextPaintInfo& rInf) co
 pDescriptor = std::make_unique();
 auto pCheckBoxWidget = 
static_cast(pDescriptor.get());
 pCheckBoxWidget->Checked = pContentControl->GetChecked();
-pCheckBoxWidget->OnValue = pContentControl->GetCheckedState();
-pCheckBoxWidget->OffValue = pContentControl->GetUncheckedState();
+// If it's checked already, then leave the default "Yes" OnValue 
unchanged, so the
+// appropriate appearance is found by 

core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-01-25 Thread Xisco Fauli (via logerrit)
 sw/qa/core/text/data/tdf159336.odt |binary
 sw/qa/core/text/text.cxx   |   35 +++
 sw/source/core/text/itrform2.cxx   |2 ++
 3 files changed, 37 insertions(+)

New commits:
commit c2032ed42ea8a44bd3a5f8e8a778e05005366099
Author: Xisco Fauli 
AuthorDate: Tue Jan 23 15:28:26 2024 +0100
Commit: Michael Stahl 
CommitDate: Thu Jan 25 11:42:52 2024 +0100

tdf#159336: export EditWidget with multiline enabled

How to reproduce it from scratch:
1. Open writer
2. Form - Content Controls - Rich Text/Plain Text
3. Split the control intro different lines
4. Export to PDF

-> The content control is displayed in one line

Change-Id: Ia8666c8a6520e94ae06693ea8767c1d79aa5d3a0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162446
Reviewed-by: Xisco Fauli 
Tested-by: Jenkins
(cherry picked from commit 8a6c9e246c746792fa0ab9d47a0fd5928b77d91d)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162532
Reviewed-by: Michael Stahl 

diff --git a/sw/qa/core/text/data/tdf159336.odt 
b/sw/qa/core/text/data/tdf159336.odt
new file mode 100644
index ..4f396e4f2abb
Binary files /dev/null and b/sw/qa/core/text/data/tdf159336.odt differ
diff --git a/sw/qa/core/text/text.cxx b/sw/qa/core/text/text.cxx
index d61492d43d61..690fc333afb5 100644
--- a/sw/qa/core/text/text.cxx
+++ b/sw/qa/core/text/text.cxx
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -115,6 +116,40 @@ CPPUNIT_TEST_FIXTURE(SwCoreTextTest, 
testLastBibliographyPdfExport)
 CPPUNIT_ASSERT(true);
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testTdf159336)
+{
+createSwDoc("tdf159336.odt");
+save("writer_pdf_Export");
+
+vcl::filter::PDFDocument aDocument;
+SvFileStream aStream(maTempFile.GetURL(), StreamMode::READ);
+CPPUNIT_ASSERT(aDocument.Read(aStream));
+
+// The document has one page.
+std::vector aPages = aDocument.GetPages();
+CPPUNIT_ASSERT_EQUAL(static_cast(1), aPages.size());
+
+auto pAnnots = 
dynamic_cast(aPages[0]->Lookup("Annots"_ostr));
+CPPUNIT_ASSERT(pAnnots);
+
+CPPUNIT_ASSERT_EQUAL(static_cast(1), 
pAnnots->GetElements().size());
+auto pAnnotReference
+= 
dynamic_cast(pAnnots->GetElements()[0]);
+CPPUNIT_ASSERT(pAnnotReference);
+vcl::filter::PDFObjectElement* pAnnot = pAnnotReference->LookupObject();
+CPPUNIT_ASSERT(pAnnot);
+CPPUNIT_ASSERT_EQUAL(
+"Annot"_ostr,
+
static_cast(pAnnot->Lookup("Type"_ostr))->GetValue());
+CPPUNIT_ASSERT_EQUAL(
+"Widget"_ostr,
+
static_cast(pAnnot->Lookup("Subtype"_ostr))->GetValue());
+// Ff = multiline
+auto pFf = 
dynamic_cast(pAnnot->Lookup("Ff"_ostr));
+CPPUNIT_ASSERT(pFf);
+CPPUNIT_ASSERT_EQUAL(4096.0, pFf->GetValue());
+}
+
 CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testBibliographyUrlPdfExport)
 {
 // Given a document with a bibliography entry field:
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index 4305e9d0948c..f38bba2ef751 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -1009,6 +1009,8 @@ bool SwContentControlPortion::DescribePDFControl(const 
SwTextPaintInfo& rInf) co
 case SwContentControlType::PLAIN_TEXT:
 {
 pDescriptor = std::make_unique();
+auto pEditWidget = 
static_cast(pDescriptor.get());
+pEditWidget->MultiLine = true;
 break;
 }
 case SwContentControlType::CHECKBOX:


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-01-24 Thread Miklos Vajna (via logerrit)
 sw/qa/core/layout/data/floattable-not-wrapped-by-table.docx |binary
 sw/qa/core/layout/tabfrm.cxx|   22 
 sw/source/core/layout/tabfrm.cxx|   15 ++--
 3 files changed, 33 insertions(+), 4 deletions(-)

New commits:
commit 5df7c66193d55af944b3269f11374e60da437c0b
Author: Miklos Vajna 
AuthorDate: Tue Jan 23 15:34:07 2024 +0100
Commit: Xisco Fauli 
CommitDate: Wed Jan 24 10:14:10 2024 +0100

tdf#159017 sw floattable: only shift to the right when needed

Regression from commit 868140fcc1311259b9d5f37b33d226511a53
(tdf#60558 sw floattable: allow wrap of table on the right of a
floattable, 2023-12-05), the document had an inline table, followed by a
floating table, and we moved the inline table to the right even if the
left hand side of the floating table already had enough space.

What happens here is that nominally the inline table's original position
overlaps, but because the table width is small enough, such an overlap
doesn't actually happen. In this case, it's not needed to shift the
inline table to the right.

Fix the problem by making the check that decides whether it's necessary
to increment the left margin of the table more strict: it's not enough
to have enough space on the right of the fly, it's also needed to *not*
have enough space on the left side.

This keeps the original "floating table wrapped by inline table on the
right" use-case working, but restores the ~no left margin for the inline
table for the new bugdoc.

Change-Id: Ifb30d90ca6dba7cc4a402d8a4445251120b575ae
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162447
Reviewed-by: Miklos Vajna 
Tested-by: Jenkins
(cherry picked from commit 6e3ad6ca0ae6cf62056610ddae9097973a887d99)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162464
Reviewed-by: Xisco Fauli 

diff --git a/sw/qa/core/layout/data/floattable-not-wrapped-by-table.docx 
b/sw/qa/core/layout/data/floattable-not-wrapped-by-table.docx
new file mode 100644
index ..2c255148d351
Binary files /dev/null and 
b/sw/qa/core/layout/data/floattable-not-wrapped-by-table.docx differ
diff --git a/sw/qa/core/layout/tabfrm.cxx b/sw/qa/core/layout/tabfrm.cxx
index 9357fc2df133..61b1a25109f5 100644
--- a/sw/qa/core/layout/tabfrm.cxx
+++ b/sw/qa/core/layout/tabfrm.cxx
@@ -199,6 +199,28 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFlyWrappedByTable)
 // i.e. the inline table was under the floating one, not on the right of 
it.
 CPPUNIT_ASSERT_LESS(nFloatingBottom, nInlineTop);
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testInlineTableThenSplitFly)
+{
+// Given a document with a floating table ("right") and an inline table 
("left"):
+// When laying out the document:
+createSwDoc("floattable-not-wrapped-by-table.docx");
+
+// Then make sure the inline table is on the left (small negative offset):
+SwDoc* pDoc = getSwDoc();
+SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+auto pPage = pLayout->Lower()->DynCastPageFrame();
+CPPUNIT_ASSERT(pPage);
+SwFrame* pBody = pPage->FindBodyCont();
+auto pTab = pBody->GetLower()->GetNext()->DynCastTabFrame();
+SwTwips nInlineLeft = pTab->getFramePrintArea().Left();
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected less than: 0
+// - Actual  : 6958
+// i.e. "left" was on the right, its horizontal margin was not a small 
negative value but a
+// large positive one.
+CPPUNIT_ASSERT_LESS(static_cast(0), nInlineLeft);
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index 033f692f47cc..f75782456181 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -3296,6 +3296,7 @@ bool SwTabFrame::CalcFlyOffsets( SwTwips& rUpper,
 
 bool bShiftDown = css::text::WrapTextMode_NONE == nSurround;
 bool bSplitFly = pFly->IsFlySplitAllowed();
+const SwRect aFlyRectWithoutSpaces = pFly->GetObjRect();
 if (!bShiftDown && bAddVerticalFlyOffsets)
 {
 if (nSurround == text::WrapTextMode_PARALLEL && 
isHoriOrientShiftDown)
@@ -3310,7 +3311,6 @@ bool SwTabFrame::CalcFlyOffsets( SwTwips& rUpper,
 
 // Ignore spacing when determining the left/right edge of the 
fly, like
 // Word does.
-const SwRect aFlyRectWithoutSpaces = pFly->GetObjRect();
 basegfx::B1DRange 
aFlyRange(aRectFnSet.GetLeft(aFlyRectWithoutSpaces),
 
aRectFnSet.GetRight(aFlyRectWithoutSpaces));
 
@@ -3373,9 +3373,16 @@ bool SwTabFrame::CalcFlyOffsets( SwTwips& rUpper,
 bool bFlyHoriOrientLeft = text::HoriOrientation::LEFT == 
rHori.GetHoriOrient();
 if (bSplitFly && 

core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-01-22 Thread László Németh (via logerrit)
 sw/qa/uitest/data/tdf159102.fodt|   61 
 sw/qa/uitest/writer_tests8/tdf159102.py |   81 
 sw/source/core/text/portxt.cxx  |   12 +++-
 3 files changed, 151 insertions(+), 3 deletions(-)

New commits:
commit d8116658ecf66d915ae8cf6510a76ee628c45431
Author: László Németh 
AuthorDate: Wed Jan 10 20:41:04 2024 +0100
Commit: Xisco Fauli 
CommitDate: Tue Jan 23 00:31:18 2024 +0100

tdf#159102 sw smart justify: fix automatic hyphenation

As before with soft hyphens, automatic hyphenation
could result too much shrinking, because of calculating
with an extra non-existing space in the line.

Also try to shrink the line only if a space likely
will be available in it.

During testing, extend user dictionary temporarily
with custom automatic hyphenation to avoid of false tests
because of non-available hyphenation patterns. (Note: maybe
the other tests with non-user dictionary based automatic
hyphenations are not correct.)

Follow-up to commit d511367c102ef2ada0f73dbe81744d39865d58ba
"tdf#195085 sw smart justify: fix bad shrinking at soft hyphen".

Change-Id: I58ecb8f1ea9f55ef2457d7ff4aca6aefa59a6dd1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162199
Tested-by: Jenkins
Reviewed-by: László Németh 
(cherry picked from commit 7c1f4dd740c32050480f3ab678805ad3c4c748bb)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162219
Reviewed-by: Xisco Fauli 

diff --git a/sw/qa/uitest/data/tdf159102.fodt b/sw/qa/uitest/data/tdf159102.fodt
new file mode 100644
index ..dfe9fc18872b
--- /dev/null
+++ b/sw/qa/uitest/data/tdf159102.fodt
@@ -0,0 +1,61 @@
+
+
+http://www.w3.org/TR/css3-text/; 
xmlns:grddl="http://www.w3.org/2003/g/data-view#; 
xmlns:xhtml="http://www.w3.org/1999/xhtml; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance; 
xmlns:xsd="http://www.w3.org/2001/XMLSchema; 
xmlns:xforms="http://www.w3.org/2002/xforms; 
xmlns:dom="http://www.w3.org/2001/xml-events; 
xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" 
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" 
xmlns:math="http://www.w3.org/1998/Math/MathML; 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:ooo="http://openoffice.org/2004/office; 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" 
xmlns:ooow="http://openoffice.org/2004/writer; 
xmlns:xlink="http://www.w3.org/1999/xlink; 
xmlns:drawooo="http://openoffice.org/2010/draw; 
xmlns:oooc="http://openoffice.org/2004/calc; 
xmlns:dc="http://purl.org/dc/elements/1.1/; xmlns:c
 alcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" 
xmlns:tableooo="http://openoffice.org/2009/table; 
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" 
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" 
xmlns:rpt="http://openoffice.org/2005/report; 
xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0"
 xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" 
xmlns:officeooo="http://openoffice.org/2009/office; 
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" 
xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" 
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" 
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:
 meta:1.0" 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"
 office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ 
+  
+   true
+   high-resolution
+  
+ 
+ 
+  
+  
+ 
+ 
+  
+   
+   
+  
+  
+   
+  
+  
+   
+  
+  
+   
+   
+  
+ 
+ 
+  
+   
+   
+  
+  
+   
+  
+  
+   
+  
+  
+   
+  
+  
+   
+
+   
+   
+   
+  
+ 
+ 
+  
+ 
+ 
+  
+   venenatis, quis commodo dolor posuere. Curabitur dignissim 
sapien quis cursus egestas.
+   venenatis, quis commodo dolor posuere. Curabitur dignissim 
sapien quis cursus 
egestas.
+  
+ 
+
diff --git a/sw/qa/uitest/writer_tests8/tdf159102.py 
b/sw/qa/uitest/writer_tests8/tdf159102.py
new file mode 100644
index ..07152ada3999
--- /dev/null
+++ b/sw/qa/uitest/writer_tests8/tdf159102.py
@@ -0,0 +1,81 @@
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+from uitest.framework import UITestCase
+from uitest.uihelper.common import 

core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-01-20 Thread Michael Stahl (via logerrit)
 sw/qa/extras/layout/data/table-0-height-rows.fodt |  630 ++
 sw/qa/extras/layout/layout3.cxx   |   14 
 sw/source/core/layout/tabfrm.cxx  |  118 
 3 files changed, 761 insertions(+), 1 deletion(-)

New commits:
commit f472defff73d495f564a0d8a84f24bc3739c9603
Author: Michael Stahl 
AuthorDate: Wed Jan 17 16:56:38 2024 +0100
Commit: Caolán McNamara 
CommitDate: Sat Jan 20 17:41:06 2024 +0100

sw: layout: prevent bad page break in table with 0-height rows

The bugdoc contains a table with most rows having a hidden-paragraph
field in every paragraph, and no cell border or padding.

The SwTabFrame is initially split across 6 pages, which should all be
joined, as there are only 3 visible rows, but the last follow is never
joined.

This is because SwTabFrame::Join() of the next-to-last follow doesn't
invalidate the SwTabFrame, because Grow(0) doesn't invalidate, and
later formatting anything in the moved SwRowFrame doesn't invalidate
either as it is all height 0.

Try to fix this by guessing that the row will have height 0 (even if
it's not formatted yet).

Change-Id: Ic8246ac91c741f5a215f89dc159c44d7c7cf2ce1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162203
Tested-by: Jenkins
Reviewed-by: Michael Stahl 
(cherry picked from commit ab7893544dc6be6dc192dffefd57cd5ddd421c35)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162223
Reviewed-by: Caolán McNamara 

diff --git a/sw/qa/extras/layout/data/table-0-height-rows.fodt 
b/sw/qa/extras/layout/data/table-0-height-rows.fodt
new file mode 100644
index ..f32e2fbe996e
--- /dev/null
+++ b/sw/qa/extras/layout/data/table-0-height-rows.fodt
@@ -0,0 +1,630 @@
+
+http://openoffice.org/2009/office; 
xmlns:css3t="http://www.w3.org/TR/css3-text/; 
xmlns:grddl="http://www.w3.org/2003/g/data-view#; 
xmlns:xhtml="http://www.w3.org/1999/xhtml; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance; 
xmlns:xsd="http://www.w3.org/2001/XMLSchema; 
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" 
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" 
xmlns:rpt="http://openoffice.org/2005/report; 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" 
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" 
xmlns:xlink="http://www.w3.org/1999/xlink; 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" 
xmlns:dc="http://purl.org/dc/eleme
 nts/1.1/" xmlns:ooo="http://openoffice.org/2004/office; 
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" 
xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0"
 
xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0"
 xmlns:drawooo="http://openoffice.org/2010/draw; 
xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" 
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" 
xmlns:ooow="http://openoffice.org/2004/writer; 
xmlns:oooc="http://openoffice.org/2004/calc; 
xmlns:tableooo="http://openoffice.org/2009/table; 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"
 xmlns:math="http://www.w3.org/1998/Math/MathML; 
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" 
xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0
 " xmlns:dom="http://www.w3.org/2001/xml-events; 
xmlns:xforms="http://www.w3.org/2002/xforms; office:version="1.2" 
office:mimetype="application/vnd.oasis.opendocument.text">
+ 
+  
+  
+  
+  
+  
+ 
+ 
+  
+   
+   
+
+   
+   
+  
+  
+   
+   
+  
+  
+   
+  
+  
+   
+  
+  
+  
+   
+
+   
+   
+  
+  
+   
+   
+  
+  
+   
+   
+  
+  
+   
+  
+  
+   
+
+ 
+ 
+
+   
+  
+  
+   
+
+ 
+ 
+
+   
+  
+  
+  
+  
+  
+   
+  
+  
+   
+  
+  
+   
+
+   
+   
+
+   
+   
+
+   
+   
+
+   
+   
+
+   
+   
+
+   
+   
+
+   
+   
+
+   
+   
+
+   
+   
+
+   
+  
+  
+   
+
+   
+   
+
+   
+   
+
+   
+   
+
+   
+   
+
+   
+   
+
+   
+   
+
+   
+   
+
+   
+   
+
+   
+   
+
+   
+  
+  
+  
+  
+ 
+ 
+  
+   
+  
+  
+   
+  
+  
+   
+  
+  
+   
+  
+  
+   
+  
+  
+   
+  
+  
+   
+  
+  
+   
+
+ 
+
+   
+  
+  
+   
+
+   
+   
+  
+  
+   
+   
+  
+  
+   
+  
+  
+   
+   
+  
+  
+   
+   
+  
+  
+   
+   
+  
+  
+   
+   
+  
+  
+   
+   
+  
+  
+   
+   
+  
+  
+   
+   
+  
+  
+   
+   
+  
+  
+   
+   
+  

core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-01-19 Thread Mike Kaganski (via logerrit)
 sw/qa/extras/layout/data/fld-in-tbl.docx |binary
 sw/qa/extras/layout/layout3.cxx  |   21 +
 sw/source/core/text/guess.cxx|   14 --
 3 files changed, 29 insertions(+), 6 deletions(-)

New commits:
commit 0f436a2fe6dfe8b2a7b159a94ed7a8706a1b4482
Author: Mike Kaganski 
AuthorDate: Fri Jan 19 11:07:58 2024 +0600
Commit: Xisco Fauli 
CommitDate: Fri Jan 19 17:05:40 2024 +0100

tdf#159271: do not try to put fields' spaces to hole portions

Change-Id: Ic1b3f9602089cc773f9c3adc0be09a3be08d690f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162269
Tested-by: Jenkins
Reviewed-by: Mike Kaganski 
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162293
Reviewed-by: Xisco Fauli 

diff --git a/sw/qa/extras/layout/data/fld-in-tbl.docx 
b/sw/qa/extras/layout/data/fld-in-tbl.docx
new file mode 100644
index ..95d1b8adae38
Binary files /dev/null and b/sw/qa/extras/layout/data/fld-in-tbl.docx differ
diff --git a/sw/qa/extras/layout/layout3.cxx b/sw/qa/extras/layout/layout3.cxx
index e0b29b43fc54..7112f8daae1a 100644
--- a/sw/qa/extras/layout/layout3.cxx
+++ b/sw/qa/extras/layout/layout3.cxx
@@ -2232,6 +2232,27 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf159050)
 u"PortionType::Margin"_ustr);
 }
 
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf159271)
+{
+// Given a document with a field with several spaces in a field content
+createSwDoc("fld-in-tbl.docx");
+xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+// Make sure there is only one page, one table with one row and two cells, 
and one paragraph
+assertXPath(pXmlDoc, "/root/page"_ostr, 1);
+assertXPath(pXmlDoc, "/root/page/body/tab"_ostr, 1);
+assertXPath(pXmlDoc, "/root/page/body/tab/row"_ostr, 1);
+assertXPath(pXmlDoc, "/root/page/body/tab/row/cell"_ostr, 2);
+assertXPath(pXmlDoc, "/root/page/body/txt"_ostr, 1);
+assertXPath(pXmlDoc, 
"/root/page/body/tab/row/cell[2]/txt/SwParaPortion"_ostr, 1);
+
+// Without the fix, this would fail:
+// - Expected: 1
+// - Actual  : 16
+// - In <>, XPath '/root/page/body/tab/row/cell[2]/txt//SwLineLayout' 
number of nodes is incorrect
+assertXPath(pXmlDoc, 
"/root/page/body/tab/row/cell[2]/txt//SwLineLayout"_ostr, 1);
+assertXPath(pXmlDoc, 
"/root/page/body/tab/row/cell[2]/txt//SwFieldPortion"_ostr, 1);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/guess.cxx b/sw/source/core/text/guess.cxx
index 3c85a42f4f15..3346fe345acc 100644
--- a/sw/source/core/text/guess.cxx
+++ b/sw/source/core/text/guess.cxx
@@ -253,9 +253,10 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, 
SwTextFormatInfo ,
 {
 // portion fits to line
 m_nCutPos = rInf.GetIdx() + nMaxLen;
-bool bRet = maybeAdjustPositionsForBlockAdjust(m_nCutPos, 
m_nBreakPos, m_nBreakStart,
-   m_nBreakWidth, 
m_nExtraBlankWidth,
-   nMaxSizeDiff, rInf, 
rSI, nMaxComp);
+bool bRet = rPor.InFieldGrp()
+|| maybeAdjustPositionsForBlockAdjust(m_nCutPos, 
m_nBreakPos, m_nBreakStart,
+  m_nBreakWidth, 
m_nExtraBlankWidth,
+  nMaxSizeDiff, 
rInf, rSI, nMaxComp);
 if( nItalic &&
 (m_nCutPos >= TextFrameIndex(rInf.GetText().getLength()) ||
   // #i48035# Needed for CalcFitToContent
@@ -408,9 +409,10 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, 
SwTextFormatInfo ,
 // there likely has been a pixel rounding error in GetTextBreak
 if ( m_nBreakWidth <= nLineWidth )
 {
-bool bRet = maybeAdjustPositionsForBlockAdjust(m_nCutPos, 
m_nBreakPos, m_nBreakStart,
-   m_nBreakWidth, 
m_nExtraBlankWidth,
-   nMaxSizeDiff, rInf, 
rSI, nMaxComp);
+bool bRet = rPor.InFieldGrp()
+|| maybeAdjustPositionsForBlockAdjust(m_nCutPos, 
m_nBreakPos, m_nBreakStart,
+  m_nBreakWidth, 
m_nExtraBlankWidth,
+  nMaxSizeDiff, 
rInf, rSI, nMaxComp);
 
 if (nItalic && (m_nBreakPos + TextFrameIndex(1)) >= 
TextFrameIndex(rInf.GetText().getLength()))
 m_nBreakWidth += nItalic;


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-01-14 Thread Justin Luth (via logerrit)
 sw/qa/extras/ooxmlexport/ooxmlexport19.cxx |1 +
 sw/qa/extras/ooxmlexport/ooxmlexport8.cxx  |8 
 sw/source/filter/ww8/docxsdrexport.cxx |5 +
 3 files changed, 14 insertions(+)

New commits:
commit 54ad2fd256224804181050f60c0668aa24cc82f7
Author: Justin Luth 
AuthorDate: Fri Jan 12 09:34:51 2024 -0500
Commit: Miklos Vajna 
CommitDate: Mon Jan 15 08:51:12 2024 +0100

tdf#139915 DOCX export: fix anchored obj position with TEXT_LINE

The position of objects was waffling back and forth
between "above" or "below" every round-trip.
For example, the unit test was alternating between 410 and 3951.

make CppunitTest_sw_ooxmlexport19 CPPUNIT_TEST_NAME=testTdf97371

This is an export followup to vmiklos' import fix in
LO 7.2 commit 2f21e4f357ec60450df84ddd858c3cf0a4711b02

I noticed that import still does not correctly position images:
make CppunitTest_sw_ooxmlexport8 CPPUNIT_TEST_NAME=testN747461
so I created tdf#159157 and tdf#159158 as follow-up bugs for that.

Change-Id: I29864d53f3b5e2fc9830793275f17a11eac0516f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161985
Tested-by: Jenkins
Reviewed-by: Justin Luth 
(cherry picked from commit c45bf5f4ae858d5d0532ee9b58fcbf23e94e2d75)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161996
Tested-by: Justin Luth 

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport19.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport19.cxx
index 0c1d1a25fb35..d6193305e96c 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport19.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport19.cxx
@@ -609,6 +609,7 @@ DECLARE_OOXMLEXPORT_TEST(testTdf97371, "tdf97371.docx")
 tools::Long nDiff = std::abs(pShape->GetSnapRect().Top() - 
pTextBox->GetSnapRect().Top());
 // The top of the two shapes were 410 and 3951, now it should be 3950 and 
3951.
 CPPUNIT_ASSERT(nDiff < 10);
+CPPUNIT_ASSERT_DOUBLES_EQUAL(tools::Long(3900), 
pShape->GetSnapRect().Top(), 100);
 }
 
 CPPUNIT_TEST_FIXTURE(Test, testTdf99140)
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx
index 10fd87ebec2c..2463534dd8ba 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx
@@ -173,6 +173,14 @@ after they are loaded.
 CPPUNIT_ASSERT_EQUAL( OUString( "Black" ), descr1 );
 CPPUNIT_ASSERT_EQUAL( OUString( "Red" ), descr2 );
 CPPUNIT_ASSERT_EQUAL( OUString( "Green" ), descr3 );
+
+//FIXME: MS Word shows the image below the line of text, not above it.
+// tdf#139915 This was 826, but it should be -826
+if (isExported())
+CPPUNIT_ASSERT_EQUAL(sal_Int32(-826), getProperty(image1, 
"VertOrientPosition"));
+sal_Int16 nExpected = text::RelOrientation::TEXT_LINE;
+CPPUNIT_ASSERT_EQUAL(nExpected, getProperty(image1, 
"VertOrientRelation"));
+
 }
 
 DECLARE_OOXMLEXPORT_TEST(testN750255, "n750255.docx")
diff --git a/sw/source/filter/ww8/docxsdrexport.cxx 
b/sw/source/filter/ww8/docxsdrexport.cxx
index 0c42d28fc6ad..5c746f6afe6e 100644
--- a/sw/source/filter/ww8/docxsdrexport.cxx
+++ b/sw/source/filter/ww8/docxsdrexport.cxx
@@ -939,6 +939,11 @@ void DocxSdrExport::startDMLAnchorInline(const 
SwFrameFormat* pFrameFormat, cons
 relativeFromV = "paragraph";
 break;
 case text::RelOrientation::TEXT_LINE:
+relativeFromV = "line";
+// Word's "line" is "below the bottom of the line", our 
TEXT_LINE is
+// "towards top, from the bottom of the line", so invert the 
vertical position.
+aPos.Y *= -1;
+break;
 default:
 relativeFromV = "line";
 break;


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-01-11 Thread Mike Kaganski (via logerrit)
 sw/qa/extras/layout/data/tdf159050-wrap-adjust.fodt |   25 ++
 sw/qa/extras/layout/layout3.cxx |   27 
 sw/source/core/text/porfly.cxx  |   12 
 3 files changed, 63 insertions(+), 1 deletion(-)

New commits:
commit 3ab08b58cbac8be8bbd5d5a409b54e488b0e2c73
Author: Mike Kaganski 
AuthorDate: Thu Jan 11 13:16:45 2024 +0600
Commit: Michael Stahl 
CommitDate: Thu Jan 11 13:15:31 2024 +0100

tdf#159050: let fly portion swallow hole portion width

Change-Id: I65492418ca5f5f5b04e5f9bab9ac3e6bf2108aff
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161910
Tested-by: Jenkins
Reviewed-by: Mike Kaganski 
Signed-off-by: Xisco Fauli 
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161919
Reviewed-by: Michael Stahl 

diff --git a/sw/qa/extras/layout/data/tdf159050-wrap-adjust.fodt 
b/sw/qa/extras/layout/data/tdf159050-wrap-adjust.fodt
new file mode 100644
index ..49d9e57071fb
--- /dev/null
+++ b/sw/qa/extras/layout/data/tdf159050-wrap-adjust.fodt
@@ -0,0 +1,25 @@
+
+
+
+ 
+  
+   
+  
+  
+   
+  
+  
+   
+  
+ 
+ 
+  
+ 
+ 
+  
+   
+ 
+Pretium semper. Proin luctus orci ac neque venenatis, 
quis commodo dolor posuere. Curabitur dignissim
+  
+ 
+
\ No newline at end of file
diff --git a/sw/qa/extras/layout/layout3.cxx b/sw/qa/extras/layout/layout3.cxx
index e17eaa108a30..9a1d9b2fb7c5 100644
--- a/sw/qa/extras/layout/layout3.cxx
+++ b/sw/qa/extras/layout/layout3.cxx
@@ -2205,6 +2205,33 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, 
testTdf57187_Tdf158900)
 u"PortionType::Break"_ustr);
 }
 
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf159050)
+{
+// Given a document with a justified paragraph and a box with optimal 
wrapping
+createSwDoc("tdf159050-wrap-adjust.fodt");
+xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+// Make sure there is only one page, one anchored object, one paragraph, 
and two lines
+assertXPath(pXmlDoc, "/root/page"_ostr, 1);
+assertXPath(pXmlDoc, 
"/root/page/body/txt/anchored/SwAnchoredDrawObject"_ostr, 1);
+assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion"_ostr, 1);
+assertXPath(pXmlDoc, 
"/root/page/body/txt/SwParaPortion/SwLineLayout"_ostr, 2);
+
+// Without the fix, this would fail: there was an unexpected second fly 
portion.
+assertXPath(pXmlDoc, 
"/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*"_ostr, 4);
+assertXPath(pXmlDoc, 
"/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*[1]"_ostr, "type"_ostr,
+u"PortionType::Text"_ustr);
+assertXPath(pXmlDoc, 
"/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*[1]"_ostr,
+"length"_ostr, u"91"_ustr);
+assertXPath(pXmlDoc, 
"/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*[2]"_ostr, "type"_ostr,
+u"PortionType::Hole"_ustr);
+assertXPath(pXmlDoc, 
"/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*[2]"_ostr,
+"length"_ostr, u"1"_ustr);
+assertXPath(pXmlDoc, 
"/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*[3]"_ostr, "type"_ostr,
+u"PortionType::Fly"_ustr);
+assertXPath(pXmlDoc, 
"/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*[4]"_ostr, "type"_ostr,
+u"PortionType::Margin"_ustr);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/porfly.cxx b/sw/source/core/text/porfly.cxx
index 7bee98d9821a..14d1bf6eaa8a 100644
--- a/sw/source/core/text/porfly.cxx
+++ b/sw/source/core/text/porfly.cxx
@@ -58,6 +58,16 @@ bool SwFlyPortion::Format( SwTextFormatInfo  )
 rInf.GetLastTab()->FormatEOL( rInf );
 
 rInf.GetLast()->FormatEOL( rInf );
+
+SetBlankWidth(0);
+if (auto blankWidth = rInf.GetLast()->ExtraBlankWidth())
+{
+// Swallow previous blank width
+SetBlankWidth(blankWidth);
+rInf.GetLast()->ExtraBlankWidth(0);
+rInf.X(rInf.X() - blankWidth); // Step back
+}
+
 PrtWidth( o3tl::narrowing(GetFix() - rInf.X() + PrtWidth()) );
 if( !Width() )
 {
@@ -78,7 +88,7 @@ bool SwFlyPortion::Format( SwTextFormatInfo  )
 && ' ' != rInf.GetChar(rInf.GetIdx() - TextFrameIndex(1))
 && ( !rInf.GetLast() || !rInf.GetLast()->IsBreakPortion() ) )
 {
-SetBlankWidth( rInf.GetTextSize(OUString(' ')).Width() );
+SetBlankWidth(GetBlankWidth() + rInf.GetTextSize(OUString(' 
')).Width());
 SetLen(TextFrameIndex(1));
 }
 


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-01-11 Thread Mike Kaganski (via logerrit)
 sw/qa/extras/ooxmlexport/data/multi_space_url.fodt |9 ++
 sw/qa/extras/ooxmlexport/ooxmlexport20.cxx |   29 +
 sw/source/filter/ww8/wrtw8nds.cxx  |4 +-
 3 files changed, 40 insertions(+), 2 deletions(-)

New commits:
commit ac09b8b599f92ffeec85fbba765d546fb4b091b1
Author: Mike Kaganski 
AuthorDate: Wed Jan 10 22:39:39 2024 +0600
Commit: Xisco Fauli 
CommitDate: Thu Jan 11 10:36:59 2024 +0100

tdf#159110: store URLs to DOCX correctly

It must not decode URLs, and must store it percent-encoded.

This was wrong since commit 7b0b5cdfeed656b279bc32cd929630d5fc25878b
(initial import, 2000-09-18).

Commit d68b1b6ae355c92e982ec845216ba459dbdd9e16 (use correct
INetURL-Decode enum, 2000-10-20) replaced incorrect "with charset"
decoding with another incorrect "unambiguous" decoding.

Change-Id: I915897dc2e3eb838fc02b4ac338b3d76fe0477fa
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161893
Tested-by: Jenkins
Reviewed-by: Mike Kaganski 
Signed-off-by: Xisco Fauli 
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161914

diff --git a/sw/qa/extras/ooxmlexport/data/multi_space_url.fodt 
b/sw/qa/extras/ooxmlexport/data/multi_space_url.fodt
new file mode 100644
index ..3a96582aa71f
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/multi_space_url.fodt
@@ -0,0 +1,9 @@
+
+
+http://www.w3.org/1999/xlink; 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ 
+  
+   http://www.example.org/path%20%20with%20%20spaces; 
text:style-name="Internet_20_link" 
text:visited-style-name="Visited_20_Internet_20_Link">A sample 
hyperlink
+  
+ 
+
\ No newline at end of file
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport20.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport20.cxx
index 2fdfcaf66bdc..8812cf729ee0 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport20.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport20.cxx
@@ -1091,6 +1091,35 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf158971)
 }
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testTdf159110)
+{
+// Given a text with an URL with multiple spaces
+loadAndReload("multi_space_url.fodt");
+
+constexpr OUString sExpectedURL = 
u"http://www.example.org/path%20%20with%20%20spaces"_ustr;
+
+// Without the fix, this would have failed with
+// - Expected: http://www.example.org/path%20%20with%20%20spaces
+// - Actual  : http://www.example.org/path with spaces
+CPPUNIT_ASSERT_EQUAL(sExpectedURL,
+ getProperty(getRun(getParagraph(1), 1), 
u"HyperLinkURL"_ustr));
+
+xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+OString sId
+= OUStringToOString(getXPath(pXmlDoc, 
"/w:document/w:body/w:p/w:hyperlink"_ostr, "id"_ostr),
+RTL_TEXTENCODING_UTF8);
+
+xmlDocUniquePtr pXmlRels = parseExport("word/_rels/document.xml.rels");
+
+// Without the fix, this would have failed with
+// - Expected: http://www.example.org/path%20%20with%20%20spaces
+// - Actual  : http://www.example.org/path  with  spaces
+// - In <>, attribute 'Target' of 
'/rels:Relationships/rels:Relationship[@Id='rId2']' incorrect value.
+// I.e., the spaces were stored without percent-encoding, and collapsed on 
import
+assertXPath(pXmlRels, "/rels:Relationships/rels:Relationship[@Id='"_ostr + 
sId + "']",
+"Target"_ostr, sExpectedURL);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx 
b/sw/source/filter/ww8/wrtw8nds.cxx
index c70c78121b8b..39e2f885230b 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -1092,8 +1092,8 @@ bool AttributeOutputBase::AnalyzeURL( const OUString& 
rUrl, const OUString& /*rT
 else
 {
 INetURLObject aURL( rUrl, INetProtocol::NotValid );
-sURL = aURL.GetURLNoMark( INetURLObject::DecodeMechanism::Unambiguous 
);
-sMark = aURL.GetMark( INetURLObject::DecodeMechanism::Unambiguous );
+sURL = aURL.GetURLNoMark( INetURLObject::DecodeMechanism::NONE );
+sMark = aURL.GetMark( INetURLObject::DecodeMechanism::NONE );
 INetProtocol aProtocol = aURL.GetProtocol();
 
 if ( aProtocol == INetProtocol::File || aProtocol == 
INetProtocol::NotValid )


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-01-10 Thread László Németh (via logerrit)
 sw/qa/extras/layout/data/tdf159085.fodt |   61 
 sw/qa/extras/layout/layout3.cxx |   24 
 sw/source/core/text/portxt.cxx  |9 
 3 files changed, 93 insertions(+), 1 deletion(-)

New commits:
commit 6bd230862605760bd4357e6e4bba2c91dcbe5438
Author: László Németh 
AuthorDate: Tue Jan 9 13:35:23 2024 +0100
Commit: László Németh 
CommitDate: Wed Jan 10 13:11:50 2024 +0100

tdf#159085 sw smart justify: fix bad shrinking at soft hyphen

Soft hyphen in the word could result too much shrinking,
calculating with an extra (non-existing) space.

Change-Id: If8b7af40ff50d12c0f2428a6f2475e261fbd0f42
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161827
Tested-by: Jenkins
Reviewed-by: László Németh 
(cherry picked from commit f35d7b0484205e6c8daef795f787e5d6cbc88fc8)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161769
Tested-by: László Németh 

diff --git a/sw/qa/extras/layout/data/tdf159085.fodt 
b/sw/qa/extras/layout/data/tdf159085.fodt
new file mode 100644
index ..efd0e98e9213
--- /dev/null
+++ b/sw/qa/extras/layout/data/tdf159085.fodt
@@ -0,0 +1,61 @@
+
+
+http://www.w3.org/TR/css3-text/; 
xmlns:grddl="http://www.w3.org/2003/g/data-view#; 
xmlns:xhtml="http://www.w3.org/1999/xhtml; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance; 
xmlns:xsd="http://www.w3.org/2001/XMLSchema; 
xmlns:xforms="http://www.w3.org/2002/xforms; 
xmlns:dom="http://www.w3.org/2001/xml-events; 
xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" 
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" 
xmlns:math="http://www.w3.org/1998/Math/MathML; 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:ooo="http://openoffice.org/2004/office; 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" 
xmlns:ooow="http://openoffice.org/2004/writer; 
xmlns:xlink="http://www.w3.org/1999/xlink; 
xmlns:drawooo="http://openoffice.org/2010/draw; 
xmlns:oooc="http://openoffice.org/2004/calc; 
xmlns:dc="http://purl.org/dc/elements/1.1/; xmlns:c
 alcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" 
xmlns:tableooo="http://openoffice.org/2009/table; 
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" 
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" 
xmlns:rpt="http://openoffice.org/2005/report; 
xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0"
 xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" 
xmlns:officeooo="http://openoffice.org/2009/office; 
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" 
xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" 
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" 
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:
 meta:1.0" 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"
 office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ 
+  
+   true
+   high-resolution
+  
+ 
+ 
+  
+  
+ 
+ 
+  
+   
+   
+  
+  
+   
+  
+  
+   
+  
+  
+   
+   
+  
+ 
+ 
+  
+   
+   
+  
+  
+   
+  
+  
+   
+  
+  
+   
+  
+  
+   
+
+   
+   
+   
+  
+ 
+ 
+  
+ 
+ 
+  
+   venenatis, quis commodo dolor posuere. Curabitur dignissim 
sapien quis cur­sus egestas.
+   venenatis, quis commodo dolor posuere. Curabitur dignissim 
sapien quis cur­sus 
egestas.
+  
+ 
+
diff --git a/sw/qa/extras/layout/layout3.cxx b/sw/qa/extras/layout/layout3.cxx
index f660334012d0..e17eaa108a30 100644
--- a/sw/qa/extras/layout/layout3.cxx
+++ b/sw/qa/extras/layout/layout3.cxx
@@ -244,6 +244,30 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf158333)
 "venenatis, quis commodo dolor posuere. Curabitur dignissim 
sapien quis ");
 }
 
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf159085)
+{
+createSwDoc("tdf159085.fodt");
+// Ensure that all text portions are calculated before testing.
+SwXTextDocument* pTextDoc = 
dynamic_cast(mxComponent.get());
+CPPUNIT_ASSERT(pTextDoc);
+SwViewShell* pViewShell
+= 
pTextDoc->GetDocShell()->GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell();
+CPPUNIT_ASSERT(pViewShell);
+pViewShell->Reformat();
+
+xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+// This was "... cursus" instead of breaking the word at soft hyphen
+assertXPath(
+pXmlDoc, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout[1]"_ostr, 
"portion"_ostr,
+u"venenatis, quis commodo dolor posuere. Curabitur dignissim sapien 
quis cur­"_ustr);
+
+// This was 

core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-01-09 Thread László Németh (via logerrit)
 sw/qa/extras/uiwriter/data/tdf159026.docx |binary
 sw/qa/extras/uiwriter/uiwriter8.cxx   |   58 ++
 sw/source/core/frmedt/tblsel.cxx  |4 +-
 3 files changed, 61 insertions(+), 1 deletion(-)

New commits:
commit de7e0bc32d3629063f13250ae3b7c9f934fba046
Author: László Németh 
AuthorDate: Mon Jan 8 01:28:36 2024 +0100
Commit: Xisco Fauli 
CommitDate: Tue Jan 9 09:37:13 2024 +0100

tdf#159026 sw: fix Undo crash with tracked floating table deletion

In Hide Changes mode, tracked deletion of a floating table,
and after that, its frame resulted a crash during Undos.

Regression from commit 0c6221e1545e7b96d9df23cdc24302c28ae935b8
"tdf#148227 sw: fix Undo of tracked row deletion in Hide Changes mode".

Change-Id: I3fd88a30df2739ce8a3cdc24da07684a3ac5a41b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161777
Tested-by: László Németh 
Reviewed-by: László Németh 
(cherry picked from commit f5a00d9ffb8325f4b9fed21b5c96ca005e11b1bb)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161758
Tested-by: Jenkins
Reviewed-by: Xisco Fauli 

diff --git a/sw/qa/extras/uiwriter/data/tdf159026.docx 
b/sw/qa/extras/uiwriter/data/tdf159026.docx
new file mode 100644
index ..65bfaae3e423
Binary files /dev/null and b/sw/qa/extras/uiwriter/data/tdf159026.docx differ
diff --git a/sw/qa/extras/uiwriter/uiwriter8.cxx 
b/sw/qa/extras/uiwriter/uiwriter8.cxx
index 9aaafa1e6967..4fa027b0515b 100644
--- a/sw/qa/extras/uiwriter/uiwriter8.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter8.cxx
@@ -15,9 +15,11 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -239,6 +241,62 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf146962)
 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row"_ostr, 2);
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf159026)
+{
+// load a floating table (tables in DOCX footnotes
+// imported as floating tables in Writer)
+createSwDoc("tdf159026.docx");
+SwDoc* pDoc = getSwDoc();
+CPPUNIT_ASSERT(pDoc);
+SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+CPPUNIT_ASSERT(pWrtShell);
+
+// enable redlining
+dispatchCommand(mxComponent, ".uno:TrackChanges", {});
+CPPUNIT_ASSERT_MESSAGE("redlining should be on",
+   pDoc->getIDocumentRedlineAccess().IsRedlineOn());
+// hide changes
+dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
+
+// select table with SelectionSupplier
+uno::Reference xTextTablesSupplier(mxComponent, 
uno::UNO_QUERY);
+uno::Reference 
xIndexAccess(xTextTablesSupplier->getTextTables(),
+ uno::UNO_QUERY);
+CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
+
+uno::Reference xModel(mxComponent, uno::UNO_QUERY);
+uno::Reference 
xSelSupplier(xModel->getCurrentController(),
+  
uno::UNO_QUERY_THROW);
+// select floating table (table in a frame)
+xSelSupplier->select(xIndexAccess->getByIndex(0));
+
+// delete table with track changes
+dispatchCommand(mxComponent, ".uno:DeleteTable", {});
+
+// tracked table deletion
+CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
+
+// hidden table
+xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+assertXPath(pXmlDoc, "//tab"_ostr, 0);
+
+// delete frame
+uno::Reference xTextFramesSupplier(mxComponent, 
uno::UNO_QUERY);
+uno::Reference 
xIndexAccess2(xTextFramesSupplier->getTextFrames(),
+  uno::UNO_QUERY);
+xSelSupplier->select(xIndexAccess2->getByIndex(0));
+dispatchCommand(mxComponent, ".uno:Delete", {});
+
+// undo frame deletion
+dispatchCommand(mxComponent, ".uno:Undo", {});
+
+// undo tracked table deletion
+
+// This resulted crashing
+dispatchCommand(mxComponent, ".uno:Undo", {});
+}
+
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf147347)
 {
 // load a 2-row table, set Hide Changes mode and delete the table with 
change tracking
diff --git a/sw/source/core/frmedt/tblsel.cxx b/sw/source/core/frmedt/tblsel.cxx
index 48a92366509c..ec56a5285675 100644
--- a/sw/source/core/frmedt/tblsel.cxx
+++ b/sw/source/core/frmedt/tblsel.cxx
@@ -2383,7 +2383,9 @@ void FndBox_::MakeFrames( SwTable  )
 for ( sal_uInt16 j = nStPos; j <= nEndPos; ++j )
 {
 SwTableLine * pLine = rTable.GetTabLines()[j];
-if ( !bHideChanges || !pLine->IsDeleted(nRedlinePos) )
+if ( ( !bHideChanges || !pLine->IsDeleted(nRedlinePos) ) &&
+// tdf#159026 fix Undo crash with floating tables
+pUpperFrame->GetUpper() )
 

core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-01-05 Thread László Németh (via logerrit)
 sw/qa/extras/ooxmlexport/data/tdf124795-5.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlexport14.cxx |6 ++
 sw/source/core/text/portxt.cxx |1 +
 3 files changed, 7 insertions(+)

New commits:
commit 9e201cbdc31caca694e067ee0f66cce2b07c9778
Author: László Németh 
AuthorDate: Fri Jan 5 01:11:34 2024 +0100
Commit: Caolán McNamara 
CommitDate: Fri Jan 5 15:49:09 2024 +0100

tdf#159032 sw smart justify: fix crash with complex tables

Regression from commit 36bfc86e27fa03ee16f87819549ab126c5a68cac
"tdf#119908 tdf#158776 sw smart justify: shrink only spaces"

Change-Id: Ia3f39ad6549ea909bfe327ff8c8cbde821b90f46
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161652
Tested-by: Jenkins
Reviewed-by: László Németh 
(cherry picked from commit 99f022bdeb2817cceffc90ff3b3439cdc4550424)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161638
Reviewed-by: Caolán McNamara 

diff --git a/sw/qa/extras/ooxmlexport/data/tdf124795-5.docx 
b/sw/qa/extras/ooxmlexport/data/tdf124795-5.docx
new file mode 100644
index ..19fd5f49c89c
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf124795-5.docx 
differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
index 0656bb868795..4b0fbdd13716 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
@@ -1414,6 +1414,12 @@ DECLARE_OOXMLEXPORT_TEST(testTdf158436, "tdf158436.docx")
 CPPUNIT_ASSERT_EQUAL(1, getPages());
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf159032, "tdf124795-5.docx")
+{
+// This resulted crashing
+CPPUNIT_ASSERT_EQUAL(57, getPages());
+}
+
 CPPUNIT_TEST_FIXTURE(Test, testHyphenationAuto)
 {
 loadAndReload("hyphenation.odt");
diff --git a/sw/source/core/text/portxt.cxx b/sw/source/core/text/portxt.cxx
index bcc547d1796b..3dcdf37ecc90 100644
--- a/sw/source/core/text/portxt.cxx
+++ b/sw/source/core/text/portxt.cxx
@@ -308,6 +308,7 @@ bool SwTextPortion::Format_( SwTextFormatInfo  )
 // adjusted line by shrinking spaces using the know space count from the 
first Guess() call
 const SvxAdjust& rAdjust = 
rInf.GetTextFrame()->GetTextNodeForParaProps()->GetSwAttrSet().GetAdjust().GetAdjust();
 if ( bFull && rAdjust == SvxAdjust::Block &&
+ aGuess.BreakPos() != TextFrameIndex(COMPLETE_STRING) &&
  rInf.GetTextFrame()->GetDoc().getIDocumentSettingAccess().get(
 DocumentSettingId::JUSTIFY_LINES_WITH_SHRINKING) &&
  // tdf#158436 avoid shrinking at underflow, e.g. no-break space after 
a


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2024-01-02 Thread Mike Kaganski (via logerrit)
 sw/qa/extras/layout/data/space+break.fodt |   50 ++
 sw/qa/extras/layout/layout3.cxx   |   22 +
 sw/source/core/text/portxt.cxx|7 +++-
 3 files changed, 78 insertions(+), 1 deletion(-)

New commits:
commit 89113b1aa39ea064c27b5a67513bade1620ba0d9
Author: Mike Kaganski 
AuthorDate: Thu Dec 28 15:06:56 2023 +0600
Commit: Xisco Fauli 
CommitDate: Tue Jan 2 12:12:56 2024 +0100

tdf#158900: make sure to not break after spaces before 


Change-Id: I9af98e270090530fc9bd621fbbcdf0ba35d0107c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161378
Tested-by: Jenkins
Reviewed-by: Mike Kaganski 
Signed-off-by: Xisco Fauli 
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161379

diff --git a/sw/qa/extras/layout/data/space+break.fodt 
b/sw/qa/extras/layout/data/space+break.fodt
new file mode 100644
index ..fbd81f37f501
--- /dev/null
+++ b/sw/qa/extras/layout/data/space+break.fodt
@@ -0,0 +1,50 @@
+
+
+http://openoffice.org/2004/office; 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ 
+  
+   false
+   false
+   false
+   0
+   false
+   high-resolution
+   false
+   false
+   true
+   true
+   false
+   false
+   false
+   false
+   false
+   false
+  
+ 
+ 
+  
+ 
+ 
+  
+   
+   
+  
+  
+ 
+ 
+  
+   
+  
+  
+   
+  
+ 
+ 
+  
+ 
+ 
+  
+   Lorem ipsum Lorem ipsum Lorem ipsum Lorem 
ipsum
+  
+ 
+
\ No newline at end of file
diff --git a/sw/qa/extras/layout/layout3.cxx b/sw/qa/extras/layout/layout3.cxx
index ec7d740cf74f..ebac0b257e53 100644
--- a/sw/qa/extras/layout/layout3.cxx
+++ b/sw/qa/extras/layout/layout3.cxx
@@ -2123,6 +2123,28 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf152307)
 CPPUNIT_ASSERT_MESSAGE(aMsg.getStr(), nTabBottom < nFooterTop);
 }
 
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf158900)
+{
+// Given a document with a single paragraph, having some long space runs 
and line breaks
+createSwDoc("space+break.fodt");
+xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+// Make sure there is only one page, one paragraph, and four lines
+assertXPath(pXmlDoc, "/root/page"_ostr, 1);
+assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion"_ostr, 1);
+// Without the fix in place, this would fail: there used to be 5 lines
+assertXPath(pXmlDoc, 
"/root/page/body/txt/SwParaPortion/SwLineLayout"_ostr, 4);
+// Check that the second line has correct portions
+// Without the fix in place, this would fail: the line had only 2 portions 
(text + hole),
+// and the break was on a separate third line
+assertXPath(pXmlDoc, 
"/root/page/body/txt/SwParaPortion/SwLineLayout[2]/*"_ostr, 3);
+assertXPath(pXmlDoc, 
"/root/page/body/txt/SwParaPortion/SwLineLayout[2]/*[1]"_ostr, "type"_ostr,
+u"PortionType::Text"_ustr);
+assertXPath(pXmlDoc, 
"/root/page/body/txt/SwParaPortion/SwLineLayout[2]/*[2]"_ostr, "type"_ostr,
+u"PortionType::Hole"_ustr);
+assertXPath(pXmlDoc, 
"/root/page/body/txt/SwParaPortion/SwLineLayout[2]/*[3]"_ostr, "type"_ostr,
+u"PortionType::Break"_ustr);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/portxt.cxx b/sw/source/core/text/portxt.cxx
index 0d3960c1bcbc..bcc547d1796b 100644
--- a/sw/source/core/text/portxt.cxx
+++ b/sw/source/core/text/portxt.cxx
@@ -360,7 +360,7 @@ bool SwTextPortion::Format_( SwTextFormatInfo  )
 new SwKernPortion( *this, nKern );
 }
 // special case: hanging portion
-else if( bFull && aGuess.GetHangingPortion() )
+else if( aGuess.GetHangingPortion() )
 {
 Width( aGuess.BreakWidth() );
 SetLen( aGuess.BreakPos() - rInf.GetIdx() );
@@ -431,6 +431,11 @@ bool SwTextPortion::Format_( SwTextFormatInfo  )
 pNew->Width(0);
 pNew->ExtraBlankWidth( aGuess.ExtraBlankWidth() );
 Insert( pNew );
+
+// UAX #14 Unicode Line Breaking Algorithm Non-tailorable Line 
breaking rule LB6:
+// https://www.unicode.org/reports/tr14/#LB6 Do not break 
before hard line breaks
+if (rInf.GetChar(aGuess.BreakStart()) == CH_BREAK)
+bFull = false; // Keep following SwBreakPortion in the 
same line
 }
 }
 else// case C2, last exit


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2023-12-28 Thread László Németh (via logerrit)
 sw/qa/extras/layout/layout3.cxx |6 ++
 sw/source/core/text/guess.cxx   |   15 ++-
 sw/source/core/text/guess.hxx   |2 +-
 sw/source/core/text/portxt.cxx  |   25 -
 4 files changed, 37 insertions(+), 11 deletions(-)

New commits:
commit 8d247e3ad47e0b828437abb019e1573dbb1c05b1
Author: László Németh 
AuthorDate: Tue Dec 19 11:58:40 2023 +0100
Commit: Xisco Fauli 
CommitDate: Thu Dec 28 13:49:48 2023 +0100

tdf#119908 tdf#158776 sw smart justify: shrink only spaces

For interoperability, only shrink spaces up to 20%,
not the lines up to 2%.

Follow-up to commit 20cbe88ce5610fd8ee302e5780a4c0821ddb3db4
"tdf#119908 tdf#158419 sw smart justify: fix cursor position"
and commit 7d08767b890e723cd502b1c61d250924f695eb98
"tdf#130088 tdf#119908 smart justify: fix DOCX line count + compat opt."

Change-Id: Idb43161cb5a57c3412abd3f0eb266c6afbe5363c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160988
Tested-by: Jenkins
Reviewed-by: László Németh 
(cherry picked from commit 36bfc86e27fa03ee16f87819549ab126c5a68cac)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161325
Reviewed-by: Xisco Fauli 

diff --git a/sw/qa/extras/layout/layout3.cxx b/sw/qa/extras/layout/layout3.cxx
index ea2c3a52d24e..ec7d740cf74f 100644
--- a/sw/qa/extras/layout/layout3.cxx
+++ b/sw/qa/extras/layout/layout3.cxx
@@ -236,6 +236,12 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf158333)
 "portion"_ostr,
 // This was "...et ", not "...et magnis "
 "consequat arcu ut diam tempor luctus. Cum sociis natoque 
penatibus et magnis ");
+
+// tdf#158776 don't shrink line 11 of paragraph 4
+assertXPath(pXmlDoc, 
"/root/page/body/txt[4]/SwParaPortion/SwLineLayout[11]"_ostr,
+"portion"_ostr,
+// This was "...quis curcus ", not "...quis "
+"venenatis, quis commodo dolor posuere. Curabitur dignissim 
sapien quis ");
 }
 
 CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf158419)
diff --git a/sw/source/core/text/guess.cxx b/sw/source/core/text/guess.cxx
index 37a2147d0987..6123ad1b6767 100644
--- a/sw/source/core/text/guess.cxx
+++ b/sw/source/core/text/guess.cxx
@@ -50,7 +50,7 @@ bool IsBlank(sal_Unicode ch) { return ch == CH_BLANK || ch == 
CH_FULL_BLANK || c
 // returns true if no line break has to be performed
 // otherwise possible break or hyphenation position is determined
 bool SwTextGuess::Guess( const SwTextPortion& rPor, SwTextFormatInfo ,
-const sal_uInt16 nPorHeight )
+const sal_uInt16 nPorHeight, sal_Int32 
nSpacesInLine )
 {
 m_nCutPos = rInf.GetIdx();
 
@@ -80,15 +80,12 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, 
SwTextFormatInfo ,
 
 const SvxAdjust& rAdjust = 
rInf.GetTextFrame()->GetTextNodeForParaProps()->GetSwAttrSet().GetAdjust().GetAdjust();
 
-// allow shrinking, i.e. more text in justified lines, depending on the 
justification algorithm
-if ( rAdjust == SvxAdjust::Block && 
rInf.GetTextFrame()->GetDoc().getIDocumentSettingAccess().get(
-DocumentSettingId::JUSTIFY_LINES_WITH_SHRINKING) &&
- // tdf#158436 avoid shrinking at underflow, e.g. no-break space
- // after a very short word resulted endless loop
- !rInf.IsUnderflow() )
+// allow up to 20% shrinking of the spaces
+if ( nSpacesInLine )
 {
-// allow up to 2% shrinking of the line
-nLineWidth = nLineWidth / 0.98 + rInf.X() / 0.98 - rInf.X();
+static constexpr OUStringLiteral STR_BLANK = u" ";
+sal_Int16 nSpaceWidth = rInf.GetTextSize(STR_BLANK).Width();
+nLineWidth += nSpacesInLine * (nSpaceWidth/0.8 - nSpaceWidth);
 }
 
 // tdf#104668 space chars at the end should be cut if the compatibility 
option is enabled
diff --git a/sw/source/core/text/guess.hxx b/sw/source/core/text/guess.hxx
index f83c7e280ae4..5a7a9ac1cfa2 100644
--- a/sw/source/core/text/guess.hxx
+++ b/sw/source/core/text/guess.hxx
@@ -46,7 +46,7 @@ public:
 
 // true, if current portion still fits to current line
 bool Guess( const SwTextPortion& rPor, SwTextFormatInfo ,
-const sal_uInt16 nHeight );
+const sal_uInt16 nHeight, sal_Int32 nSpacesInLine = 0 );
 bool AlternativeSpelling( const SwTextFormatInfo , const 
TextFrameIndex nPos );
 
 SwHangingPortion* GetHangingPortion() const { return m_pHanging.get(); }
diff --git a/sw/source/core/text/portxt.cxx b/sw/source/core/text/portxt.cxx
index 9631fc232dc3..0d3960c1bcbc 100644
--- a/sw/source/core/text/portxt.cxx
+++ b/sw/source/core/text/portxt.cxx
@@ -302,7 +302,30 @@ bool SwTextPortion::Format_( SwTextFormatInfo  )
 }
 
 SwTextGuess aGuess;
-const bool bFull = !aGuess.Guess( *this, rInf, Height() );
+bool bFull = !aGuess.Guess( *this, rInf, Height() );
+
+// tdf#158776 for the 

core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2023-12-19 Thread Noel Grandin (via logerrit)
 sw/qa/uitest/writer_tests7/tdf144439.py |   22 
 sw/source/core/doc/number.cxx   |   35 +---
 2 files changed, 37 insertions(+), 20 deletions(-)

New commits:
commit d595b4436320fcd3ce0a84968d16d51f512a1e87
Author: Noel Grandin 
AuthorDate: Tue Dec 19 11:40:24 2023 +0200
Commit: Noel Grandin 
CommitDate: Wed Dec 20 07:19:10 2023 +0100

tdf#154864 Changing starting number of numbered list does nothing

regression from
commit cd3c16fbcb4f8e5e4c4448bc7cda96e8476d6aec
Author: Noel Grandin 
Date:   Fri Oct 14 15:14:13 2022 +0200
tdf#129101 CTRL+A & Cut very slow
avoid repeated invalidation of number tree, shaves 90% time off

The problem is that, after the above change, InvalidateListTree is not
called late enough to force invalidation of all necessary stuff.

So simply delay that until we do re-validation in SwNumRule::Validate.

Change-Id: I796cc34fe7d66d4876ee06286a8af7029a759eca
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160974
Tested-by: Jenkins
Reviewed-by: Noel Grandin 
(cherry picked from commit 62afdd6f82c51cee330b278518622eaf1776e2c4)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161011

diff --git a/sw/qa/uitest/writer_tests7/tdf144439.py 
b/sw/qa/uitest/writer_tests7/tdf144439.py
index 34911ee4c542..4d0ce465d5ac 100644
--- a/sw/qa/uitest/writer_tests7/tdf144439.py
+++ b/sw/qa/uitest/writer_tests7/tdf144439.py
@@ -40,6 +40,28 @@ class tdf144439(UITestCase):
 self.assertEqual(Para1.String, "List item")
 self.assertEqual(Para1.getPropertyValue("ListLabelString"), "1.1.")
 
+# this section is checking tdf#154864 - Changing starting number 
of numbered list does nothing
+#
+
+with 
self.ui_test.execute_dialog_through_command(".uno:BulletsAndNumberingDialog") 
as xDialog:
+# Select custom tab
+xTabs = xDialog.getChild("tabcontrol")
+select_pos(xTabs, "5")
+
+# Select numbering
+xNumFmt = xDialog.getChild("numfmtlb")
+select_by_text(xNumFmt, "1, 2, 3, ...")
+
+# Increase "start at"
+xStartAt = xDialog.getChild("startat")
+xStartAt.executeAction("UP", tuple())
+xStartAt.executeAction("UP", tuple())
+
+Paragraphs = document.Text.createEnumeration()
+Para1 = Paragraphs.nextElement()
+self.assertEqual(Para1.String, "List item")
+self.assertEqual(Para1.getPropertyValue("ListLabelString"), "1.3.")
+
 def test_tdf144439_outline(self):
 with self.ui_test.create_doc_in_start_center("writer") as document:
 xWriterDoc = self.xUITest.getTopFocusWindow()
diff --git a/sw/source/core/doc/number.cxx b/sw/source/core/doc/number.cxx
index d2cb98924e0f..9cef97ddc2fe 100644
--- a/sw/source/core/doc/number.cxx
+++ b/sw/source/core/doc/number.cxx
@@ -153,10 +153,17 @@ void SwNumRule::RemoveTextNode( SwTextNode& rTextNode )
 {
 tTextNodeList::iterator aIter =
 std::find( maTextNodeList.begin(), maTextNodeList.end(),  );
+if ( aIter == maTextNodeList.end() )
+return;
 
-if ( aIter != maTextNodeList.end() )
+maTextNodeList.erase( aIter );
+
+// Just in case we remove a node after we have marked the rule invalid, 
but before we have validated the tree
+if (mbInvalidRuleFlag)
 {
-maTextNodeList.erase( aIter );
+SwList* pList = 
rTextNode.GetDoc().getIDocumentListsAccess().getListByName( 
rTextNode.GetListId() );
+if (pList)
+pList->InvalidateListTree();
 }
 }
 
@@ -1051,23 +1058,6 @@ void SwNumRule::SetInvalidRule(bool bFlag)
 if (mbInvalidRuleFlag == bFlag)
 return;
 
-if (bFlag)
-{
-o3tl::sorted_vector< SwList* > aLists;
-for ( const SwTextNode* pTextNode : maTextNodeList )
-{
-// #i111681# - applying patch from cmc
-SwList* pList = 
pTextNode->GetDoc().getIDocumentListsAccess().getListByName( 
pTextNode->GetListId() );
-OSL_ENSURE( pList, " - list at 
which the text node is registered at does not exist. This is a serious issue.");
-if ( pList )
-{
-aLists.insert( pList );
-}
-}
-for ( auto aList : aLists )
-aList->InvalidateListTree();
-}
-
 mbInvalidRuleFlag = bFlag;
 }
 
@@ -1168,8 +1158,13 @@ void SwNumRule::Validate(const SwDoc& rDoc)
 o3tl::sorted_vector< SwList* > aLists;
 for ( const SwTextNode* pTextNode : maTextNodeList )
 {
-aLists.insert( 
pTextNode->GetDoc().getIDocumentListsAccess().getListByName( 
pTextNode->GetListId() ) );
+SwList* pList = 
pTextNode->GetDoc().getIDocumentListsAccess().getListByName( 
pTextNode->GetListId() );
+aLists.insert( pList );
 }
+
+

core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2023-12-15 Thread Miklos Vajna (via logerrit)
 sw/qa/uitest/data/floattable-in-shape-text.docx |binary
 sw/qa/uitest/ui/frmdlg/frmdlg.py|   35 
 sw/source/ui/frmdlg/frmpage.cxx |   30 
 3 files changed, 65 insertions(+)

New commits:
commit b6b682d3c78ec61456572c6837ad94716a1fa0f9
Author: Miklos Vajna 
AuthorDate: Fri Dec 15 08:42:21 2023 +0100
Commit: Miklos Vajna 
CommitDate: Fri Dec 15 14:08:22 2023 +0100

sw floattable: disable UI to enable this when anchored inside TextBox

Similar to headers or footers, shape text is another area where
multi-page floating tables don't make sense, the Word UI to float a
table in shape text is even disabled.

Our UI to create a floating table is to select a table and then insert
frame, and that already refused to make a new frame around a table to
split. However, one could be creative and enable the split only later,
and that was allowed.

Fix the problem by extending SwFramePage::Reset(), so in case the
currently selected frame is edited and it's anchored in a Word-style
shape+text, then the checkbox to allow the split is hidden.

This is meant to help users to not create document model that would be
later problematic to export to Word formats.

Change-Id: I63e981bd93fd16195ccdac2d5a5ec785e7c18b97
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160814
Reviewed-by: Miklos Vajna 
Tested-by: Jenkins
(cherry picked from commit 4e8895d3d86db3776c56070c395cd727fd4b9101)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160806

diff --git a/sw/qa/uitest/data/floattable-in-shape-text.docx 
b/sw/qa/uitest/data/floattable-in-shape-text.docx
new file mode 100644
index ..357213d12912
Binary files /dev/null and b/sw/qa/uitest/data/floattable-in-shape-text.docx 
differ
diff --git a/sw/qa/uitest/ui/frmdlg/frmdlg.py b/sw/qa/uitest/ui/frmdlg/frmdlg.py
index 51b6f6e53199..36de1876bdd9 100644
--- a/sw/qa/uitest/ui/frmdlg/frmdlg.py
+++ b/sw/qa/uitest/ui/frmdlg/frmdlg.py
@@ -115,4 +115,39 @@ class Test(UITestCase):
 # inconsistent.
 self.assertTrue(to_char_enabled)
 
+def test_floattable_in_shape_text(self):
+with 
self.ui_test.load_file(get_url_for_data_file("floattable-in-shape-text.docx")) 
as xComponent:
+# Given a table in a frame, anchored in shape text (TextBox case):
+self.xUITest.executeCommand(".uno:SelectAll")
+# Insert frame around the selected table:
+args = {
+"AnchorType": 0,
+}
+self.xUITest.executeCommandWithParameters(".uno:InsertFrame", 
mkPropertyValues(args))
+# Cut it from the body text:
+self.xUITest.executeCommand(".uno:Cut")
+# Select the shape:
+
xComponent.CurrentController.select(xComponent.DrawPage.getByIndex(0))
+xWriterDoc = self.xUITest.getTopFocusWindow()
+xWriterEdit = xWriterDoc.getChild("writer_edit")
+# Begin text edit on the shape:
+xWriterEdit.executeAction("TYPE", 
mkPropertyValues({"KEYCODE":"F2"}))
+# Paste it into the shape text:
+self.xUITest.executeCommand(".uno:Paste")
+
+# When editing that frame:
+visible = "true"
+with 
self.ui_test.execute_dialog_through_command(".uno:FrameDialog") as xDialog:
+xFlysplit = xDialog.getChild("flysplit")
+visible = get_state_as_dict(xFlysplit)['Visible']
+
+# Then make sure that the option allow split is hidden:
+# Without the accompanying fix in place, this test would have 
failed with:
+# AssertionError: 'true' != 'false'
+# - true
+# + false
+# i.e. the UI allowed creating split floating tables in shape 
text, which is unnecessary
+# complexity.
+self.assertEqual(visible, "false")
+
 # vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/sw/source/ui/frmdlg/frmpage.cxx b/sw/source/ui/frmdlg/frmpage.cxx
index bdf1c90291ff..b3e2a873ad18 100644
--- a/sw/source/ui/frmdlg/frmpage.cxx
+++ b/sw/source/ui/frmdlg/frmpage.cxx
@@ -829,6 +829,31 @@ bool ContainsChain(const SwFrameFormat& rFlyFormat)
 const SwFormatChain& rChain = rFlyFormat.GetChain();
 return rChain.GetPrev() || rChain.GetNext();
 }
+
+/// Determines if rFlyFormat is anchored in a fly frame that is part of a 
draw-format + fly-format
+/// ("textbox") pair.
+bool InTextBox(const SwFrameFormat& rFlyFormat)
+{
+const SwFormatAnchor& rAnchor = rFlyFormat.GetAnchor();
+SwNode* pAnchorNode = rAnchor.GetAnchorNode();
+if (!pAnchorNode)
+{
+return false;
+}
+
+const SwStartNode* pFlyNode = pAnchorNode->FindFlyStartNode();
+if (!pFlyNode)
+{
+return false;
+}
+
+if (!pFlyNode->GetFlyFormat()->GetOtherTextBoxFormats())
+{
+

core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2023-12-14 Thread Miklos Vajna (via logerrit)
 sw/qa/core/txtnode/txtnode.cxx   |   14 +-
 sw/source/core/layout/flylay.cxx |   11 +++
 2 files changed, 24 insertions(+), 1 deletion(-)

New commits:
commit a74d8487c9bb2f586067f2139e8c136628da2da4
Author: Miklos Vajna 
AuthorDate: Thu Dec 14 08:39:50 2023 +0100
Commit: Miklos Vajna 
CommitDate: Thu Dec 14 16:13:44 2023 +0100

sw floattable: fix outdated text frame portions after split

The document has a floating table of 2 pages, with some anchor text on
page 2. Split of the anchor text resulted in 2 paragraphs: the first
still hosts the floating table and now lacks a fly portion (overlap of
text and floating table) and the second still wraps around the floating
table but has the correct position.

What happens is that we format the first text frame, then its flys
(which moves the follow fly from page 1 to page 2) and then we format
the second text frame. This means that the first text frame should have
a fly portion to wrap around the floating table, but it does not have,
because SwTextFrame::Format() is called for the first text frame, then
SwPageFrame::MoveFly() is called, then SwTextFrame::Format() for the
second text frame, i.e. no reformat of the first text frame after moving
the fly.

Fix the problem somewhat similar to what commit
cf2c070de2bafeec3b476c6bff7bb4ac87ba46db (sw layout: invalidate margins
of body content when moving a fly from page, 2022-12-09) did, but here
what's outdated is the portions of the text frame, and only for the
anchor text frame.

This fixes the problem in practice, but note that in theory this could
affect non-split flys and also other, non-anchor text frames as well.
Limit the update of the portion list to the anchor of the split fly, but
we may want to do the same for all lowers of the body frame if there is
a practical need for it.

Change-Id: I3067e78d30e16ed3d2f02a80cff4cd84d9bdcf3b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160748
Reviewed-by: Miklos Vajna 
Tested-by: Jenkins
(cherry picked from commit 5fec60b4732bdbdb681be08e43a9be47c3bfb320)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160704

diff --git a/sw/qa/core/txtnode/txtnode.cxx b/sw/qa/core/txtnode/txtnode.cxx
index 5b4023a41dc6..c2df8a407e69 100644
--- a/sw/qa/core/txtnode/txtnode.cxx
+++ b/sw/qa/core/txtnode/txtnode.cxx
@@ -517,7 +517,7 @@ CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, 
testSplitFlyAnchorSplit)
 CPPUNIT_ASSERT(pPage1->GetSortedObjs());
 auto pPage2 = pPage1->GetNext()->DynCastPageFrame();
 CPPUNIT_ASSERT(pPage2);
-// Page 1 has the follow fly:
+// Page 2 has the follow fly:
 CPPUNIT_ASSERT(pPage2->GetSortedObjs());
 // Anchor text is now just "A":
 auto pText1 = pPage2->FindFirstBodyContent()->DynCastTextFrame();
@@ -525,6 +525,18 @@ CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, 
testSplitFlyAnchorSplit)
 // New text frame is just "B":
 auto pText2 = pText1->GetNext()->DynCastTextFrame();
 CPPUNIT_ASSERT_EQUAL(OUString("B"), pText2->GetText());
+
+// Also test that the new follow anchor text frame still has a fly 
portion, otherwise the anchor
+// text and the floating table would overlap:
+xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+OUString aPortionType
+= getXPath(pXmlDoc, 
"//page[2]/body/txt[1]/SwParaPortion/SwLineLayout[1]/child::*[1]"_ostr,
+   "type"_ostr);
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected: PortionType::Fly
+// - Actual  : PortionType::Para
+// i.e. the fly portion was missing, text overlapped.
+CPPUNIT_ASSERT_EQUAL(OUString("PortionType::Fly"), aPortionType);
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/layout/flylay.cxx b/sw/source/core/layout/flylay.cxx
index e507e92e6dcd..457a0d41bbf3 100644
--- a/sw/source/core/layout/flylay.cxx
+++ b/sw/source/core/layout/flylay.cxx
@@ -1039,6 +1039,17 @@ void SwPageFrame::MoveFly( SwFlyFrame *pToMove, 
SwPageFrame *pDest )
 // #i28701#
 pToMove->UnlockPosition();
 
+if (pToMove->IsFlySplitAllowed())
+{
+// Inserting a fly to the page affects the fly portions of the 
intersecting paragraphs, so
+// update the portions of the anchor of the fly frame.
+SwTextFrame* pAnchor = pToMove->FindAnchorCharFrame();
+if (pAnchor)
+{
+pAnchor->ClearPara();
+}
+}
+
 // Notify accessible layout. That's required at this place for
 // frames only where the anchor is moved. Creation of new frames
 // is additionally handled by the SwFrameNotify class.


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2023-12-14 Thread Miklos Vajna (via logerrit)
 sw/qa/core/layout/flycnt.cxx |   19 +--
 sw/source/core/txtnode/ndtxt.cxx |2 +-
 2 files changed, 14 insertions(+), 7 deletions(-)

New commits:
commit 83c300d00d25aa85381d91ed82b236ee8bb37a67
Author: Miklos Vajna 
AuthorDate: Wed Dec 13 08:32:02 2023 +0100
Commit: Miklos Vajna 
CommitDate: Thu Dec 14 09:45:42 2023 +0100

sw floattable: fix split of anchor text at para start

The document has a floating table with some anchor text. If we hit enter
at the end of the anchor text, the anchor text remains in the old text
node and a new text node is inserted after it, still wrapping around the
floating table. If you do the same at the start of the anchor text, then
a new paragraph is inserted before the floating table, which is
unexpected.

The OOXML concept we try to model here is that a floating table is a
table-in-fly that's followed by a paragraph that hosts the anchor text,
so the anchor position of the floating table should never change. This
behavior was even locked down in the testSplitFlyMoveMaster testcase,
but there the motivation was to make sure the fly chain is consistent.

Fix the problem by removing the special-casing in
SwTextNode::SplitContentNode() for the "at para start" case that was
added just to please the testcase. Instead update the test assert the
bad 1 -> 4 -> 2 chain is not there, so it still covers the old fix but
allows the new behavior.

With this, the Word and Writer UI behaves the same when inserting a new
para right after a floating table. The layout position problem of the
empty text node (should be wrapped, is not) still needs fixing.

(cherry picked from commit d852e27ed205c1a60de0979b80f3861bf93c44ae)

Change-Id: Ib9a1f07eeb144ea929183cdc72a22bc23042fee1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160749
Tested-by: Jenkins
Reviewed-by: Miklos Vajna 

diff --git a/sw/qa/core/layout/flycnt.cxx b/sw/qa/core/layout/flycnt.cxx
index 6b84ca3fb16d..455012ea4948 100644
--- a/sw/qa/core/layout/flycnt.cxx
+++ b/sw/qa/core/layout/flycnt.cxx
@@ -,20 +,27 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFlyMoveMaster)
 // Given a document with a multi-page floating table on pages 1 -> 2 -> 3:
 createSwDoc("floattable-move-master.docx");
 
-// When adding an empty para before the table, so the table gets shifted 
to pages 2 -> 3:
+// When adding an empty para at the start of the anchor text of the table:
 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
 pWrtShell->SttEndDoc(/*bStt=*/true);
 pWrtShell->Down(/*bSelect=*/false, /*nCount=*/4);
 pWrtShell->SplitNode();
 
-// Then make sure page 1 has no flys, page 2 and 3 has the split fly and 
no flys on page 4:
+// Then make sure page the fly chain is pages 1 -> 2 -> 3, still:
 SwDoc* pDoc = getSwDoc();
 SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
 auto pPage1 = pLayout->Lower()->DynCastPageFrame();
 CPPUNIT_ASSERT(pPage1);
-// Without the accompanying fix in place, this test would have failed, the 
start of the fly was
-// still on page 1 instead of page 2.
-CPPUNIT_ASSERT(!pPage1->GetSortedObjs());
+// Without the accompanying fix in place, this test would have failed, the 
fly chain was pages 1
+// -> 4 -> 2.
+CPPUNIT_ASSERT(pPage1->GetSortedObjs());
+CPPUNIT_ASSERT(pPage1->GetSortedObjs());
+SwSortedObjs& rPage1Objs = *pPage1->GetSortedObjs();
+CPPUNIT_ASSERT_EQUAL(static_cast(1), rPage1Objs.size());
+auto pPage1Fly = 
rPage1Objs[0]->DynCastFlyFrame()->DynCastFlyAtContentFrame();
+CPPUNIT_ASSERT(pPage1Fly);
+CPPUNIT_ASSERT(!pPage1Fly->GetPrecede());
+CPPUNIT_ASSERT(pPage1Fly->HasFollow());
 auto pPage2 = pPage1->GetNext()->DynCastPageFrame();
 CPPUNIT_ASSERT(pPage2);
 CPPUNIT_ASSERT(pPage2->GetSortedObjs());
@@ -1132,7 +1139,7 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFlyMoveMaster)
 CPPUNIT_ASSERT_EQUAL(static_cast(1), rPage2Objs.size());
 auto pPage2Fly = 
rPage2Objs[0]->DynCastFlyFrame()->DynCastFlyAtContentFrame();
 CPPUNIT_ASSERT(pPage2Fly);
-CPPUNIT_ASSERT(!pPage2Fly->GetPrecede());
+CPPUNIT_ASSERT(pPage2Fly->GetPrecede());
 CPPUNIT_ASSERT(pPage2Fly->HasFollow());
 auto pPage3 = pPage2->GetNext()->DynCastPageFrame();
 CPPUNIT_ASSERT(pPage3);
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 8cce58df0960..47bff5e08bac 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -464,7 +464,7 @@ SwTextNode *SwTextNode::SplitContentNode(const SwPosition & 
rPos,
 
 bool bSplitFly = false;
 std::optional> oFlys = 
sw::GetFlysAnchoredAt(GetDoc(), GetIndex());
-if (oFlys.has_value() && nSplitPos > 0)
+if (oFlys.has_value())
 {
 // See if one of the flys is a split fly. If so, we need to keep

core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2023-12-14 Thread Vojtěch Doležal (via logerrit)
 sw/qa/core/text/data/tdf158505.odt  |binary
 sw/qa/core/text/text.cxx|   12 
 sw/source/core/text/EnhancedPDFExportHelper.cxx |5 -
 sw/source/uibase/shells/textidx.cxx |6 ++
 4 files changed, 22 insertions(+), 1 deletion(-)

New commits:
commit 347e8161ba38822de96851dd7ed92b7e85ac1943
Author: Vojtěch Doležal 
AuthorDate: Sat Dec 9 11:03:05 2023 +0100
Commit: Xisco Fauli 
CommitDate: Thu Dec 14 09:44:14 2023 +0100

tdf#158505 - Fix PDF export when bibliography is last paragraph

Change-Id: Iadafff97ba19d5c24be768238bddb4d684edde1c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160509
Tested-by: Jenkins
Reviewed-by: Mike Kaganski 
(cherry picked from commit 94d18ea557a03c1f2d450454908787f7d3af8a6e)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160646
Reviewed-by: Xisco Fauli 

diff --git a/sw/qa/core/text/data/tdf158505.odt 
b/sw/qa/core/text/data/tdf158505.odt
new file mode 100644
index ..c9a71033a2de
Binary files /dev/null and b/sw/qa/core/text/data/tdf158505.odt differ
diff --git a/sw/qa/core/text/text.cxx b/sw/qa/core/text/text.cxx
index 7340a151d1f4..666e6d29f250 100644
--- a/sw/qa/core/text/text.cxx
+++ b/sw/qa/core/text/text.cxx
@@ -103,6 +103,18 @@ CPPUNIT_TEST_FIXTURE(SwCoreTextTest, 
testSemiTransparentText)
 assertXPath(pXmlDoc, "//floattransparent"_ostr);
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testLastBibliographyPdfExport)
+{
+// Given a document with a bibliography as the last paragraph:
+createSwDoc("tdf158505.odt");
+
+// It should be possible to export to PDF:
+save("writer_pdf_Export");
+
+// Without the accompanying fix, the export to PDF would get stuck in an 
infinite loop
+CPPUNIT_ASSERT(true);
+}
+
 CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testBibliographyUrlPdfExport)
 {
 // Given a document with a bibliography entry field:
diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx 
b/sw/source/core/text/EnhancedPDFExportHelper.cxx
index 2bf5ca3f883d..499dcc24178a 100644
--- a/sw/source/core/text/EnhancedPDFExportHelper.cxx
+++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx
@@ -2825,7 +2825,10 @@ void 
SwEnhancedPDFExportHelper::ExportAuthorityEntryLinks()
 }
 }
 }
-mrSh.MovePara(GoNextPara, fnParaStart);
+if (!mrSh.MovePara(GoNextPara, fnParaStart))
+{ // Cursor is stuck in the TOX due to document ending 
immediately afterwards
+break;
+}
 }
 }
 }
diff --git a/sw/source/uibase/shells/textidx.cxx 
b/sw/source/uibase/shells/textidx.cxx
index 45d9df2c70b6..35642a73f198 100644
--- a/sw/source/uibase/shells/textidx.cxx
+++ b/sw/source/uibase/shells/textidx.cxx
@@ -127,6 +127,12 @@ void SwTextShell::ExecIdx(SfxRequest const )
 
rShell.GetCursor_()->GetPoint()->Assign(*pTableRowNode);
 rShell.UpdateTableOf(*pCurrentTOX);
 }
+else
+{
+// I think this ideally should be a pop-up warning, 
right?
+SAL_WARN("sw", "No matching bibliography mark found. "
+"This feature is only guaranteed to 
work if the bibliography table is up to date.");
+}
 }
 }
 


core.git: Branch 'libreoffice-24-2' - sw/qa sw/source

2023-12-12 Thread Miklos Vajna (via logerrit)
 sw/qa/core/txtnode/data/floattable-anchor-split.docx |binary
 sw/qa/core/txtnode/txtnode.cxx   |   36 +++
 sw/source/core/txtnode/ndtxt.cxx |   21 ++-
 3 files changed, 56 insertions(+), 1 deletion(-)

New commits:
commit fa61b425e6c84f2a949b80acff35ac07db3a92b0
Author: Miklos Vajna 
AuthorDate: Tue Dec 12 08:39:54 2023 +0100
Commit: Miklos Vajna 
CommitDate: Tue Dec 12 11:58:40 2023 +0100

sw floattable: fix split of anchor text in 2nd half of the paragraph

If you go to the anchor text of the floating table and you press enter
in the second half of the anchor text, you get a layout loop.

The reason for this: an invariant around split text frames were
violated, later resulting in a layout loop. The rule is that in case you
have a split frame, then there can't be a frame for a new text node
between the two split frames. So no new text frame for an other node
after the master anchor of the fly; no new text frame for an other node
before the follow anchor of the fly.

Fix the problem by improving SwTextNode::SplitContentNode() to check if
this is an anchor for a split fly: if so, always insert the new text
frame after the follow anchor of the fly, which doesn't break the above
invariant.

The layout loop is fixed, but the text in the follow anchor of the fly
still has a bad position, that still needs fixing. Also currently
testSplitFlyMoveMaster enforces that split at the para start inserts a
paragraph before the floating table, so leave that case unchanged for
now.

Change-Id: I77962a354e297d2e9957edcce9bf140f2c72fc6e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160608
Reviewed-by: Miklos Vajna 
Tested-by: Jenkins
(cherry picked from commit 0746d13365139c356eb9d297a358c486bf47d6fb)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160586

diff --git a/sw/qa/core/txtnode/data/floattable-anchor-split.docx 
b/sw/qa/core/txtnode/data/floattable-anchor-split.docx
new file mode 100644
index ..a5dcdb28eb8c
Binary files /dev/null and 
b/sw/qa/core/txtnode/data/floattable-anchor-split.docx differ
diff --git a/sw/qa/core/txtnode/txtnode.cxx b/sw/qa/core/txtnode/txtnode.cxx
index 9369a187c482..5b4023a41dc6 100644
--- a/sw/qa/core/txtnode/txtnode.cxx
+++ b/sw/qa/core/txtnode/txtnode.cxx
@@ -21,6 +21,7 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -37,6 +38,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 /// Covers sw/source/core/txtnode/ fixes.
 class SwCoreTxtnodeTest : public SwModelTestBase
@@ -491,6 +495,38 @@ CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, 
testFlySplitFootnote)
 CPPUNIT_ASSERT(!pDoc->GetFootnoteIdxs().empty());
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, testSplitFlyAnchorSplit)
+{
+// Given a document with a 2 pages long floating table:
+createSwDoc("floattable-anchor-split.docx");
+
+// When splitting the "AB" anchor text into "A" (remains as anchor text) 
and "B" (new text node
+// after it):
+SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
+pWrtShell->SttEndDoc(/*bStt=*/false);
+pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, 
/*bBasicCall=*/false);
+// Without the accompanying fix in place, this test would have failed with 
a layout loop.
+pWrtShell->SplitNode();
+
+// Then make sure the resulting layout is what we want:
+SwDoc* pDoc = getSwDoc();
+SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+auto pPage1 = pLayout->Lower()->DynCastPageFrame();
+CPPUNIT_ASSERT(pPage1);
+// Page 1 has the master fly:
+CPPUNIT_ASSERT(pPage1->GetSortedObjs());
+auto pPage2 = pPage1->GetNext()->DynCastPageFrame();
+CPPUNIT_ASSERT(pPage2);
+// Page 1 has the follow fly:
+CPPUNIT_ASSERT(pPage2->GetSortedObjs());
+// Anchor text is now just "A":
+auto pText1 = pPage2->FindFirstBodyContent()->DynCastTextFrame();
+CPPUNIT_ASSERT_EQUAL(OUString("A"), pText1->GetText());
+// New text frame is just "B":
+auto pText2 = pText1->GetNext()->DynCastTextFrame();
+CPPUNIT_ASSERT_EQUAL(OUString("B"), pText2->GetText());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 541e3fd5049f..8cce58df0960 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -83,6 +83,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 using namespace ::com::sun::star;
 
@@ -460,7 +462,24 @@ SwTextNode *SwTextNode::SplitContentNode(const SwPosition 
& rPos,
 ResetAttr( RES_PARATR_LIST_LEVEL );
 }
 
-if ( HasWriterListeners() && !m_Text.isEmpty() && (nTextLen / 2) < 
nSplitPos )
+bool bSplitFly = false;
+std::optional> oFlys =