core.git: sw/qa sw/source

2024-06-07 Thread Miklos Vajna (via logerrit)
 sw/qa/writerfilter/dmapper/DomainMapper.cxx  |   24 +++
 sw/qa/writerfilter/dmapper/data/table-style-para-border.docx |binary
 sw/source/writerfilter/dmapper/DomainMapper.cxx  |9 
 3 files changed, 33 insertions(+)

New commits:
commit 39c54c0ef837e0e23a676a4d1fa5da667e18939c
Author: Miklos Vajna 
AuthorDate: Fri Jun 7 09:14:21 2024 +0200
Commit: Miklos Vajna 
CommitDate: Fri Jun 7 10:20:05 2024 +0200

tdf#161443 DOCX import, table style: fix para border leaking into cell 
border

Open the document with a single table, notice that start of the text in
A1 cell is missing.

Seems what happens is that the cell has some positive border distance,
then the para has the same negative left margin, so in total there is 0
left margin for the text, which makes this readable in Word. On our
side, we map the paragraph border from the table style to the
LeftBorderDistance property, then throw this on the cell object, which
gives us 0 border distance, so the negative para left margin results in
an unwanted shift of text towards the left: the start of the text is
hidden by clipping to make sure the painted text is inside the cell
frame. (Both paragraphs and cells have a LeftBorderDistance property, by
accident.)

Given that a visible paragraph border from table style is not actually
imported, first just do the minimal fix and make sure we don't import
paragraph borders from table style at all: this solves the problem of
unwanted 0 cell border distances and the full text is now readable.

In case the paragraph border in the table style would be actually
visible, that would be useful to route to the paragraphs in the cell,
that's not yet done here.

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

diff --git a/sw/qa/writerfilter/dmapper/DomainMapper.cxx 
b/sw/qa/writerfilter/dmapper/DomainMapper.cxx
index 5c6b429bc9f6..851ab20412e8 100644
--- a/sw/qa/writerfilter/dmapper/DomainMapper.cxx
+++ b/sw/qa/writerfilter/dmapper/DomainMapper.cxx
@@ -13,6 +13,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -161,6 +162,29 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf158360)
 // just test that doc with annotation in TOC doesn't crash/assert
 loadFromFile(u"tdf158360.docx");
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testTableStyleParaBorder)
+{
+// Given a document with a table, table style defines 115 twips left cell 
margin and an empty
+// paragraph border:
+// When importing that file:
+loadFromFile(u"table-style-para-border.docx");
+
+// Then make sure the cell margin is not lost:
+uno::Reference xTextDocument(mxComponent, 
uno::UNO_QUERY);
+uno::Reference 
xParaEnumAccess(xTextDocument->getText(),
+  
uno::UNO_QUERY);
+uno::Reference xParaEnum = 
xParaEnumAccess->createEnumeration();
+uno::Reference xPara(xParaEnum->nextElement(), 
uno::UNO_QUERY);
+uno::Reference xCell(xPara->getCellByName("A1"), 
uno::UNO_QUERY);
+sal_Int32 nLeftBorderDistance{};
+xCell->getPropertyValue("LeftBorderDistance") >>= nLeftBorderDistance;
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected: 203
+// - Actual  : 0
+// i.e. the 0 para border distance was applied on the cell instead.
+CPPUNIT_ASSERT_EQUAL(static_cast(203), nLeftBorderDistance);
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/writerfilter/dmapper/data/table-style-para-border.docx 
b/sw/qa/writerfilter/dmapper/data/table-style-para-border.docx
new file mode 100644
index ..0d7154eade1f
Binary files /dev/null and 
b/sw/qa/writerfilter/dmapper/data/table-style-para-border.docx differ
diff --git a/sw/source/writerfilter/dmapper/DomainMapper.cxx 
b/sw/source/writerfilter/dmapper/DomainMapper.cxx
index 72f88fc2a1a3..30c5f02fb693 100644
--- a/sw/source/writerfilter/dmapper/DomainMapper.cxx
+++ b/sw/source/writerfilter/dmapper/DomainMapper.cxx
@@ -1654,6 +1654,15 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const 
PropertyMapPtr& rContext )
 PropertyIds eBorderId = PropertyIds::INVALID;
 PropertyIds eBorderComplexColorId = PropertyIds::INVALID;
 PropertyIds eBorderDistId = PropertyIds::INVALID;
+
+const StyleSheetEntryPtr& pEntry = 
GetStyleSheetTable()->GetCurrentEntry();
+if (pEntry && pEntry->m_nStyleTypeCode == STYLE_TYPE_TABLE)
+{
+// This would map para borders in table style to cell borders, 
avoid that till we
+// have separate property names for these.
+break;
+}
+
 switch( nSprmId )
 {
 case NS_ooxml::LN_CT_PBdr_top:


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

2024-06-06 Thread Miklos Vajna (via logerrit)
 sw/CppunitTest_sw_core_text.mk|1 
 sw/qa/core/text/data/clearing-break-wrap-through.docx |binary
 sw/qa/core/text/txtfly.cxx|   52 ++
 sw/source/core/text/txtfly.cxx|7 ++
 4 files changed, 60 insertions(+)

New commits:
commit 317e12faa71dab378da6db48b5d612ad258c058c
Author: Miklos Vajna 
AuthorDate: Thu May 30 08:10:13 2024 +0200
Commit: Xisco Fauli 
CommitDate: Thu Jun 6 16:35:37 2024 +0200

tdf#161318 sw clearing break: ignore wrap-through anchored objects

Import the bugdoc: we expect just a single page for the 2 paragraphs,
but the second paragraph goes to a 2nd page.

What seems to happen since commit
f86d1482bef285f90079b5130e410646db96cf58 (sw clearing breaks: add DOCX
import, 2022-03-08) is that on one hand, SwTextFly::ForEach() ignores
wrap-through shapes, but at the same time SwTextFly::GetMaxBottom() did
not, and this lead to a loop: the first paragraph kept growing till the
shape was shifted to page 2, but then the same first paragraph was
reduced to just 2 lines, goto 1.

Fix the problem by extending SwTextFly::GetMaxBottom() to also ignore
wrap-though shapes: this is the intention, just clearing breaks were not
tested with wrap-though wrap mode before.

This is a reduced bugdoc, the original one even produced warnings like:
warn:legacy.osl:12034:12034:sw/source/core/layout/flowfrm.cxx:2667: 
 - layout loop control for layout action  applied!
without the fix, and these are now gone.

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

diff --git a/sw/CppunitTest_sw_core_text.mk b/sw/CppunitTest_sw_core_text.mk
index ce27696b3c4c..5e623d3b0cd0 100644
--- a/sw/CppunitTest_sw_core_text.mk
+++ b/sw/CppunitTest_sw_core_text.mk
@@ -20,6 +20,7 @@ $(eval $(call 
gb_CppunitTest_add_exception_objects,sw_core_text, \
 sw/qa/core/text/porlay \
 sw/qa/core/text/porrst \
 sw/qa/core/text/text \
+sw/qa/core/text/txtfly \
 ))
 
 $(eval $(call gb_CppunitTest_use_libraries,sw_core_text, \
diff --git a/sw/qa/core/text/data/clearing-break-wrap-through.docx 
b/sw/qa/core/text/data/clearing-break-wrap-through.docx
new file mode 100644
index ..c96e8c27da5e
Binary files /dev/null and 
b/sw/qa/core/text/data/clearing-break-wrap-through.docx differ
diff --git a/sw/qa/core/text/txtfly.cxx b/sw/qa/core/text/txtfly.cxx
new file mode 100644
index ..461ed81e2203
--- /dev/null
+++ b/sw/qa/core/text/txtfly.cxx
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-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/.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+namespace
+{
+/// Covers sw/source/core/text/txtfly.cxx fixes.
+class Test : public SwModelTestBase
+{
+public:
+Test()
+: SwModelTestBase("/sw/qa/core/text/data/")
+{
+}
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testClearingBreakWrapThrough)
+{
+// Given a document with a clearing break, then a shape in the next 
paragraph:
+createSwDoc("clearing-break-wrap-through.docx");
+
+// When laying out that document:
+calcLayout();
+
+// Then make sure we layout these 2 paragraphs on a single page, since 
there is enough space for
+// them:
+SwDoc* pDoc = getSwDoc();
+SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+auto pPage = pLayout->Lower()->DynCastPageFrame();
+CPPUNIT_ASSERT(pPage);
+// Without the accompanying fix in place, this test would have failed, we 
had an unexpected 2nd
+// page.
+CPPUNIT_ASSERT(!pPage->GetNext());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/txtfly.cxx b/sw/source/core/text/txtfly.cxx
index 7c4d9a2e160d..45eea853 100644
--- a/sw/source/core/text/txtfly.cxx
+++ b/sw/source/core/text/txtfly.cxx
@@ -1051,6 +1051,13 @@ SwTwips SwTextFly::GetMaxBottom(const SwBreakPortion& 
rPortion, const SwTextForm
 continue;
 }
 
+const SwFormatSurround& rSurround = 
pAnchoredObj->GetFrameFormat()->GetSurround();
+if (rSurround.GetValue() == text::WrapTextMode_THROUGH)
+{
+// Wrap through has no influence on clearing breaks.
+continue;
+}
+
 SwRect aRect(pAnchoredObj->GetObjRectWithSpaces());
 
 if (m_pCurrFrame->IsVertical())


core.git: cpp.hint sw/qa

2024-06-06 Thread Miklos Vajna (via logerrit)
 cpp.hint  |1 -
 sw/qa/inc/swmodeltestbase.hxx |1 -
 2 files changed, 2 deletions(-)

New commits:
commit c6a2fb62947ae8411a8a336d74f2ceb2258c899c
Author: Miklos Vajna 
AuthorDate: Thu Jun 6 08:12:01 2024 +0200
Commit: Miklos Vajna 
CommitDate: Thu Jun 6 09:58:39 2024 +0200

sw: remove unused DECLARE_RTFEXPORT_TEST()

Replaced by CPPUNIT_TEST_FIXTURE().

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

diff --git a/cpp.hint b/cpp.hint
index 1000d44cd627..727243a3f966 100644
--- a/cpp.hint
+++ b/cpp.hint
@@ -57,7 +57,6 @@
 void TestName::verify()
 
 #define DECLARE_OOXMLEXPORT_TEST(TestName, filename) 
DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, nullptr, Test)
-#define DECLARE_RTFEXPORT_TEST(TestName, filename) 
DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, nullptr, Test)
 #define DECLARE_ODFEXPORT_TEST(TestName, filename) 
DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, nullptr, Test)
 #define DECLARE_FODFEXPORT_TEST(TestName, filename) 
DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, nullptr, Test)
 #define DECLARE_WW8EXPORT_TEST(TestName, filename) 
DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, nullptr, Test)
diff --git a/sw/qa/inc/swmodeltestbase.hxx b/sw/qa/inc/swmodeltestbase.hxx
index 579fb77e7217..e4fff44da2bc 100644
--- a/sw/qa/inc/swmodeltestbase.hxx
+++ b/sw/qa/inc/swmodeltestbase.hxx
@@ -56,7 +56,6 @@
 void TestName::verify()
 
 #define DECLARE_OOXMLEXPORT_TEST(TestName, filename) 
DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, nullptr, Test)
-#define DECLARE_RTFEXPORT_TEST(TestName, filename) 
DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, nullptr, Test)
 #define DECLARE_ODFEXPORT_TEST(TestName, filename) 
DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, nullptr, Test)
 #define DECLARE_FODFEXPORT_TEST(TestName, filename) 
DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, nullptr, Test)
 #define DECLARE_WW8EXPORT_TEST(TestName, filename) 
DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, nullptr, Test)


core.git: sw/qa sw/source

2024-06-05 Thread Miklos Vajna (via logerrit)
 sw/qa/extras/rtfexport/rtfexport8.cxx   |   31 +++
 sw/source/filter/ww8/rtfattributeoutput.cxx |   18 +
 sw/source/filter/ww8/rtfexport.cxx  |   55 ++--
 3 files changed, 102 insertions(+), 2 deletions(-)

New commits:
commit 937bdd08ee8ff9ce90db06fd463719ba8e9da996
Author: Miklos Vajna 
AuthorDate: Wed Jun 5 12:13:14 2024 +0200
Commit: Miklos Vajna 
CommitDate: Wed Jun 5 14:49:36 2024 +0200

tdf#161417 RTF export: handle endnotes at section ends

Similar to commit 566c7017a84e3d573de85a6d986b81d3f59de0fa (tdf#160984
sw continuous endnotes: DOCX: export of  pos == sectEnd,
2024-05-29), but this is RTF, not DOCX.

Additional complexity is that it's not enough to just write endnotes
(sect end) or enddoc (doc end) to export the position, also et and
ndnhere needs writing, otherwise Word ignores this.

Last bit is to ignore section formats which are not nullptr but are -1,
ignore these in RtfAttributeOutput::SectionBreak(), similar to how
DocxAttributeOutput::SectionBreak() does the same already.

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

diff --git a/sw/qa/extras/rtfexport/rtfexport8.cxx 
b/sw/qa/extras/rtfexport/rtfexport8.cxx
index 33219edcfe9d..347b39c68563 100644
--- a/sw/qa/extras/rtfexport/rtfexport8.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport8.cxx
@@ -39,6 +39,7 @@
 #include 
 #include 
 #include 
+#include 
 
 using namespace css;
 
@@ -173,6 +174,36 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf158586_lostFrame)
 verify();
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testEndnotesAtSectEndRTF)
+{
+// Given a document, endnotes at collected at section end:
+createSwDoc();
+{
+SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
+pWrtShell->SplitNode();
+pWrtShell->Up(/*bSelect=*/false);
+pWrtShell->Insert("x");
+pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, 
/*bBasicCall=*/false);
+SwSectionData aSection(SectionType::Content, 
pWrtShell->GetUniqueSectionName());
+pWrtShell->StartAction();
+SfxItemSetFixed 
aSet(pWrtShell->GetAttrPool());
+aSet.Put(SwFormatEndAtTextEnd(FTNEND_ATTXTEND));
+pWrtShell->InsertSection(aSection, );
+pWrtShell->EndAction();
+pWrtShell->InsertFootnote(OUString(), /*bEndNote=*/true);
+}
+
+// When saving to DOC:
+saveAndReload(mpFilter);
+
+// Then make sure the endnote position is section end:
+SwDoc* pDoc = getSwDoc();
+SwSectionFormats& rSections = pDoc->GetSections();
+SwSectionFormat* pFormat = rSections[0];
+// Without the accompanying fix in place, this test would have failed, 
endnotes were at doc end.
+CPPUNIT_ASSERT(pFormat->GetEndAtTextEnd().IsAtEnd());
+}
+
 CPPUNIT_TEST_FIXTURE(Test, testTdf158983)
 {
 auto verify = [this]() {
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx 
b/sw/source/filter/ww8/rtfattributeoutput.cxx
index 2c9f92aaa245..8721e2f0d99b 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -97,6 +97,7 @@
 #include "rtfexport.hxx"
 #include 
 #include 
+#include 
 
 using namespace ::com::sun::star;
 using namespace sw::util;
@@ -1367,6 +1368,23 @@ void RtfAttributeOutput::SectionBreak(sal_uInt8 nC, bool 
/*bBreakAfter*/,
 m_rExport.SectionProperties(*pSectionInfo);
 break;
 }
+
+// Endnotes included in the section:
+if (!pSectionInfo)
+{
+return;
+}
+const SwSectionFormat* pSectionFormat = pSectionInfo->pSectionFormat;
+if (!pSectionFormat || pSectionFormat == 
reinterpret_cast(sal_IntPtr(-1)))
+{
+// MSWordExportBase::WriteText() can set the section format to -1, 
ignore.
+return;
+}
+if (!pSectionFormat->GetEndAtTextEnd().IsAtEnd())
+{
+return;
+}
+m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_ENDNHERE);
 }
 
 void RtfAttributeOutput::StartSection()
diff --git a/sw/source/filter/ww8/rtfexport.cxx 
b/sw/source/filter/ww8/rtfexport.cxx
index 8acd96461ac6..88a3086c6dfc 100644
--- a/sw/source/filter/ww8/rtfexport.cxx
+++ b/sw/source/filter/ww8/rtfexport.cxx
@@ -70,6 +70,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 using namespace ::com::sun::star;
 
@@ -798,7 +801,8 @@ ErrCode RtfExport::ExportDocument_Impl()
 // enable it on a per-section basis. OTOH don't always enable it as it
 // breaks moving of drawings - so write it only in case there is really a
 // protected section in the document.
-for (auto const& pSectionFormat : m_rDoc.GetSections())
+SwSectionFormats& rSections = m_rDoc.GetSections();
+for (auto const& pSectionFormat : rSections)
 {
 if (!pSectionFormat->IsInUndo() && 

core.git: sw/qa sw/source

2024-06-05 Thread Miklos Vajna (via logerrit)
 sw/qa/writerfilter/rtftok/data/endnote-at-section-end.rtf |   15 +
 sw/qa/writerfilter/rtftok/rtfdispatchflag.cxx |   23 ++
 sw/source/writerfilter/rtftok/rtfdispatchflag.cxx |7 +++-
 3 files changed, 44 insertions(+), 1 deletion(-)

New commits:
commit ad8fa1b5912a04f4cc016965175315e4784fa229
Author: Miklos Vajna 
AuthorDate: Wed Jun 5 09:34:14 2024 +0200
Commit: Miklos Vajna 
CommitDate: Wed Jun 5 10:38:18 2024 +0200

tdf#161417 RTF import: handle endnotes at section ends

This is similar to commit 2d2dd56e0b2dc708f1f758d7fc9a1263ff09b83c
(tdf#160984 sw continuous endnotes: DOCX: import  pos ==
sectEnd, 2024-05-28), but that was for DOCX import, this is for RTF
import.

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

diff --git a/sw/qa/writerfilter/rtftok/data/endnote-at-section-end.rtf 
b/sw/qa/writerfilter/rtftok/data/endnote-at-section-end.rtf
new file mode 100644
index ..945bd42c24c9
--- /dev/null
+++ b/sw/qa/writerfilter/rtftok/data/endnote-at-section-end.rtf
@@ -0,0 +1,15 @@
+{ tf1
+\paperw11906\paperh16838\margl1134\margr1134\margt1134\margb1134
+endnoteset1
+\pard\plain
+First
+\sect\sectd\sbknonendnhere
+second
++{ootnotetnalt\pard\plain
++}
+\sect\sectd\sbknonendnhere\pard\plain
+third
+\par
+}
diff --git a/sw/qa/writerfilter/rtftok/rtfdispatchflag.cxx 
b/sw/qa/writerfilter/rtftok/rtfdispatchflag.cxx
index 8c660435a3a6..62fb089e29d3 100644
--- a/sw/qa/writerfilter/rtftok/rtfdispatchflag.cxx
+++ b/sw/qa/writerfilter/rtftok/rtfdispatchflag.cxx
@@ -13,6 +13,7 @@
 #include 
 #include 
 #include 
+#include 
 
 using namespace ::com::sun::star;
 
@@ -100,6 +101,28 @@ CPPUNIT_TEST_FIXTURE(Test, testTblOverlap)
 // "can overlap".
 CPPUNIT_ASSERT(!bAllowOverlap);
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testEndnoteAtSectionEndRTFImport)
+{
+// Given a document with at-section-end endnotes enabled:
+// When loading that document:
+loadFromFile(u"endnote-at-section-end.rtf");
+
+// Go to the second paragraph, which is inside Word's second section:
+uno::Reference xTextDocument(mxComponent, 
uno::UNO_QUERY);
+uno::Reference 
xParaEnumAccess(xTextDocument->getText(),
+  
uno::UNO_QUERY);
+uno::Reference xParaEnum = 
xParaEnumAccess->createEnumeration();
+xParaEnum->nextElement();
+uno::Reference xPara(xParaEnum->nextElement(), 
uno::UNO_QUERY);
+uno::Reference xSection;
+xPara->getPropertyValue("TextSection") >>= xSection;
+bool bEndnoteIsCollectAtTextEnd = false;
+xSection->getPropertyValue("EndnoteIsCollectAtTextEnd") >>= 
bEndnoteIsCollectAtTextEnd;
+// Without the accompanying fix in place, this test would have failed, 
endnotes were always at
+// document end.
+CPPUNIT_ASSERT(bEndnoteIsCollectAtTextEnd);
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/writerfilter/rtftok/rtfdispatchflag.cxx 
b/sw/source/writerfilter/rtftok/rtfdispatchflag.cxx
index dfc5be5b1e05..acd753fe6eb3 100644
--- a/sw/source/writerfilter/rtftok/rtfdispatchflag.cxx
+++ b/sw/source/writerfilter/rtftok/rtfdispatchflag.cxx
@@ -925,8 +925,13 @@ RTFError RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
 break;
 case RTFKeyword::AENDDOC:
 // Noop, this is the default in Writer.
+break;
 case RTFKeyword::AENDNOTES:
-// Noop
+{
+auto pValue = new RTFValue(NS_ooxml::LN_Value_ST_EdnPos_sectEnd);
+m_aSettingsTableSprms.set(NS_ooxml::LN_CT_EdnProps_pos, pValue);
+}
+break;
 case RTFKeyword::AFTNRSTCONT:
 // Noop, this is the default in Writer.
 case RTFKeyword::AFTNRESTART:


core.git: bin/diff-pdf-page.py

2024-06-04 Thread Miklos Vajna (via logerrit)
 bin/diff-pdf-page.py |   42 ++
 1 file changed, 42 insertions(+)

New commits:
commit e42b7ab0c796f5b2a985cdac56b1c342c5501984
Author: Miklos Vajna 
AuthorDate: Tue Jun 4 16:14:15 2024 +0200
Commit: Miklos Vajna 
CommitDate: Tue Jun 4 17:27:40 2024 +0200

bin: add a diff-pdf-page.py script to diff reference vs our rendering via 
PDF

Thanks László Németh for the idea, the mechanism used in the tool was
also used to generate the visual diff visible at

.

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

diff --git a/bin/diff-pdf-page.py b/bin/diff-pdf-page.py
new file mode 100755
index ..153654d5d386
--- /dev/null
+++ b/bin/diff-pdf-page.py
@@ -0,0 +1,42 @@
+#!/usr/bin/env python3
+#
+# 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/.
+#
+# Diffs two PDF pages: a reference and our own output. Red output means some 
to fix: the amount of
+# red is meant to reduce as fixing progresses. Sample usage:
+#
+# bin/diff-pdf-page.py reference.pdf test.pdf diff.png
+
+import argparse
+import tempfile
+import subprocess
+
+def run(argv):
+print(" ".join(argv))
+subprocess.run(argv, check=True)
+
+def main():
+parser = argparse.ArgumentParser(description="Diffs two PDF pages, first 
is painted red instead of black, the second is painted on top of the first.")
+parser.add_argument("-d", "--density", default="384")
+parser.add_argument("-p", "--page", default="0")
+parser.add_argument("a_pdf")
+parser.add_argument("b_pdf")
+parser.add_argument("diff_png")
+args = parser.parse_args()
+
+a_png = tempfile.NamedTemporaryFile(suffix=".png")
+a_pdf = args.a_pdf + "[" + args.page + "]"
+run(["convert", "-density", args.density, a_pdf, "-colorspace", "RGB", 
"-fuzz", "95%", "-fill", "red", "-opaque", "black", a_png.name])
+b_png = tempfile.NamedTemporaryFile(suffix=".png")
+b_pdf = args.b_pdf + "[" + args.page + "]"
+run(["convert", "-density", args.density, b_pdf, "-colorspace", "RGB", 
b_png.name])
+composite_png = tempfile.NamedTemporaryFile(suffix=".png")
+run(["convert", "-composite", a_png.name, b_png.name, composite_png.name])
+run(["convert", composite_png.name, "-background", "white", "-flatten", 
args.diff_png])
+
+if __name__ == "__main__":
+main()
+
+# vim:set shiftwidth=4 softtabstop=4 expandtab:


core.git: Branch 'distro/collabora/co-24.04' - sw/source sw/uiconfig

2024-06-04 Thread Miklos Vajna (via logerrit)
 sw/source/ui/misc/pgfnote.cxx  |   29 +
 sw/source/uibase/inc/pgfnote.hxx   |4 
 sw/source/uibase/utlui/uitool.cxx  |7 +++
 sw/uiconfig/swriter/ui/footnoteareapage.ui |8 
 4 files changed, 44 insertions(+), 4 deletions(-)

New commits:
commit c080c2598537a7283849d344b61c1032e5cc7979
Author: Miklos Vajna 
AuthorDate: Fri May 31 16:11:42 2024 +0200
Commit: Miklos Vajna 
CommitDate: Tue Jun 4 14:53:29 2024 +0200

tdf#160984 sw continuous endnotes: hide not functional UI in this mode

Previous commits bug have fixed cases where opening a Word document
rendered a different foot/endnote separator than expected for Word. The
followings were modified:

- distance between body text and separator, between separator and first
  note

- the vertical position of the line

- the length of the line

Now ODT files keep the original feature set and Word files look as
expected, but a couple of UI controls are ignored by the layout, hide
these as they intentionally don't do anything while we're in Word compat
mode.

(cherry picked from commit 8f3e11dc9a4b3fd9ad1985d88b241df7bcb66fec)

Change-Id: I72a3dde637d3e224038886a79550fa069253a4f9
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168375
Tested-by: Jenkins CollaboraOffice 
Reviewed-by: Caolán McNamara 
Reviewed-by: Miklos Vajna 

diff --git a/sw/source/ui/misc/pgfnote.cxx b/sw/source/ui/misc/pgfnote.cxx
index 14eec4b21be1..8da1597882d7 100644
--- a/sw/source/ui/misc/pgfnote.cxx
+++ b/sw/source/ui/misc/pgfnote.cxx
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -99,13 +100,17 @@ SwFootNotePage::SwFootNotePage(weld::Container* pPage, 
weld::DialogController* p
 , m_xMaxHeightPageBtn(m_xBuilder->weld_radio_button("maxheightpage"))
 , m_xMaxHeightBtn(m_xBuilder->weld_radio_button("maxheight"))
 , m_xMaxHeightEdit(m_xBuilder->weld_metric_spin_button("maxheightsb", 
FieldUnit::CM))
+, m_xDistLabel(m_xBuilder->weld_label("spacetotextlabel"))
 , m_xDistEdit(m_xBuilder->weld_metric_spin_button("spacetotext", 
FieldUnit::CM))
+, m_xLinePosLabel(m_xBuilder->weld_label("positionlabel"))
 , m_xLinePosBox(m_xBuilder->weld_combo_box("position"))
 , m_xLineTypeBox(new SvtLineListBox(m_xBuilder->weld_menu_button("style")))
 , m_xLineWidthEdit(m_xBuilder->weld_metric_spin_button("thickness", 
FieldUnit::POINT))
 , m_xLineColorBox(new ColorListBox(m_xBuilder->weld_menu_button("color"),
 [this]{ return GetDialogController()->getDialog(); }))
+, m_xLineLengthLabel(m_xBuilder->weld_label("lengthlabel"))
 , m_xLineLengthEdit(m_xBuilder->weld_metric_spin_button("length", 
FieldUnit::PERCENT))
+, m_xLineDistLabel(m_xBuilder->weld_label("spacingtocontentslabel"))
 , m_xLineDistEdit(m_xBuilder->weld_metric_spin_button("spacingtocontents", 
FieldUnit::CM))
 {
 SetExchangeSupport();
@@ -116,6 +121,30 @@ SwFootNotePage::SwFootNotePage(weld::Container* pPage, 
weld::DialogController* p
 MeasurementSystem eSys = 
SvtSysLocale().GetLocaleData().getMeasurementSystemEnum();
 tools::Long nHeightValue = MeasurementSystem::Metric != eSys ? 1440 : 1134;
 
m_xMaxHeightEdit->set_value(m_xMaxHeightEdit->normalize(nHeightValue),FieldUnit::TWIP);
+
+bool bContinuousEndnotes = false;
+if (const SfxGrabBagItem* pGragbagItem = 
rSet.GetItemIfSet(SID_ATTR_CHAR_GRABBAG))
+{
+auto it = pGragbagItem->GetGrabBag().find("ContinuousEndnotes");
+if (it != pGragbagItem->GetGrabBag().end())
+{
+it->second >>= bContinuousEndnotes;
+}
+}
+
+if (bContinuousEndnotes)
+{
+// These are ignored in SwFootnoteContFrame::Format() and 
SwFootnoteContFrame::PaintLine(),
+// hide them.
+m_xDistLabel->set_visible(false);
+m_xDistEdit->set_visible(false);
+m_xLinePosLabel->set_visible(false);
+m_xLinePosBox->set_visible(false);
+m_xLineLengthLabel->set_visible(false);
+m_xLineLengthEdit->set_visible(false);
+m_xLineDistLabel->set_visible(false);
+m_xLineDistEdit->set_visible(false);
+}
 }
 
 SwFootNotePage::~SwFootNotePage()
diff --git a/sw/source/uibase/inc/pgfnote.hxx b/sw/source/uibase/inc/pgfnote.hxx
index c239f1ed292f..0abb09a80a9d 100644
--- a/sw/source/uibase/inc/pgfnote.hxx
+++ b/sw/source/uibase/inc/pgfnote.hxx
@@ -44,12 +44,16 @@ private:
 std::unique_ptr m_xMaxHeightPageBtn;
 std::unique_ptr m_xMaxHeightBtn;
 std::unique_ptr m_xMaxHeightEdit;
+std::unique_ptr m_xDistLabel;
 std::unique_ptr m_xDistEdit;
+std::unique_ptr m_xLinePosLabel;
 std::unique_ptr m_xLinePosBox;
 std::unique_ptr m_xLineTypeBox;
 std::unique_ptr m_xLineWidthEdit;
 std::unique_ptr m_xLineColorBox;
+std::unique_ptr m_xLineLengthLabel;
 

core.git: sw/qa sw/source

2024-06-04 Thread Miklos Vajna (via logerrit)
 sw/qa/extras/ww8export/ww8export4.cxx |   31 +++
 sw/source/filter/ww8/wrtww8.cxx   |   13 +
 2 files changed, 44 insertions(+)

New commits:
commit 24ab535087991f1ce8dee9a561476bc0a987bac5
Author: Miklos Vajna 
AuthorDate: Tue Jun 4 13:43:23 2024 +0200
Commit: Miklos Vajna 
CommitDate: Tue Jun 4 14:46:53 2024 +0200

tdf#161417 DOC export: handle endnotes at section ends

Similar to commit 566c7017a84e3d573de85a6d986b81d3f59de0fa (tdf#160984
sw continuous endnotes: DOCX: export of  pos == sectEnd,
2024-05-29), but this is for DOC, not DOCX.

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

diff --git a/sw/qa/extras/ww8export/ww8export4.cxx 
b/sw/qa/extras/ww8export/ww8export4.cxx
index b52e2b8f77f1..187e18267463 100644
--- a/sw/qa/extras/ww8export/ww8export4.cxx
+++ b/sw/qa/extras/ww8export/ww8export4.cxx
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 
 namespace
 {
@@ -122,6 +123,36 @@ DECLARE_WW8EXPORT_TEST(testTdf141649_conditionalText, 
"tdf141649_conditionalText
 getParagraph(1, "trueResult");
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testEndnotesAtSectEndDOC)
+{
+// Given a document, endnotes at collected at section end:
+createSwDoc();
+{
+SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
+pWrtShell->SplitNode();
+pWrtShell->Up(/*bSelect=*/false);
+pWrtShell->Insert("x");
+pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, 
/*bBasicCall=*/false);
+SwSectionData aSection(SectionType::Content, 
pWrtShell->GetUniqueSectionName());
+pWrtShell->StartAction();
+SfxItemSetFixed 
aSet(pWrtShell->GetAttrPool());
+aSet.Put(SwFormatEndAtTextEnd(FTNEND_ATTXTEND));
+pWrtShell->InsertSection(aSection, );
+pWrtShell->EndAction();
+pWrtShell->InsertFootnote(OUString(), /*bEndNote=*/true);
+}
+
+// When saving to DOC:
+saveAndReload("MS Word 97");
+
+// Then make sure the endnote position is section end:
+SwDoc* pDoc = getSwDoc();
+SwSectionFormats& rSections = pDoc->GetSections();
+SwSectionFormat* pFormat = rSections[0];
+// Without the accompanying fix in place, this test would have failed, 
endnotes were at doc end.
+CPPUNIT_ASSERT(pFormat->GetEndAtTextEnd().IsAtEnd());
+}
+
 DECLARE_WW8EXPORT_TEST(testTdf90408, "tdf90408.doc")
 {
 uno::Reference xRun(getRun(getParagraph(1), 1), 
uno::UNO_QUERY_THROW);
diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx
index a14412469cf8..467a7c18949a 100644
--- a/sw/source/filter/ww8/wrtww8.cxx
+++ b/sw/source/filter/ww8/wrtww8.cxx
@@ -87,6 +87,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "sprmids.hxx"
 
 #include 
@@ -493,6 +494,18 @@ static void WriteDop( WW8Export& rWrt )
 rDop.cParas = rDStat.nPara;
 rDop.cLines = rDStat.nPara;
 
+SwSectionFormats& rSections = rWrt.m_rDoc.GetSections();
+if (!rSections.empty())
+{
+SwSectionFormat* pFormat = rSections[0];
+bool bEndnAtEnd = pFormat->GetEndAtTextEnd().IsAtEnd();
+if (bEndnAtEnd)
+{
+// DopBase.epc: this is normally 3 (end of document), change this 
to end of section.
+rDop.epc = 0;
+}
+}
+
 SwDocShell *pDocShell(rWrt.m_rDoc.GetDocShell());
 OSL_ENSURE(pDocShell, "no SwDocShell");
 uno::Reference xDocProps;


core.git: svtools/source

2024-06-04 Thread Miklos Vajna (via logerrit)
 svtools/source/brwbox/brwbox1.cxx |5 -
 1 file changed, 5 deletions(-)

New commits:
commit 31490e9bd93bfd622ddda79e927114b3fafba6c1
Author: Miklos Vajna 
AuthorDate: Tue Jun 4 11:11:33 2024 +0200
Commit: Miklos Vajna 
CommitDate: Tue Jun 4 12:24:46 2024 +0200

Revert "svtools: fix crash in BrowseBox::GetControlArea()"

This reverts commit ec5aa7e88b0d412041f8575111f0da295065cecb (svtools:
fix crash in BrowseBox::GetControlArea(), 2024-06-04), not needed after
commit 6f2b5043613bea755f01b413fd86ece0b3a29e5d (crashtesting:
BrowseBox::GetControlArea crash, 2024-06-03).

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

diff --git a/svtools/source/brwbox/brwbox1.cxx 
b/svtools/source/brwbox/brwbox1.cxx
index 0457d768ec98..982e00cfd388 100644
--- a/svtools/source/brwbox/brwbox1.cxx
+++ b/svtools/source/brwbox/brwbox1.cxx
@@ -2134,11 +2134,6 @@ bool BrowseBox::ReserveControlArea(sal_uInt16 nWidth)
 
 tools::Rectangle BrowseBox::GetControlArea() const
 {
-if (!aHScroll)
-{
-return tools::Rectangle();
-}
-
 auto nHeight = aHScroll->GetSizePixel().Height();
 auto nEndRight = aHScroll->GetPosPixel().X();
 


core.git: Branch 'distro/collabora/co-24.04' - sw/qa sw/source

2024-06-04 Thread Miklos Vajna (via logerrit)
 sw/qa/core/layout/data/endnote-cont-separator.docx |binary
 sw/qa/core/layout/paintfrm.cxx |   27 +
 sw/source/core/inc/ftnfrm.hxx  |1 
 sw/source/core/layout/findfrm.cxx  |   11 
 sw/source/core/layout/paintfrm.cxx |   16 ++--
 5 files changed, 52 insertions(+), 3 deletions(-)

New commits:
commit 3939d516fd27759e779d72f70ceef1e8bb23fa00
Author: Miklos Vajna 
AuthorDate: Thu May 30 15:23:45 2024 +0200
Commit: Caolán McNamara 
CommitDate: Tue Jun 4 10:55:21 2024 +0200

tdf#160984 sw continuous endnotes: fix the endnote continuation separator 
len

See e.g.
,
one remaining difference for the Word vs Writer note separator is the
length of the endnote continuation separator: it's body frame width in
Word, shorter in Writer.

Seems this is specific to the endnote continuation separator, i.e.
normal endnote separator, footnote separator and footnote continuation
separator is not affected. Additionally, it's really footnote vs
endnote: if you put footnotes to the end of the document in Word, it
still doesn't make the separator longer.

Fix the problem by extending SwFootnoteContFrame::PaintLine() to handle
this: if in Word compat mode, first note frame is a follow endnote
frame, then paint the longer separator.

The usual render test way via SfxObjectShell::GetPreviewMetaFile() only
works with 1st pages and we want to assert the 2nd page here, so go via
DocumentToGraphicRenderer, similar to how
EPUBExportFilter::CreateMetafiles() does it.

(cherry picked from commit 6450159e0e7c5fac9c998087e99f3fec602ff84d)

Change-Id: Ia0ba1138070f1a68f62ea6f5a6a85fbe0f76d482
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168374
Tested-by: Jenkins CollaboraOffice 
Reviewed-by: Caolán McNamara 

diff --git a/sw/qa/core/layout/data/endnote-cont-separator.docx 
b/sw/qa/core/layout/data/endnote-cont-separator.docx
new file mode 100644
index ..2e01a5c91354
Binary files /dev/null and b/sw/qa/core/layout/data/endnote-cont-separator.docx 
differ
diff --git a/sw/qa/core/layout/paintfrm.cxx b/sw/qa/core/layout/paintfrm.cxx
index a5213c57d639..464979c988a6 100644
--- a/sw/qa/core/layout/paintfrm.cxx
+++ b/sw/qa/core/layout/paintfrm.cxx
@@ -10,6 +10,7 @@
 #include 
 
 #include 
+#include 
 
 #include 
 #include 
@@ -188,6 +189,32 @@ CPPUNIT_TEST_FIXTURE(Test, 
testInlineEndnoteSeparatorPosition)
 // i.e. the separator wasn't 2 inches long, but was shorter vs Word.
 CPPUNIT_ASSERT_EQUAL(static_cast(2880), 
nEndnoteSeparatorLength);
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testEndnoteContSeparator)
+{
+// Given a document with a Word-style endnote continuation separator:
+createSwDoc("endnote-cont-separator.docx");
+
+// When rendering page 2:
+sal_Int32 nPage = 2;
+DocumentToGraphicRenderer aRenderer(mxComponent, /*bSelectionOnly=*/false);
+Size aSize = aRenderer.getDocumentSizeInPixels(nPage);
+Graphic aGraphic = aRenderer.renderToGraphic(nPage, aSize, aSize, 
COL_WHITE,
+ /*bExtOutDevData=*/false);
+auto& xMetaFile = const_cast(aGraphic.GetGDIMetaFile());
+
+// Then make sure the separator length is correct:
+MetafileXmlDump aDumper;
+xmlDocUniquePtr pXmlDoc = dumpAndParse(aDumper, xMetaFile);
+auto nEndnoteSeparatorStart = getXPath(pXmlDoc, "//polygon/point[1]"_ostr, 
"x"_ostr).toInt32();
+auto nEndnoteSeparatorEnd = getXPath(pXmlDoc, "//polygon/point[2]"_ostr, 
"x"_ostr).toInt32();
+sal_Int32 nEndnoteSeparatorLength = nEndnoteSeparatorEnd - 
nEndnoteSeparatorStart;
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected: 9360 (page print area width)
+// - Actual  : 2880 (2 inches)
+// i.e. the separator was too short vs Word.
+CPPUNIT_ASSERT_EQUAL(static_cast(9360), 
nEndnoteSeparatorLength);
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/inc/ftnfrm.hxx b/sw/source/core/inc/ftnfrm.hxx
index 558c4941bf06..7331ef07d100 100644
--- a/sw/source/core/inc/ftnfrm.hxx
+++ b/sw/source/core/inc/ftnfrm.hxx
@@ -51,6 +51,7 @@ public:
 SwFootnoteContFrame( SwFrameFormat*, SwFrame* );
 
 const SwFootnoteFrame* FindFootNote() const;
+const SwFootnoteFrame* FindEndNote() const;
 
 static inline SwFootnoteFrame* AppendChained(SwFrame* pThis, bool 
bDefaultFormat);
 static inline SwFootnoteFrame* PrependChained(SwFrame* pThis, bool 
bDefaultFormat);
diff --git a/sw/source/core/layout/findfrm.cxx 
b/sw/source/core/layout/findfrm.cxx
index 4efa25e553e6..fc0293381168 100644
--- a/sw/source/core/layout/findfrm.cxx
+++ b/sw/source/core/layout/findfrm.cxx
@@ -679,6 +679,17 @@ const SwFootnoteFrame* 

core.git: svtools/source

2024-06-04 Thread Miklos Vajna (via logerrit)
 svtools/source/brwbox/brwbox1.cxx |5 +
 1 file changed, 5 insertions(+)

New commits:
commit ec5aa7e88b0d412041f8575111f0da295065cecb
Author: Miklos Vajna 
AuthorDate: Tue Jun 4 08:54:29 2024 +0200
Commit: Miklos Vajna 
CommitDate: Tue Jun 4 09:58:09 2024 +0200

svtools: fix crash in BrowseBox::GetControlArea()

UITest_writer_tests4 sometimes (but not always) crashes for me,
typically not when it's execute alone, but when it's executed as part of
'make check'. The soffice process crashes on shutdown, after all tests
passed without problems.

coredumpctl gives this in gdb:

Program terminated with signal SIGSEGV, Segmentation fault.
#0  BrowseBox::GetControlArea (this=0x9bd3f90) at 
svtools/source/brwbox/brwbox1.cxx:2137
2137auto nHeight = aHScroll->GetSizePixel().Height();
(gdb) print aHScroll
$1 = {m_rInnerRef = empty rtl::Reference}
(gdb) bt
#0  BrowseBox::GetControlArea() const (this=0x9bd3f90) at 
svtools/source/brwbox/brwbox1.cxx:2137
#1  0x7fbbd2022ed9 in DbGridControl::RearrangeHdl(Timer*) 
(this=0x9bd3f90) at svx/source/fmcomp/gridctrl.cxx:2646
#2  0x7fbbd2022ea3 in 
DbGridControl::LinkStubRearrangeHdl(void*, Timer*) (instance=0x9bd3f90, 
data=0x9bd4468) at svx/source/fmcomp/gridctrl.cxx:2643
#3  0x7fbbcedb8d79 in Link::Call(Timer*) const 
(this=0x9bd4488, data=0x9bd4468) at include/tools/link.hxx:111
#4  0x7fbbcedb8c01 in Timer::Invoke() (this=0x9bd4468) at 
vcl/source/app/timer.cxx:75

Let's assume the problem is that somehow we can get here after the
VclPtr is already disposed and just return early to avoid the crash.

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

diff --git a/svtools/source/brwbox/brwbox1.cxx 
b/svtools/source/brwbox/brwbox1.cxx
index 982e00cfd388..0457d768ec98 100644
--- a/svtools/source/brwbox/brwbox1.cxx
+++ b/svtools/source/brwbox/brwbox1.cxx
@@ -2134,6 +2134,11 @@ bool BrowseBox::ReserveControlArea(sal_uInt16 nWidth)
 
 tools::Rectangle BrowseBox::GetControlArea() const
 {
+if (!aHScroll)
+{
+return tools::Rectangle();
+}
+
 auto nHeight = aHScroll->GetSizePixel().Height();
 auto nEndRight = aHScroll->GetPosPixel().X();
 


core.git: Branch 'distro/collabora/co-23.05' - writerfilter/qa writerfilter/source

2024-06-04 Thread Miklos Vajna (via logerrit)
 writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx |   23 
++
 writerfilter/qa/cppunittests/dmapper/data/clearing-break-sect-end.docx |binary
 writerfilter/source/dmapper/DomainMapper.cxx   |4 -
 writerfilter/source/dmapper/DomainMapper_Impl.cxx  |5 
++
 writerfilter/source/dmapper/DomainMapper_Impl.hxx  |3 +
 5 files changed, 33 insertions(+), 2 deletions(-)

New commits:
commit ece1abdda6bc40e9911e07db66cecfc02e0c76df
Author: Miklos Vajna 
AuthorDate: Fri May 31 09:00:18 2024 +0200
Commit: Miklos Vajna 
CommitDate: Tue Jun 4 09:38:46 2024 +0200

tdf#161318 sw clearing break: fix this at section end

Regression from commit 19bca24486315cc35f873486e6a2dd18394d0614
(tdf#126287: docx import: use defered linebreak, 2022-02-07), the bugdoc
has a single paragraph in the first section, containing a clearing
break, which is lost. This leads to overlapping text as the text is
shifted up.

Seems the intention was to avoid a line break at the very end of the
document, as that can lead to an empty page with "next page" section
breaks, with non-clearing line breaks.

Fix the problem by only doing this for non-clearing line breaks: that
keeps the old use-case working, but the new, clearing line break then
shifts down the text, so no text overlap happens.

Switching from appendTextPortion() to HandleLineBreak() helps because
HandleLineBreak() does exactly appendTextPortion("
") in the
non-clearing case, but knows about the stream stack's line break clear
status.

(cherry picked from commit e00479404af5058b982c447e485af995d552e372)

Conflicts:

writerfilter/qa/cppunittests/dmapper/data/clearing-break-sect-end.docx
writerfilter/source/dmapper/DomainMapper.cxx

Change-Id: I38868eeeac55e20e86b668e9baf7e0d6a4976608
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168361
Reviewed-by: Caolán McNamara 
Tested-by: Jenkins CollaboraOffice 
(cherry picked from commit f1338ba7de2ab1abf98283f977605a9d1053b82d)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168385
Reviewed-by: Miklos Vajna 

diff --git a/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx
index dc99e6ae2168..c299294d92cd 100644
--- a/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx
@@ -411,6 +411,29 @@ CPPUNIT_TEST_FIXTURE(Test, testRedlinedShapeThenSdt)
 CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"),
  
xPortion->getPropertyValue("TextPortionType").get());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testClearingBreakSectEnd)
+{
+// Given a file with a single-paragraph section, ends with a clearing 
break:
+// When importing that document:
+loadFromURL(u"clearing-break-sect-end.docx");
+
+// Then make sure the clearing break is not lost before a cont sect break:
+uno::Reference xTextDocument(mxComponent, 
uno::UNO_QUERY);
+uno::Reference 
xParaEnumAccess(xTextDocument->getText(),
+  
uno::UNO_QUERY);
+uno::Reference xParaEnum = 
xParaEnumAccess->createEnumeration();
+uno::Reference 
xPortionEnumAccess(xParaEnum->nextElement(),
+ 
uno::UNO_QUERY);
+uno::Reference xPortionEnum = 
xPortionEnumAccess->createEnumeration();
+uno::Reference xPortion(xPortionEnum->nextElement(), 
uno::UNO_QUERY);
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected: LineBreak
+// - Actual  : Text
+// i.e. the clearing break at sect end was lost, leading to text overlap.
+CPPUNIT_ASSERT_EQUAL(OUString("LineBreak"),
+ 
xPortion->getPropertyValue("TextPortionType").get());
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git 
a/writerfilter/qa/cppunittests/dmapper/data/clearing-break-sect-end.docx 
b/writerfilter/qa/cppunittests/dmapper/data/clearing-break-sect-end.docx
new file mode 100644
index ..5052b2dd1649
Binary files /dev/null and 
b/writerfilter/qa/cppunittests/dmapper/data/clearing-break-sect-end.docx differ
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx 
b/writerfilter/source/dmapper/DomainMapper.cxx
index f75e765ba07c..24c626fb83de 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -4165,13 +4165,13 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, 
size_t len)
 else if (len == 1 && sText[0] == ' ')
 {
 // Clear "last" one linebreak at end of section
-if (m_pImpl->GetIsLastParagraphInSection() && 
m_pImpl->isBreakDeferred(LINE_BREAK))
+if 

core.git: Branch 'distro/collabora/libreoffice-7-5+backports' - sw/CppunitTest_sw_core_layout.mk sw/qa sw/source

2024-06-04 Thread Miklos Vajna (via logerrit)
 sw/CppunitTest_sw_core_layout.mk  |1 
 sw/qa/core/layout/data/table-print-area-left.docx |binary
 sw/qa/core/layout/tabfrm.cxx  |   38 ++
 sw/source/core/layout/tabfrm.cxx  |7 ++--
 4 files changed, 44 insertions(+), 2 deletions(-)

New commits:
commit 3b92f905115cd789a4dafb4e2ee8ee6043693ea8
Author: Miklos Vajna 
AuthorDate: Wed May 10 23:28:03 2023 +0100
Commit: Mike Kaganski 
CommitDate: Mon Jun 3 10:27:47 2024 +0500

tdf#154775 sw layout: fix unexpected large table print area left margin

The bugdoc had 2 pages, but the second page's content was mostly a
table. This table was rendered outside the page frame, so it was
practically invisible.

This started after commit fd7749fddc5a767461dfced55369af48e5a6d561 (sw:
fix handling of table vs fly overlaps in the AddVerticalFlyOffsets case,
2020-02-14), and that behavior is still wanted to have correct table
borders, but that change introduced an inconsistent case: we started to
always accept an invalid frame area definition of the fly, but we only
shifted the content down in the text::HoriOrientation::NONE case.

Fix the problem by limiting the "accept invalid frame area definition"
based on the horizontal orientation, so we either both ignore the
validity flag & shift down or do none of this. This keeps the original
bug fixed, but addresses the new "no visible table" problem.

Note that this only fixes the regression part; once the image from the
header is removed and undo is invoked, a similar problem still happens.
But that is a pre-existing, separate problem.

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

diff --git a/sw/CppunitTest_sw_core_layout.mk b/sw/CppunitTest_sw_core_layout.mk
index 9a7a4710dfb7..1c991f8c19ba 100644
--- a/sw/CppunitTest_sw_core_layout.mk
+++ b/sw/CppunitTest_sw_core_layout.mk
@@ -15,6 +15,7 @@ $(eval $(call 
gb_CppunitTest_use_common_precompiled_header,sw_core_layout))
 
 $(eval $(call gb_CppunitTest_add_exception_objects,sw_core_layout, \
 sw/qa/core/layout/layout \
+sw/qa/core/layout/tabfrm \
 ))
 
 $(eval $(call gb_CppunitTest_use_libraries,sw_core_layout, \
diff --git a/sw/qa/core/layout/data/table-print-area-left.docx 
b/sw/qa/core/layout/data/table-print-area-left.docx
new file mode 100644
index ..e326bed82f39
Binary files /dev/null and b/sw/qa/core/layout/data/table-print-area-left.docx 
differ
diff --git a/sw/qa/core/layout/tabfrm.cxx b/sw/qa/core/layout/tabfrm.cxx
new file mode 100644
index ..4b991c27dbf8
--- /dev/null
+++ b/sw/qa/core/layout/tabfrm.cxx
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-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/.
+ */
+
+#include 
+
+/// Covers sw/source/core/layout/tabfrm.cxx fixes.
+class Test : public SwModelTestBase
+{
+public:
+Test()
+: SwModelTestBase("/sw/qa/core/layout/data/")
+{
+}
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testTablePrintAreaLeft)
+{
+// Given a document with a header containing an image, and also with an 
overlapping table:
+createSwDoc("table-print-area-left.docx");
+
+// When laying out that document & parsing the left margin of the table:
+SwTwips nTablePrintLeft = parseDump("//tab/infos/prtBounds", 
"left").toInt32();
+
+// Then make sure it has ~no left margin:
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected: 5
+// - Actual  : 10646
+// i.e. the table was shifted outside the page, was invisible.
+CPPUNIT_ASSERT_EQUAL(static_cast(5), nTablePrintLeft);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index d2e4618bf317..abf9fa1bb4f0 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -2860,10 +2860,14 @@ bool SwTabFrame::CalcFlyOffsets( SwTwips& rUpper,
 //   at the page frame, the table is on, but it's anchor 
character
 //   text frame has already changed its page.
 const SwTextFrame* pAnchorCharFrame = 
pFly->FindAnchorCharFrame();
+const SwFormatHoriOrient& rHori = 
pFly->GetFormat()->GetHoriOrient();
+// Only consider invalid Writer fly frames if they'll be 
shifted down.
+bool bIgnoreFlyValidity
+= bAddVerticalFlyOffsets && rHori.GetHoriOrient() == 
text::HoriOrientation::NONE;
 bool bConsiderFly =
 

core.git: officecfg/registry sw/inc sw/source

2024-06-03 Thread Miklos Vajna (via logerrit)
 officecfg/registry/schema/org/openoffice/Office/Compatibility.xcs |6 
 sw/inc/strings.hrc|3 +-
 sw/inc/viewsh.hxx |2 +
 sw/source/core/doc/DocumentSettingManager.cxx |1 
 sw/source/core/view/viewsh.cxx|   14 
++
 sw/source/ui/config/optcomp.cxx   |6 
 6 files changed, 31 insertions(+), 1 deletion(-)

New commits:
commit b79b50c8f06a5c977451995b2d632e5738d7d335
Author: Miklos Vajna 
AuthorDate: Mon Jun 3 17:01:20 2024 +0200
Commit: Miklos Vajna 
CommitDate: Mon Jun 3 18:34:02 2024 +0200

tdf#160984 sw continuous endnotes: add enable/disable option UI

Doing this via a macro was possible already, but that didn't invalidate
the endnote positions on the layout, so required a document reload,
which was ugly.

Implement the new SwViewShell::SetContinuousEndnotes() by removing the
endnote frames in the document, so they'll be re-created at the expected
place as the layout action ends.

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

diff --git a/officecfg/registry/schema/org/openoffice/Office/Compatibility.xcs 
b/officecfg/registry/schema/org/openoffice/Office/Compatibility.xcs
index 9bc722106070..c1fc01658ad3 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Compatibility.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Compatibility.xcs
@@ -158,6 +158,12 @@
 
 false
   
+  
+
+  Render endnotes at the end of the document inline, rather than 
on a separate page
+
+false
+  
 
   
   
diff --git a/sw/inc/strings.hrc b/sw/inc/strings.hrc
index 6a36f4740926..298b861eecf6 100644
--- a/sw/inc/strings.hrc
+++ b/sw/inc/strings.hrc
@@ -1492,7 +1492,8 @@
 #define STR_COMPAT_OPT_NOGAPAFTERNOTENUMBER 
NC_("STR_COMPAT_OPT_NOGAPAFTERNOTENUMBER", "Do not add an extra space after 
number in footnotes / endnotes with hanging first line")
 #define STR_COMPAT_OPT_TABSRELATIVETOINDENT 
NC_("STR_COMPAT_OPT_TABSRELATIVETOINDENT", "Set tabstops relative to indent of 
paragraph")
 #define STR_COMPAT_OPT_TABOVERMARGIN
NC_("STR_COMPAT_OPT_TABOVERMARGIN", "Allow tabs to extend beyond the right 
margin")
-#define STR_COMPAT_OPT_DO_NOT_MIRROR_RTL_DRAW_OBJS 
NC_("DO_NOT_MIRROR_RTL_DRAW_OBJS", "Do not mirror drawing objects anchored in 
paragraphs with an RTL writing direction")
+#define STR_COMPAT_OPT_DO_NOT_MIRROR_RTL_DRAW_OBJS 
NC_("STR_COMPAT_OPT_DO_NOT_MIRROR_RTL_DRAW_OBJS", "Do not mirror drawing 
objects anchored in paragraphs with an RTL writing direction")
+#define STR_COMPAT_OPT_CONTINUOUS_ENDNOTES 
NC_("STR_COMPAT_OPT_CONTINUOUS_ENDNOTES", "Render endnotes at the end of 
document inline, rather than on a separate page")
 
 #define STR_TABLE_PANEL_ALIGN_AUTO  
NC_("sidebartableedit|alignautolabel", "Automatic")
 #define STR_TABLE_PANEL_ALIGN_LEFT  
NC_("sidebartableedit|alignleftlabel", "Left")
diff --git a/sw/inc/viewsh.hxx b/sw/inc/viewsh.hxx
index 18d33266b627..b53a3ed7b719 100644
--- a/sw/inc/viewsh.hxx
+++ b/sw/inc/viewsh.hxx
@@ -453,6 +453,8 @@ public:
 
 SW_DLLPUBLIC void SetDoNotMirrorRtlDrawObjs(bool bDoNotMirrorRtlDrawObjs);
 
+SW_DLLPUBLIC void SetContinuousEndnotes(bool bContinuousEndnotes);
+
 // DOCUMENT COMPATIBILITY FLAGS END
 
 // Calls Idle-formatter of Layout.
diff --git a/sw/source/core/doc/DocumentSettingManager.cxx 
b/sw/source/core/doc/DocumentSettingManager.cxx
index 0a02eb5cb72f..52d609be2e78 100644
--- a/sw/source/core/doc/DocumentSettingManager.cxx
+++ b/sw/source/core/doc/DocumentSettingManager.cxx
@@ -141,6 +141,7 @@ sw::DocumentSettingManager::DocumentSettingManager(SwDoc 
)
 mbTabRelativeToIndent   = 
aOptions.get(u"TabsRelativeToIndent"_ustr);
 mbTabOverMargin = 
aOptions.get(u"TabOverMargin"_ustr);
 mbDoNotMirrorRtlDrawObjs= 
aOptions.get(u"DoNotMirrorRtlDrawObjs"_ustr);
+mbContinuousEndnotes= 
aOptions.get(u"ContinuousEndnotes"_ustr);
 }
 else
 {
diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx
index ec29a15874c0..c4d9a551807c 100644
--- a/sw/source/core/view/viewsh.cxx
+++ b/sw/source/core/view/viewsh.cxx
@@ -1094,6 +1094,20 @@ void SwViewShell::SetDoNotMirrorRtlDrawObjs(bool 
bDoNotMirrorRtlDrawObjs)
 }
 }
 
+void SwViewShell::SetContinuousEndnotes(bool bContinuousEndnotes)
+{
+IDocumentSettingAccess& rIDSA = getIDocumentSettingAccess();
+if (rIDSA.get(DocumentSettingId::CONTINUOUS_ENDNOTES) != 
bContinuousEndnotes)
+{
+SwWait aWait(*GetDoc()->GetDocShell(), true);
+

core.git: Branch 'distro/collabora/co-24.04' - writerfilter/qa writerfilter/source

2024-06-03 Thread Miklos Vajna (via logerrit)
 writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx |   23 
++
 writerfilter/qa/cppunittests/dmapper/data/clearing-break-sect-end.docx |binary
 writerfilter/source/dmapper/DomainMapper.cxx   |4 -
 writerfilter/source/dmapper/DomainMapper_Impl.cxx  |5 
++
 writerfilter/source/dmapper/DomainMapper_Impl.hxx  |3 +
 5 files changed, 33 insertions(+), 2 deletions(-)

New commits:
commit f1338ba7de2ab1abf98283f977605a9d1053b82d
Author: Miklos Vajna 
AuthorDate: Fri May 31 09:00:18 2024 +0200
Commit: Caolán McNamara 
CommitDate: Mon Jun 3 16:08:02 2024 +0200

tdf#161318 sw clearing break: fix this at section end

Regression from commit 19bca24486315cc35f873486e6a2dd18394d0614
(tdf#126287: docx import: use defered linebreak, 2022-02-07), the bugdoc
has a single paragraph in the first section, containing a clearing
break, which is lost. This leads to overlapping text as the text is
shifted up.

Seems the intention was to avoid a line break at the very end of the
document, as that can lead to an empty page with "next page" section
breaks, with non-clearing line breaks.

Fix the problem by only doing this for non-clearing line breaks: that
keeps the old use-case working, but the new, clearing line break then
shifts down the text, so no text overlap happens.

Switching from appendTextPortion() to HandleLineBreak() helps because
HandleLineBreak() does exactly appendTextPortion("
") in the
non-clearing case, but knows about the stream stack's line break clear
status.

(cherry picked from commit e00479404af5058b982c447e485af995d552e372)

Conflicts:

writerfilter/qa/cppunittests/dmapper/data/clearing-break-sect-end.docx
writerfilter/source/dmapper/DomainMapper.cxx

Change-Id: I38868eeeac55e20e86b668e9baf7e0d6a4976608
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168361
Reviewed-by: Caolán McNamara 
Tested-by: Jenkins CollaboraOffice 

diff --git a/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx
index 16aa5cbfb2df..d2388505d71d 100644
--- a/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx
@@ -411,6 +411,29 @@ CPPUNIT_TEST_FIXTURE(Test, testRedlinedShapeThenSdt)
 CPPUNIT_ASSERT_EQUAL(u"ContentControl"_ustr,
  
xPortion->getPropertyValue("TextPortionType").get());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testClearingBreakSectEnd)
+{
+// Given a file with a single-paragraph section, ends with a clearing 
break:
+// When importing that document:
+loadFromFile(u"clearing-break-sect-end.docx");
+
+// Then make sure the clearing break is not lost before a cont sect break:
+uno::Reference xTextDocument(mxComponent, 
uno::UNO_QUERY);
+uno::Reference 
xParaEnumAccess(xTextDocument->getText(),
+  
uno::UNO_QUERY);
+uno::Reference xParaEnum = 
xParaEnumAccess->createEnumeration();
+uno::Reference 
xPortionEnumAccess(xParaEnum->nextElement(),
+ 
uno::UNO_QUERY);
+uno::Reference xPortionEnum = 
xPortionEnumAccess->createEnumeration();
+uno::Reference xPortion(xPortionEnum->nextElement(), 
uno::UNO_QUERY);
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected: LineBreak
+// - Actual  : Text
+// i.e. the clearing break at sect end was lost, leading to text overlap.
+CPPUNIT_ASSERT_EQUAL(u"LineBreak"_ustr,
+ 
xPortion->getPropertyValue("TextPortionType").get());
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git 
a/writerfilter/qa/cppunittests/dmapper/data/clearing-break-sect-end.docx 
b/writerfilter/qa/cppunittests/dmapper/data/clearing-break-sect-end.docx
new file mode 100644
index ..5052b2dd1649
Binary files /dev/null and 
b/writerfilter/qa/cppunittests/dmapper/data/clearing-break-sect-end.docx differ
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx 
b/writerfilter/source/dmapper/DomainMapper.cxx
index bfca0214a017..d206fa0b140f 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -4354,13 +4354,13 @@ void DomainMapper::lcl_utext(const sal_Unicode *const 
data_, size_t len)
 else if (len == 1 && sText[0] == ' ')
 {
 // Clear "last" one linebreak at end of section
-if (m_pImpl->GetIsLastParagraphInSection() && 
m_pImpl->isBreakDeferred(LINE_BREAK))
+if (m_pImpl->GetIsLastParagraphInSection() && 
m_pImpl->isBreakDeferred(LINE_BREAK) && !m_pImpl->HasLineBreakClear())
 m_pImpl->clearDeferredBreak(LINE_BREAK);
 // And emit 

core.git: include/svx svx/source

2024-06-03 Thread Miklos Vajna (via logerrit)
 include/svx/svdundo.hxx   |6 +++---
 svx/source/svdraw/svdundo.cxx |   28 ++--
 2 files changed, 17 insertions(+), 17 deletions(-)

New commits:
commit 61f5006c18b3194f6aaa03e260425dc878cfff79
Author: Miklos Vajna 
AuthorDate: Mon Jun 3 09:32:38 2024 +0200
Commit: Miklos Vajna 
CommitDate: Mon Jun 3 12:24:08 2024 +0200

svx: prefix members of SdrUndoGeoObj

See tdf#94879 for motivation.

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

diff --git a/include/svx/svdundo.hxx b/include/svx/svdundo.hxx
index e1b778064e6d..bc15932fd81c 100644
--- a/include/svx/svdundo.hxx
+++ b/include/svx/svdundo.hxx
@@ -211,10 +211,10 @@ public:
 
 class SVXCORE_DLLPUBLIC SdrUndoGeoObj : public SdrUndoObj
 {
-std::unique_ptr pUndoGeo;
-std::unique_ptr pRedoGeo;
+std::unique_ptr m_pUndoGeo;
+std::unique_ptr m_pRedoGeo;
 // If we have a group object:
-std::unique_ptr pUndoGroup;
+std::unique_ptr m_pUndoGroup;
 /// If we have a table object, should its layout change?
 bool mbSkipChangeLayout;
 
diff --git a/svx/source/svdraw/svdundo.cxx b/svx/source/svdraw/svdundo.cxx
index c7bb38d81ada..7d98d21b7cb4 100644
--- a/svx/source/svdraw/svdundo.cxx
+++ b/svx/source/svdraw/svdundo.cxx
@@ -564,21 +564,21 @@ SdrUndoGeoObj::SdrUndoGeoObj(SdrObject& rNewObj)
 // this is a group object!
 // If this were 3D scene, we'd only add an Undo for the scene itself
 // (which we do elsewhere).
-pUndoGroup.reset(new SdrUndoGroup(mxObj->getSdrModelFromSdrObject()));
+m_pUndoGroup.reset(new 
SdrUndoGroup(mxObj->getSdrModelFromSdrObject()));
 for (const rtl::Reference& pObj : *pOL)
-pUndoGroup->AddAction(std::make_unique(*pObj));
+m_pUndoGroup->AddAction(std::make_unique(*pObj));
 }
 else
 {
-pUndoGeo = mxObj->GetGeoData();
+m_pUndoGeo = mxObj->GetGeoData();
 }
 }
 
 SdrUndoGeoObj::~SdrUndoGeoObj()
 {
-pUndoGeo.reset();
-pRedoGeo.reset();
-pUndoGroup.reset();
+m_pUndoGeo.reset();
+m_pRedoGeo.reset();
+m_pUndoGroup.reset();
 }
 
 void SdrUndoGeoObj::Undo()
@@ -586,21 +586,21 @@ void SdrUndoGeoObj::Undo()
 // Trigger PageChangeCall
 ImpShowPageOfThisObject();
 
-if(pUndoGroup)
+if(m_pUndoGroup)
 {
-pUndoGroup->Undo();
+m_pUndoGroup->Undo();
 
 // only repaint, no objectchange
 mxObj->ActionChanged();
 }
 else
 {
-pRedoGeo = mxObj->GetGeoData();
+m_pRedoGeo = mxObj->GetGeoData();
 
 auto pTableObj = dynamic_cast(mxObj.get());
 if (pTableObj && mbSkipChangeLayout)
 pTableObj->SetSkipChangeLayout(true);
-mxObj->SetGeoData(*pUndoGeo);
+mxObj->SetGeoData(*m_pUndoGeo);
 if (pTableObj && mbSkipChangeLayout)
 pTableObj->SetSkipChangeLayout(false);
 }
@@ -608,17 +608,17 @@ void SdrUndoGeoObj::Undo()
 
 void SdrUndoGeoObj::Redo()
 {
-if(pUndoGroup)
+if(m_pUndoGroup)
 {
-pUndoGroup->Redo();
+m_pUndoGroup->Redo();
 
 // only repaint, no objectchange
 mxObj->ActionChanged();
 }
 else
 {
-pUndoGeo = mxObj->GetGeoData();
-mxObj->SetGeoData(*pRedoGeo);
+m_pUndoGeo = mxObj->GetGeoData();
+mxObj->SetGeoData(*m_pRedoGeo);
 }
 
 // Trigger PageChangeCall


core.git: sw/source sw/uiconfig

2024-05-31 Thread Miklos Vajna (via logerrit)
 sw/source/ui/misc/pgfnote.cxx  |   29 +
 sw/source/uibase/inc/pgfnote.hxx   |4 
 sw/source/uibase/utlui/uitool.cxx  |7 +++
 sw/uiconfig/swriter/ui/footnoteareapage.ui |8 
 4 files changed, 44 insertions(+), 4 deletions(-)

New commits:
commit 8f3e11dc9a4b3fd9ad1985d88b241df7bcb66fec
Author: Miklos Vajna 
AuthorDate: Fri May 31 16:11:42 2024 +0200
Commit: Miklos Vajna 
CommitDate: Fri May 31 21:59:57 2024 +0200

tdf#160984 sw continuous endnotes: hide not functional UI in this mode

Previous commits bug have fixed cases where opening a Word document
rendered a different foot/endnote separator than expected for Word. The
followings were modified:

- distance between body text and separator, between separator and first
  note

- the vertical position of the line

- the length of the line

Now ODT files keep the original feature set and Word files look as
expected, but a couple of UI controls are ignored by the layout, hide
these as they intentionally don't do anything while we're in Word compat
mode.

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

diff --git a/sw/source/ui/misc/pgfnote.cxx b/sw/source/ui/misc/pgfnote.cxx
index 0316f6251eaa..9ed64e3e3de6 100644
--- a/sw/source/ui/misc/pgfnote.cxx
+++ b/sw/source/ui/misc/pgfnote.cxx
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -99,13 +100,17 @@ SwFootNotePage::SwFootNotePage(weld::Container* pPage, 
weld::DialogController* p
 , m_xMaxHeightPageBtn(m_xBuilder->weld_radio_button("maxheightpage"))
 , m_xMaxHeightBtn(m_xBuilder->weld_radio_button("maxheight"))
 , m_xMaxHeightEdit(m_xBuilder->weld_metric_spin_button("maxheightsb", 
FieldUnit::CM))
+, m_xDistLabel(m_xBuilder->weld_label("spacetotextlabel"))
 , m_xDistEdit(m_xBuilder->weld_metric_spin_button("spacetotext", 
FieldUnit::CM))
+, m_xLinePosLabel(m_xBuilder->weld_label("positionlabel"))
 , m_xLinePosBox(m_xBuilder->weld_combo_box("position"))
 , m_xLineTypeBox(new SvtLineListBox(m_xBuilder->weld_menu_button("style")))
 , m_xLineWidthEdit(m_xBuilder->weld_metric_spin_button("thickness", 
FieldUnit::POINT))
 , m_xLineColorBox(new ColorListBox(m_xBuilder->weld_menu_button("color"),
 [this]{ return GetDialogController()->getDialog(); }))
+, m_xLineLengthLabel(m_xBuilder->weld_label("lengthlabel"))
 , m_xLineLengthEdit(m_xBuilder->weld_metric_spin_button("length", 
FieldUnit::PERCENT))
+, m_xLineDistLabel(m_xBuilder->weld_label("spacingtocontentslabel"))
 , m_xLineDistEdit(m_xBuilder->weld_metric_spin_button("spacingtocontents", 
FieldUnit::CM))
 {
 SetExchangeSupport();
@@ -116,6 +121,30 @@ SwFootNotePage::SwFootNotePage(weld::Container* pPage, 
weld::DialogController* p
 MeasurementSystem eSys = 
SvtSysLocale().GetLocaleData().getMeasurementSystemEnum();
 tools::Long nHeightValue = MeasurementSystem::Metric != eSys ? 1440 : 1134;
 
m_xMaxHeightEdit->set_value(m_xMaxHeightEdit->normalize(nHeightValue),FieldUnit::TWIP);
+
+bool bContinuousEndnotes = false;
+if (const SfxGrabBagItem* pGragbagItem = 
rSet.GetItemIfSet(SID_ATTR_CHAR_GRABBAG))
+{
+auto it = pGragbagItem->GetGrabBag().find("ContinuousEndnotes");
+if (it != pGragbagItem->GetGrabBag().end())
+{
+it->second >>= bContinuousEndnotes;
+}
+}
+
+if (bContinuousEndnotes)
+{
+// These are ignored in SwFootnoteContFrame::Format() and 
SwFootnoteContFrame::PaintLine(),
+// hide them.
+m_xDistLabel->set_visible(false);
+m_xDistEdit->set_visible(false);
+m_xLinePosLabel->set_visible(false);
+m_xLinePosBox->set_visible(false);
+m_xLineLengthLabel->set_visible(false);
+m_xLineLengthEdit->set_visible(false);
+m_xLineDistLabel->set_visible(false);
+m_xLineDistEdit->set_visible(false);
+}
 }
 
 SwFootNotePage::~SwFootNotePage()
diff --git a/sw/source/uibase/inc/pgfnote.hxx b/sw/source/uibase/inc/pgfnote.hxx
index c239f1ed292f..0abb09a80a9d 100644
--- a/sw/source/uibase/inc/pgfnote.hxx
+++ b/sw/source/uibase/inc/pgfnote.hxx
@@ -44,12 +44,16 @@ private:
 std::unique_ptr m_xMaxHeightPageBtn;
 std::unique_ptr m_xMaxHeightBtn;
 std::unique_ptr m_xMaxHeightEdit;
+std::unique_ptr m_xDistLabel;
 std::unique_ptr m_xDistEdit;
+std::unique_ptr m_xLinePosLabel;
 std::unique_ptr m_xLinePosBox;
 std::unique_ptr m_xLineTypeBox;
 std::unique_ptr m_xLineWidthEdit;
 std::unique_ptr m_xLineColorBox;
+std::unique_ptr m_xLineLengthLabel;
 std::unique_ptr m_xLineLengthEdit;
+std::unique_ptr m_xLineDistLabel;
 std::unique_ptr m_xLineDistEdit;
 
 

core.git: sw/qa sw/source

2024-05-31 Thread Miklos Vajna (via logerrit)
 sw/qa/core/layout/data/endnote-cont-separator.docx |binary
 sw/qa/core/layout/paintfrm.cxx |   27 +
 sw/source/core/inc/ftnfrm.hxx  |1 
 sw/source/core/layout/findfrm.cxx  |   11 
 sw/source/core/layout/paintfrm.cxx |   16 ++--
 5 files changed, 52 insertions(+), 3 deletions(-)

New commits:
commit 6450159e0e7c5fac9c998087e99f3fec602ff84d
Author: Miklos Vajna 
AuthorDate: Thu May 30 15:23:45 2024 +0200
Commit: Miklos Vajna 
CommitDate: Fri May 31 17:01:33 2024 +0200

tdf#160984 sw continuous endnotes: fix the endnote continuation separator 
len

See e.g.
,
one remaining difference for the Word vs Writer note separator is the
length of the endnote continuation separator: it's body frame width in
Word, shorter in Writer.

Seems this is specific to the endnote continuation separator, i.e.
normal endnote separator, footnote separator and footnote continuation
separator is not affected. Additionally, it's really footnote vs
endnote: if you put footnotes to the end of the document in Word, it
still doesn't make the separator longer.

Fix the problem by extending SwFootnoteContFrame::PaintLine() to handle
this: if in Word compat mode, first note frame is a follow endnote
frame, then paint the longer separator.

The usual render test way via SfxObjectShell::GetPreviewMetaFile() only
works with 1st pages and we want to assert the 2nd page here, so go via
DocumentToGraphicRenderer, similar to how
EPUBExportFilter::CreateMetafiles() does it.

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

diff --git a/sw/qa/core/layout/data/endnote-cont-separator.docx 
b/sw/qa/core/layout/data/endnote-cont-separator.docx
new file mode 100644
index ..2e01a5c91354
Binary files /dev/null and b/sw/qa/core/layout/data/endnote-cont-separator.docx 
differ
diff --git a/sw/qa/core/layout/paintfrm.cxx b/sw/qa/core/layout/paintfrm.cxx
index a5213c57d639..464979c988a6 100644
--- a/sw/qa/core/layout/paintfrm.cxx
+++ b/sw/qa/core/layout/paintfrm.cxx
@@ -10,6 +10,7 @@
 #include 
 
 #include 
+#include 
 
 #include 
 #include 
@@ -188,6 +189,32 @@ CPPUNIT_TEST_FIXTURE(Test, 
testInlineEndnoteSeparatorPosition)
 // i.e. the separator wasn't 2 inches long, but was shorter vs Word.
 CPPUNIT_ASSERT_EQUAL(static_cast(2880), 
nEndnoteSeparatorLength);
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testEndnoteContSeparator)
+{
+// Given a document with a Word-style endnote continuation separator:
+createSwDoc("endnote-cont-separator.docx");
+
+// When rendering page 2:
+sal_Int32 nPage = 2;
+DocumentToGraphicRenderer aRenderer(mxComponent, /*bSelectionOnly=*/false);
+Size aSize = aRenderer.getDocumentSizeInPixels(nPage);
+Graphic aGraphic = aRenderer.renderToGraphic(nPage, aSize, aSize, 
COL_WHITE,
+ /*bExtOutDevData=*/false);
+auto& xMetaFile = const_cast(aGraphic.GetGDIMetaFile());
+
+// Then make sure the separator length is correct:
+MetafileXmlDump aDumper;
+xmlDocUniquePtr pXmlDoc = dumpAndParse(aDumper, xMetaFile);
+auto nEndnoteSeparatorStart = getXPath(pXmlDoc, "//polygon/point[1]"_ostr, 
"x"_ostr).toInt32();
+auto nEndnoteSeparatorEnd = getXPath(pXmlDoc, "//polygon/point[2]"_ostr, 
"x"_ostr).toInt32();
+sal_Int32 nEndnoteSeparatorLength = nEndnoteSeparatorEnd - 
nEndnoteSeparatorStart;
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected: 9360 (page print area width)
+// - Actual  : 2880 (2 inches)
+// i.e. the separator was too short vs Word.
+CPPUNIT_ASSERT_EQUAL(static_cast(9360), 
nEndnoteSeparatorLength);
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/inc/ftnfrm.hxx b/sw/source/core/inc/ftnfrm.hxx
index 558c4941bf06..7331ef07d100 100644
--- a/sw/source/core/inc/ftnfrm.hxx
+++ b/sw/source/core/inc/ftnfrm.hxx
@@ -51,6 +51,7 @@ public:
 SwFootnoteContFrame( SwFrameFormat*, SwFrame* );
 
 const SwFootnoteFrame* FindFootNote() const;
+const SwFootnoteFrame* FindEndNote() const;
 
 static inline SwFootnoteFrame* AppendChained(SwFrame* pThis, bool 
bDefaultFormat);
 static inline SwFootnoteFrame* PrependChained(SwFrame* pThis, bool 
bDefaultFormat);
diff --git a/sw/source/core/layout/findfrm.cxx 
b/sw/source/core/layout/findfrm.cxx
index e83f4f8414a0..5f0cc8a0f256 100644
--- a/sw/source/core/layout/findfrm.cxx
+++ b/sw/source/core/layout/findfrm.cxx
@@ -698,6 +698,17 @@ const SwFootnoteFrame* SwFootnoteContFrame::FindFootNote() 
const
 return nullptr;
 }
 
+const SwFootnoteFrame* 

core.git: sw/qa sw/source

2024-05-31 Thread Miklos Vajna (via logerrit)
 sw/qa/writerfilter/dmapper/DomainMapper_Impl.cxx |   23 +++
 sw/qa/writerfilter/dmapper/data/clearing-break-sect-end.docx |binary
 sw/source/writerfilter/dmapper/DomainMapper.cxx  |4 -
 sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx |5 ++
 sw/source/writerfilter/dmapper/DomainMapper_Impl.hxx |3 +
 5 files changed, 33 insertions(+), 2 deletions(-)

New commits:
commit e00479404af5058b982c447e485af995d552e372
Author: Miklos Vajna 
AuthorDate: Fri May 31 09:00:18 2024 +0200
Commit: Miklos Vajna 
CommitDate: Fri May 31 12:58:00 2024 +0200

tdf#161318 sw clearing break: fix this at section end

Regression from commit 19bca24486315cc35f873486e6a2dd18394d0614
(tdf#126287: docx import: use defered linebreak, 2022-02-07), the bugdoc
has a single paragraph in the first section, containing a clearing
break, which is lost. This leads to overlapping text as the text is
shifted up.

Seems the intention was to avoid a line break at the very end of the
document, as that can lead to an empty page with "next page" section
breaks, with non-clearing line breaks.

Fix the problem by only doing this for non-clearing line breaks: that
keeps the old use-case working, but the new, clearing line break then
shifts down the text, so no text overlap happens.

Switching from appendTextPortion() to HandleLineBreak() helps because
HandleLineBreak() does exactly appendTextPortion("
") in the
non-clearing case, but knows about the stream stack's line break clear
status.

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

diff --git a/sw/qa/writerfilter/dmapper/DomainMapper_Impl.cxx 
b/sw/qa/writerfilter/dmapper/DomainMapper_Impl.cxx
index 825e615fb574..963db22c4c28 100644
--- a/sw/qa/writerfilter/dmapper/DomainMapper_Impl.cxx
+++ b/sw/qa/writerfilter/dmapper/DomainMapper_Impl.cxx
@@ -411,6 +411,29 @@ CPPUNIT_TEST_FIXTURE(Test, testRedlinedShapeThenSdt)
 CPPUNIT_ASSERT_EQUAL(u"ContentControl"_ustr,
  
xPortion->getPropertyValue("TextPortionType").get());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testClearingBreakSectEnd)
+{
+// Given a file with a single-paragraph section, ends with a clearing 
break:
+// When importing that document:
+loadFromFile(u"clearing-break-sect-end.docx");
+
+// Then make sure the clearing break is not lost before a cont sect break:
+uno::Reference xTextDocument(mxComponent, 
uno::UNO_QUERY);
+uno::Reference 
xParaEnumAccess(xTextDocument->getText(),
+  
uno::UNO_QUERY);
+uno::Reference xParaEnum = 
xParaEnumAccess->createEnumeration();
+uno::Reference 
xPortionEnumAccess(xParaEnum->nextElement(),
+ 
uno::UNO_QUERY);
+uno::Reference xPortionEnum = 
xPortionEnumAccess->createEnumeration();
+uno::Reference xPortion(xPortionEnum->nextElement(), 
uno::UNO_QUERY);
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected: LineBreak
+// - Actual  : Text
+// i.e. the clearing break at sect end was lost, leading to text overlap.
+CPPUNIT_ASSERT_EQUAL(u"LineBreak"_ustr,
+ 
xPortion->getPropertyValue("TextPortionType").get());
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/writerfilter/dmapper/data/clearing-break-sect-end.docx 
b/sw/qa/writerfilter/dmapper/data/clearing-break-sect-end.docx
new file mode 100644
index ..5052b2dd1649
Binary files /dev/null and 
b/sw/qa/writerfilter/dmapper/data/clearing-break-sect-end.docx differ
diff --git a/sw/source/writerfilter/dmapper/DomainMapper.cxx 
b/sw/source/writerfilter/dmapper/DomainMapper.cxx
index 9144acaf79f7..72f88fc2a1a3 100644
--- a/sw/source/writerfilter/dmapper/DomainMapper.cxx
+++ b/sw/source/writerfilter/dmapper/DomainMapper.cxx
@@ -4347,13 +4347,13 @@ void DomainMapper::lcl_utext(const sal_Unicode *const 
data_, size_t len)
 else if (len == 1 && sText[0] == ' ')
 {
 // Clear "last" one linebreak at end of section
-if (m_pImpl->GetIsLastParagraphInSection() && 
m_pImpl->isBreakDeferred(LINE_BREAK))
+if (m_pImpl->GetIsLastParagraphInSection() && 
m_pImpl->isBreakDeferred(LINE_BREAK) && !m_pImpl->HasLineBreakClear())
 m_pImpl->clearDeferredBreak(LINE_BREAK);
 // And emit all other linebreaks
 while (m_pImpl->isBreakDeferred(LINE_BREAK))
 {
 m_pImpl->clearDeferredBreak(LINE_BREAK);
-m_pImpl->appendTextPortion(u"
"_ustr, m_pImpl->GetTopContext());
+m_pImpl->HandleLineBreak(m_pImpl->GetTopContext());
 }
 }
 else if (len == 1 && sText[0] == ' ' )
diff --git 

core.git: Branch 'distro/collabora/co-23.05' - sw/CppunitTest_sw_core_text.mk sw/qa sw/source

2024-05-30 Thread Miklos Vajna (via logerrit)
 sw/CppunitTest_sw_core_text.mk|1 
 sw/qa/core/text/data/clearing-break-wrap-through.docx |binary
 sw/qa/core/text/txtfly.cxx|   52 ++
 sw/source/core/text/txtfly.cxx|7 ++
 4 files changed, 60 insertions(+)

New commits:
commit af5b508e92bd9df21ba821f266ec4ede606677aa
Author: Miklos Vajna 
AuthorDate: Thu May 30 08:10:13 2024 +0200
Commit: Miklos Vajna 
CommitDate: Thu May 30 15:39:26 2024 +0200

tdf#161318 sw clearing break: ignore wrap-through anchored objects

Import the bugdoc: we expect just a single page for the 2 paragraphs,
but the second paragraph goes to a 2nd page.

What seems to happen since commit
f86d1482bef285f90079b5130e410646db96cf58 (sw clearing breaks: add DOCX
import, 2022-03-08) is that on one hand, SwTextFly::ForEach() ignores
wrap-through shapes, but at the same time SwTextFly::GetMaxBottom() did
not, and this lead to a loop: the first paragraph kept growing till the
shape was shifted to page 2, but then the same first paragraph was
reduced to just 2 lines, goto 1.

Fix the problem by extending SwTextFly::GetMaxBottom() to also ignore
wrap-though shapes: this is the intention, just clearing breaks were not
tested with wrap-though wrap mode before.

This is a reduced bugdoc, the original one even produced warnings like:
warn:legacy.osl:12034:12034:sw/source/core/layout/flowfrm.cxx:2667: 
 - layout loop control for layout action  applied!
without the fix, and these are now gone.

(cherry picked from commit 304cc248f15d795bc9fe8b751b0d98841b8ff5d1)

Conflicts:
sw/CppunitTest_sw_core_text.mk

Change-Id: Iaf9849dbf8e1a8e5d625d3c19b99636247804cdd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168254
Reviewed-by: Caolán McNamara 
Tested-by: Jenkins CollaboraOffice 
Tested-by: Caolán McNamara 
(cherry picked from commit 317ca78624b1594a40c4917482e99d10bd8e2780)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168262
Reviewed-by: Miklos Vajna 

diff --git a/sw/CppunitTest_sw_core_text.mk b/sw/CppunitTest_sw_core_text.mk
index ce27696b3c4c..5e623d3b0cd0 100644
--- a/sw/CppunitTest_sw_core_text.mk
+++ b/sw/CppunitTest_sw_core_text.mk
@@ -20,6 +20,7 @@ $(eval $(call 
gb_CppunitTest_add_exception_objects,sw_core_text, \
 sw/qa/core/text/porlay \
 sw/qa/core/text/porrst \
 sw/qa/core/text/text \
+sw/qa/core/text/txtfly \
 ))
 
 $(eval $(call gb_CppunitTest_use_libraries,sw_core_text, \
diff --git a/sw/qa/core/text/data/clearing-break-wrap-through.docx 
b/sw/qa/core/text/data/clearing-break-wrap-through.docx
new file mode 100644
index ..c96e8c27da5e
Binary files /dev/null and 
b/sw/qa/core/text/data/clearing-break-wrap-through.docx differ
diff --git a/sw/qa/core/text/txtfly.cxx b/sw/qa/core/text/txtfly.cxx
new file mode 100644
index ..461ed81e2203
--- /dev/null
+++ b/sw/qa/core/text/txtfly.cxx
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-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/.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+namespace
+{
+/// Covers sw/source/core/text/txtfly.cxx fixes.
+class Test : public SwModelTestBase
+{
+public:
+Test()
+: SwModelTestBase("/sw/qa/core/text/data/")
+{
+}
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testClearingBreakWrapThrough)
+{
+// Given a document with a clearing break, then a shape in the next 
paragraph:
+createSwDoc("clearing-break-wrap-through.docx");
+
+// When laying out that document:
+calcLayout();
+
+// Then make sure we layout these 2 paragraphs on a single page, since 
there is enough space for
+// them:
+SwDoc* pDoc = getSwDoc();
+SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+auto pPage = pLayout->Lower()->DynCastPageFrame();
+CPPUNIT_ASSERT(pPage);
+// Without the accompanying fix in place, this test would have failed, we 
had an unexpected 2nd
+// page.
+CPPUNIT_ASSERT(!pPage->GetNext());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/txtfly.cxx b/sw/source/core/text/txtfly.cxx
index a4f625651f1e..dc4d24f27aab 100644
--- a/sw/source/core/text/txtfly.cxx
+++ b/sw/source/core/text/txtfly.cxx
@@ -1043,6 +1043,13 @@ SwTwips SwTextFly::GetMaxBottom(const SwBreakPortion& 
rPortion, const SwTextForm
 continue;
 }
 
+const SwFormatSurround& rSurround = 
pAnchoredObj->GetFrameFormat().GetSurround();
+if (rSurround.GetValue() == text::WrapTextMode_THROUGH)
+{
+

core.git: Branch 'distro/collabora/co-24.04' - sw/CppunitTest_sw_core_text.mk sw/qa sw/source

2024-05-30 Thread Miklos Vajna (via logerrit)
 sw/CppunitTest_sw_core_text.mk|1 
 sw/qa/core/text/data/clearing-break-wrap-through.docx |binary
 sw/qa/core/text/txtfly.cxx|   52 ++
 sw/source/core/text/txtfly.cxx|7 ++
 4 files changed, 60 insertions(+)

New commits:
commit 317ca78624b1594a40c4917482e99d10bd8e2780
Author: Miklos Vajna 
AuthorDate: Thu May 30 08:10:13 2024 +0200
Commit: Caolán McNamara 
CommitDate: Thu May 30 14:09:53 2024 +0200

tdf#161318 sw clearing break: ignore wrap-through anchored objects

Import the bugdoc: we expect just a single page for the 2 paragraphs,
but the second paragraph goes to a 2nd page.

What seems to happen since commit
f86d1482bef285f90079b5130e410646db96cf58 (sw clearing breaks: add DOCX
import, 2022-03-08) is that on one hand, SwTextFly::ForEach() ignores
wrap-through shapes, but at the same time SwTextFly::GetMaxBottom() did
not, and this lead to a loop: the first paragraph kept growing till the
shape was shifted to page 2, but then the same first paragraph was
reduced to just 2 lines, goto 1.

Fix the problem by extending SwTextFly::GetMaxBottom() to also ignore
wrap-though shapes: this is the intention, just clearing breaks were not
tested with wrap-though wrap mode before.

This is a reduced bugdoc, the original one even produced warnings like:
warn:legacy.osl:12034:12034:sw/source/core/layout/flowfrm.cxx:2667: 
 - layout loop control for layout action  applied!
without the fix, and these are now gone.

(cherry picked from commit 304cc248f15d795bc9fe8b751b0d98841b8ff5d1)

Conflicts:
sw/CppunitTest_sw_core_text.mk

Change-Id: Iaf9849dbf8e1a8e5d625d3c19b99636247804cdd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168254
Reviewed-by: Caolán McNamara 
Tested-by: Jenkins CollaboraOffice 
Tested-by: Caolán McNamara 

diff --git a/sw/CppunitTest_sw_core_text.mk b/sw/CppunitTest_sw_core_text.mk
index ce27696b3c4c..5e623d3b0cd0 100644
--- a/sw/CppunitTest_sw_core_text.mk
+++ b/sw/CppunitTest_sw_core_text.mk
@@ -20,6 +20,7 @@ $(eval $(call 
gb_CppunitTest_add_exception_objects,sw_core_text, \
 sw/qa/core/text/porlay \
 sw/qa/core/text/porrst \
 sw/qa/core/text/text \
+sw/qa/core/text/txtfly \
 ))
 
 $(eval $(call gb_CppunitTest_use_libraries,sw_core_text, \
diff --git a/sw/qa/core/text/data/clearing-break-wrap-through.docx 
b/sw/qa/core/text/data/clearing-break-wrap-through.docx
new file mode 100644
index ..c96e8c27da5e
Binary files /dev/null and 
b/sw/qa/core/text/data/clearing-break-wrap-through.docx differ
diff --git a/sw/qa/core/text/txtfly.cxx b/sw/qa/core/text/txtfly.cxx
new file mode 100644
index ..461ed81e2203
--- /dev/null
+++ b/sw/qa/core/text/txtfly.cxx
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-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/.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+namespace
+{
+/// Covers sw/source/core/text/txtfly.cxx fixes.
+class Test : public SwModelTestBase
+{
+public:
+Test()
+: SwModelTestBase("/sw/qa/core/text/data/")
+{
+}
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testClearingBreakWrapThrough)
+{
+// Given a document with a clearing break, then a shape in the next 
paragraph:
+createSwDoc("clearing-break-wrap-through.docx");
+
+// When laying out that document:
+calcLayout();
+
+// Then make sure we layout these 2 paragraphs on a single page, since 
there is enough space for
+// them:
+SwDoc* pDoc = getSwDoc();
+SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+auto pPage = pLayout->Lower()->DynCastPageFrame();
+CPPUNIT_ASSERT(pPage);
+// Without the accompanying fix in place, this test would have failed, we 
had an unexpected 2nd
+// page.
+CPPUNIT_ASSERT(!pPage->GetNext());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/txtfly.cxx b/sw/source/core/text/txtfly.cxx
index 7c4d9a2e160d..45eea853 100644
--- a/sw/source/core/text/txtfly.cxx
+++ b/sw/source/core/text/txtfly.cxx
@@ -1051,6 +1051,13 @@ SwTwips SwTextFly::GetMaxBottom(const SwBreakPortion& 
rPortion, const SwTextForm
 continue;
 }
 
+const SwFormatSurround& rSurround = 
pAnchoredObj->GetFrameFormat()->GetSurround();
+if (rSurround.GetValue() == text::WrapTextMode_THROUGH)
+{
+// Wrap through has no influence on clearing breaks.
+continue;
+}
+
 SwRect aRect(pAnchoredObj->GetObjRectWithSpaces());
 

core.git: Branch 'distro/collabora/co-24.04' - sw/qa sw/source

2024-05-30 Thread Miklos Vajna (via logerrit)
 sw/qa/filter/ww8/ww8.cxx |   30 +++
 sw/source/filter/ww8/docxattributeoutput.cxx |   13 +++
 sw/source/filter/ww8/docxattributeoutput.hxx |2 -
 sw/source/filter/ww8/docxexport.cxx  |4 +--
 4 files changed, 46 insertions(+), 3 deletions(-)

New commits:
commit d0ee0c93d6145542d82ba62887f4e5a3691333fe
Author: Miklos Vajna 
AuthorDate: Wed May 29 13:34:25 2024 +0200
Commit: Caolán McNamara 
CommitDate: Thu May 30 14:08:24 2024 +0200

tdf#160984 sw continuous endnotes: DOCX: export of  pos == 
sectEnd

In case a DOCX file is re-exported to Word and it collected endnotes at
section end, this setting was lost on save.

The relevant markup seems to be  -> , though that's a per-section setting in Writer, and is
a per-doc setting in Word.

Fix the problem by doing it similar to
DocxExport::WriteDocumentBackgroundFill(), which takes the first page
style in a similar case; here we take the first section format.

This is meant to be good enough for the DOCX editing case, where we know
all sections have the same endnote position properties anyway.

(cherry picked from commit 566c7017a84e3d573de85a6d986b81d3f59de0fa)

Change-Id: I95508296e31c9be34196bdc0da2177101647abf9
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168241
Tested-by: Jenkins CollaboraOffice 
Reviewed-by: Caolán McNamara 

diff --git a/sw/qa/filter/ww8/ww8.cxx b/sw/qa/filter/ww8/ww8.cxx
index 4cbbfe5fbf31..070565345a2d 100644
--- a/sw/qa/filter/ww8/ww8.cxx
+++ b/sw/qa/filter/ww8/ww8.cxx
@@ -32,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 
 namespace
 {
@@ -564,6 +565,35 @@ CPPUNIT_TEST_FIXTURE(Test, testNullPointerDereference)
 createSwDoc("null-pointer-dereference.doc");
 CPPUNIT_ASSERT_EQUAL(6, getPages());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testEndnotesAtSectEnd)
+{
+// Given a document, endnotes at collected at section end:
+createSwDoc();
+SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
+pWrtShell->SplitNode();
+pWrtShell->Up(/*bSelect=*/false);
+pWrtShell->Insert("x");
+pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, 
/*bBasicCall=*/false);
+SwSectionData aSection(SectionType::Content, 
pWrtShell->GetUniqueSectionName());
+pWrtShell->StartAction();
+SfxItemSetFixed 
aSet(pWrtShell->GetAttrPool());
+aSet.Put(SwFormatEndAtTextEnd(FTNEND_ATTXTEND));
+pWrtShell->InsertSection(aSection, );
+pWrtShell->EndAction();
+pWrtShell->InsertFootnote(OUString(), /*bEndNote=*/true);
+
+// When saving to DOCX:
+save("Office Open XML Text");
+
+// Then make sure the endnote position is section end:
+xmlDocUniquePtr pXmlDoc = parseExport("word/settings.xml");
+OUString aPos = getXPath(pXmlDoc, "/w:settings/w:endnotePr/w:pos"_ostr, 
"val"_ostr);
+// Without the accompanying fix in place, this test would have failed with:
+// - XPath '/w:settings/w:endnotePr/w:pos' number of nodes is incorrect
+// i.e. the default position was used: document end.
+CPPUNIT_ASSERT_EQUAL(OUString("sectEnd"), aPos);
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index 3201321a6328..2f77cf07b06a 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -127,6 +127,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -8786,6 +8787,18 @@ void DocxAttributeOutput::WriteFootnoteEndnotePr( 
::sax_fastparser::FSHelperPtr
 const SwEndNoteInfo& info, int listtag )
 {
 fs->startElementNS(XML_w, tag);
+
+SwSectionFormats& rSections = m_rExport.m_rDoc.GetSections();
+if (!rSections.empty())
+{
+SwSectionFormat* pFormat = rSections[0];
+bool bEndnAtEnd = pFormat->GetEndAtTextEnd().IsAtEnd();
+if (bEndnAtEnd)
+{
+fs->singleElementNS(XML_w, XML_pos, FSNS(XML_w, XML_val), 
"sectEnd");
+}
+}
+
 OString aCustomFormat;
 OString fmt = lcl_ConvertNumberingType(info.m_aFormat.GetNumberingType(), 
nullptr, aCustomFormat);
 if (!fmt.isEmpty() && aCustomFormat.isEmpty())
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx 
b/sw/source/filter/ww8/docxattributeoutput.hxx
index 10f39debc2a0..b23f5b98ee7e 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -1109,7 +1109,7 @@ public:
 void FootnotesEndnotes( bool bFootnotes );
 
 /// writes the footnotePr/endnotePr (depending on tag) section
-static void WriteFootnoteEndnotePr( ::sax_fastparser::FSHelperPtr const & 
fs, int tag, const SwEndNoteInfo& info, int listtag );
+void WriteFootnoteEndnotePr( ::sax_fastparser::FSHelperPtr const & fs, int 
tag, const SwEndNoteInfo& info, int listtag );
 
 bool HasPostitFields() const;
  

core.git: sw/CppunitTest_sw_core_text.mk sw/qa sw/source

2024-05-30 Thread Miklos Vajna (via logerrit)
 sw/CppunitTest_sw_core_text.mk|1 
 sw/qa/core/text/data/clearing-break-wrap-through.docx |binary
 sw/qa/core/text/txtfly.cxx|   52 ++
 sw/source/core/text/txtfly.cxx|7 ++
 4 files changed, 60 insertions(+)

New commits:
commit 304cc248f15d795bc9fe8b751b0d98841b8ff5d1
Author: Miklos Vajna 
AuthorDate: Thu May 30 08:10:13 2024 +0200
Commit: Miklos Vajna 
CommitDate: Thu May 30 13:30:40 2024 +0200

tdf#161318 sw clearing break: ignore wrap-through anchored objects

Import the bugdoc: we expect just a single page for the 2 paragraphs,
but the second paragraph goes to a 2nd page.

What seems to happen since commit
f86d1482bef285f90079b5130e410646db96cf58 (sw clearing breaks: add DOCX
import, 2022-03-08) is that on one hand, SwTextFly::ForEach() ignores
wrap-through shapes, but at the same time SwTextFly::GetMaxBottom() did
not, and this lead to a loop: the first paragraph kept growing till the
shape was shifted to page 2, but then the same first paragraph was
reduced to just 2 lines, goto 1.

Fix the problem by extending SwTextFly::GetMaxBottom() to also ignore
wrap-though shapes: this is the intention, just clearing breaks were not
tested with wrap-though wrap mode before.

This is a reduced bugdoc, the original one even produced warnings like:
warn:legacy.osl:12034:12034:sw/source/core/layout/flowfrm.cxx:2667: 
 - layout loop control for layout action  applied!
without the fix, and these are now gone.

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

diff --git a/sw/CppunitTest_sw_core_text.mk b/sw/CppunitTest_sw_core_text.mk
index 95b69b90113b..8c215dfab4e1 100644
--- a/sw/CppunitTest_sw_core_text.mk
+++ b/sw/CppunitTest_sw_core_text.mk
@@ -20,6 +20,7 @@ $(eval $(call 
gb_CppunitTest_add_exception_objects,sw_core_text, \
 sw/qa/core/text/porlay \
 sw/qa/core/text/porrst \
 sw/qa/core/text/text \
+sw/qa/core/text/txtfly \
 sw/qa/core/text/widorp \
 ))
 
diff --git a/sw/qa/core/text/data/clearing-break-wrap-through.docx 
b/sw/qa/core/text/data/clearing-break-wrap-through.docx
new file mode 100644
index ..c96e8c27da5e
Binary files /dev/null and 
b/sw/qa/core/text/data/clearing-break-wrap-through.docx differ
diff --git a/sw/qa/core/text/txtfly.cxx b/sw/qa/core/text/txtfly.cxx
new file mode 100644
index ..461ed81e2203
--- /dev/null
+++ b/sw/qa/core/text/txtfly.cxx
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-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/.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+namespace
+{
+/// Covers sw/source/core/text/txtfly.cxx fixes.
+class Test : public SwModelTestBase
+{
+public:
+Test()
+: SwModelTestBase("/sw/qa/core/text/data/")
+{
+}
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testClearingBreakWrapThrough)
+{
+// Given a document with a clearing break, then a shape in the next 
paragraph:
+createSwDoc("clearing-break-wrap-through.docx");
+
+// When laying out that document:
+calcLayout();
+
+// Then make sure we layout these 2 paragraphs on a single page, since 
there is enough space for
+// them:
+SwDoc* pDoc = getSwDoc();
+SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+auto pPage = pLayout->Lower()->DynCastPageFrame();
+CPPUNIT_ASSERT(pPage);
+// Without the accompanying fix in place, this test would have failed, we 
had an unexpected 2nd
+// page.
+CPPUNIT_ASSERT(!pPage->GetNext());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/txtfly.cxx b/sw/source/core/text/txtfly.cxx
index 7c4d9a2e160d..45eea853 100644
--- a/sw/source/core/text/txtfly.cxx
+++ b/sw/source/core/text/txtfly.cxx
@@ -1051,6 +1051,13 @@ SwTwips SwTextFly::GetMaxBottom(const SwBreakPortion& 
rPortion, const SwTextForm
 continue;
 }
 
+const SwFormatSurround& rSurround = 
pAnchoredObj->GetFrameFormat()->GetSurround();
+if (rSurround.GetValue() == text::WrapTextMode_THROUGH)
+{
+// Wrap through has no influence on clearing breaks.
+continue;
+}
+
 SwRect aRect(pAnchoredObj->GetObjRectWithSpaces());
 
 if (m_pCurrFrame->IsVertical())


core.git: Branch 'distro/collabora/co-24.04' - libreofficekit/README.md

2024-05-30 Thread Miklos Vajna (via logerrit)
 libreofficekit/README.md |   14 ++
 1 file changed, 14 insertions(+)

New commits:
commit fd22acaf8914b11962d6667eacfc47e514fc7b43
Author: Miklos Vajna 
AuthorDate: Wed May 29 08:21:37 2024 +0200
Commit: Caolán McNamara 
CommitDate: Thu May 30 10:24:35 2024 +0200

lok: document some guidelines on how to not end up with too many callbacks

In general, the existing command dispatch, command value getter &
command state callback is meant to be enough for most needs.

(cherry picked from commit ff0cb77a6c9fec7127c26f63a420e877ac4f852e)

Change-Id: Ibba5455b461a8eac052f17ac5e824ddea42755f3
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168240
Tested-by: Jenkins CollaboraOffice 
Reviewed-by: Caolán McNamara 
Tested-by: Caolán McNamara 

diff --git a/libreofficekit/README.md b/libreofficekit/README.md
index 95a33707a28a..148879ec57fc 100644
--- a/libreofficekit/README.md
+++ b/libreofficekit/README.md
@@ -81,6 +81,20 @@ once a feature works there, then implement the Android part, 
with its slower
 development iteration (slow uploading to the device, the need to link all
 object files into a single `.so`, etc).
 
+### LOK API guidelines
+
+Introducing explicit new API under `include/LibreOfficeKit/` adds type safety 
but listing each &
+every micro-feature in those headers don't scale. Before extending those 
headers, consider using one
+of the following alternatives, which require no changes to these headers:
+
+- LOK client → core direction: use `postUnoCommand()` to dispatch an UNO 
command, optionally with
+  parameters.
+- core → LOK client direction:
+  - Use `getCommandValues()` when this is initiated by the LOK client.
+  - Use `LOK_CALLBACK_STATE_CHANGED` with a JSON payload when this is 
initiated by core.
+
+It's useful to stick to these if possible, only add new C++ API when these are 
not a good fit.
+
 * Debugging with gdb and `gtktiledviewer`
 
 To run `gtktiledviewer`:


core.git: sw/qa sw/source

2024-05-29 Thread Miklos Vajna (via logerrit)
 sw/qa/filter/ww8/ww8.cxx |   30 +++
 sw/source/filter/ww8/docxattributeoutput.cxx |   13 +++
 sw/source/filter/ww8/docxattributeoutput.hxx |2 -
 sw/source/filter/ww8/docxexport.cxx  |4 +--
 4 files changed, 46 insertions(+), 3 deletions(-)

New commits:
commit 566c7017a84e3d573de85a6d986b81d3f59de0fa
Author: Miklos Vajna 
AuthorDate: Wed May 29 13:34:25 2024 +0200
Commit: Miklos Vajna 
CommitDate: Wed May 29 20:10:50 2024 +0200

tdf#160984 sw continuous endnotes: DOCX: export of  pos == 
sectEnd

In case a DOCX file is re-exported to Word and it collected endnotes at
section end, this setting was lost on save.

The relevant markup seems to be  -> , though that's a per-section setting in Writer, and is
a per-doc setting in Word.

Fix the problem by doing it similar to
DocxExport::WriteDocumentBackgroundFill(), which takes the first page
style in a similar case; here we take the first section format.

This is meant to be good enough for the DOCX editing case, where we know
all sections have the same endnote position properties anyway.

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

diff --git a/sw/qa/filter/ww8/ww8.cxx b/sw/qa/filter/ww8/ww8.cxx
index 4cbbfe5fbf31..070565345a2d 100644
--- a/sw/qa/filter/ww8/ww8.cxx
+++ b/sw/qa/filter/ww8/ww8.cxx
@@ -32,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 
 namespace
 {
@@ -564,6 +565,35 @@ CPPUNIT_TEST_FIXTURE(Test, testNullPointerDereference)
 createSwDoc("null-pointer-dereference.doc");
 CPPUNIT_ASSERT_EQUAL(6, getPages());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testEndnotesAtSectEnd)
+{
+// Given a document, endnotes at collected at section end:
+createSwDoc();
+SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
+pWrtShell->SplitNode();
+pWrtShell->Up(/*bSelect=*/false);
+pWrtShell->Insert("x");
+pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, 
/*bBasicCall=*/false);
+SwSectionData aSection(SectionType::Content, 
pWrtShell->GetUniqueSectionName());
+pWrtShell->StartAction();
+SfxItemSetFixed 
aSet(pWrtShell->GetAttrPool());
+aSet.Put(SwFormatEndAtTextEnd(FTNEND_ATTXTEND));
+pWrtShell->InsertSection(aSection, );
+pWrtShell->EndAction();
+pWrtShell->InsertFootnote(OUString(), /*bEndNote=*/true);
+
+// When saving to DOCX:
+save("Office Open XML Text");
+
+// Then make sure the endnote position is section end:
+xmlDocUniquePtr pXmlDoc = parseExport("word/settings.xml");
+OUString aPos = getXPath(pXmlDoc, "/w:settings/w:endnotePr/w:pos"_ostr, 
"val"_ostr);
+// Without the accompanying fix in place, this test would have failed with:
+// - XPath '/w:settings/w:endnotePr/w:pos' number of nodes is incorrect
+// i.e. the default position was used: document end.
+CPPUNIT_ASSERT_EQUAL(OUString("sectEnd"), aPos);
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index 1532ecf72c81..971f27df0314 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -127,6 +127,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -8780,6 +8781,18 @@ void DocxAttributeOutput::WriteFootnoteEndnotePr( 
::sax_fastparser::FSHelperPtr
 const SwEndNoteInfo& info, int listtag )
 {
 fs->startElementNS(XML_w, tag);
+
+SwSectionFormats& rSections = m_rExport.m_rDoc.GetSections();
+if (!rSections.empty())
+{
+SwSectionFormat* pFormat = rSections[0];
+bool bEndnAtEnd = pFormat->GetEndAtTextEnd().IsAtEnd();
+if (bEndnAtEnd)
+{
+fs->singleElementNS(XML_w, XML_pos, FSNS(XML_w, XML_val), 
"sectEnd");
+}
+}
+
 OString aCustomFormat;
 OString fmt = lcl_ConvertNumberingType(info.m_aFormat.GetNumberingType(), 
nullptr, aCustomFormat);
 if (!fmt.isEmpty() && aCustomFormat.isEmpty())
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx 
b/sw/source/filter/ww8/docxattributeoutput.hxx
index b1da698c3dec..063cb02bbc69 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -1109,7 +1109,7 @@ public:
 void FootnotesEndnotes( bool bFootnotes );
 
 /// writes the footnotePr/endnotePr (depending on tag) section
-static void WriteFootnoteEndnotePr( ::sax_fastparser::FSHelperPtr const & 
fs, int tag, const SwEndNoteInfo& info, int listtag );
+void WriteFootnoteEndnotePr( ::sax_fastparser::FSHelperPtr const & fs, int 
tag, const SwEndNoteInfo& info, int listtag );
 
 bool HasPostitFields() const;
 enum class hasProperties { no, yes };
diff --git a/sw/source/filter/ww8/docxexport.cxx 

core.git: libreofficekit/README.md

2024-05-29 Thread Miklos Vajna (via logerrit)
 libreofficekit/README.md |   14 ++
 1 file changed, 14 insertions(+)

New commits:
commit ff0cb77a6c9fec7127c26f63a420e877ac4f852e
Author: Miklos Vajna 
AuthorDate: Wed May 29 08:21:37 2024 +0200
Commit: Miklos Vajna 
CommitDate: Wed May 29 19:32:19 2024 +0200

lok: document some guidelines on how to not end up with too many callbacks

In general, the existing command dispatch, command value getter &
command state callback is meant to be enough for most needs.

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

diff --git a/libreofficekit/README.md b/libreofficekit/README.md
index 95a33707a28a..148879ec57fc 100644
--- a/libreofficekit/README.md
+++ b/libreofficekit/README.md
@@ -81,6 +81,20 @@ once a feature works there, then implement the Android part, 
with its slower
 development iteration (slow uploading to the device, the need to link all
 object files into a single `.so`, etc).
 
+### LOK API guidelines
+
+Introducing explicit new API under `include/LibreOfficeKit/` adds type safety 
but listing each &
+every micro-feature in those headers don't scale. Before extending those 
headers, consider using one
+of the following alternatives, which require no changes to these headers:
+
+- LOK client → core direction: use `postUnoCommand()` to dispatch an UNO 
command, optionally with
+  parameters.
+- core → LOK client direction:
+  - Use `getCommandValues()` when this is initiated by the LOK client.
+  - Use `LOK_CALLBACK_STATE_CHANGED` with a JSON payload when this is 
initiated by core.
+
+It's useful to stick to these if possible, only add new C++ API when these are 
not a good fit.
+
 * Debugging with gdb and `gtktiledviewer`
 
 To run `gtktiledviewer`:


core.git: Branch 'distro/collabora/co-24.04' - writerfilter/qa writerfilter/source

2024-05-29 Thread Miklos Vajna (via logerrit)
 writerfilter/qa/cppunittests/dmapper/SettingsTable.cxx|   22 
++
 writerfilter/qa/cppunittests/dmapper/data/endnote-at-section-end.docx |binary
 writerfilter/source/dmapper/PropertyMap.cxx   |7 
++-
 writerfilter/source/dmapper/SettingsTable.cxx |   13 
+
 writerfilter/source/dmapper/SettingsTable.hxx |2 
 5 files changed, 43 insertions(+), 1 deletion(-)

New commits:
commit 812d5e98dc2a96e9b7351d19ab33031af7d90221
Author: Miklos Vajna 
AuthorDate: Tue May 28 13:26:05 2024 +0200
Commit: Caolán McNamara 
CommitDate: Wed May 29 09:16:13 2024 +0200

tdf#160984 sw continuous endnotes: DOCX: import  pos == sectEnd

Word can have per-section endnotes, but if endnotes are collected at the
end of the section vs document end is a per-document setting.

The DOC import already handles this in wwSectionManager::InsertSection()
when it constructs an SwFormatEndAtTextEnd with FTNEND_ATTXTEND.

Fix the problem by doing the same in writerfilter: in case settings.xml
wants at-section-end endnotes, set EndnoteIsCollectAtTextEnd to true
when applying section properties.

The export side still needs doing.

(cherry picked from commit 2d2dd56e0b2dc708f1f758d7fc9a1263ff09b83c)

Conflicts:
writerfilter/source/dmapper/PropertyMap.cxx

Change-Id: Ibad9c2d62a2945ee42877c849482feee60a50178
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168179
Tested-by: Jenkins CollaboraOffice 
Reviewed-by: Caolán McNamara 

diff --git a/writerfilter/qa/cppunittests/dmapper/SettingsTable.cxx 
b/writerfilter/qa/cppunittests/dmapper/SettingsTable.cxx
index 52814727f91c..bf7a4e48de49 100644
--- a/writerfilter/qa/cppunittests/dmapper/SettingsTable.cxx
+++ b/writerfilter/qa/cppunittests/dmapper/SettingsTable.cxx
@@ -11,6 +11,7 @@
 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -87,6 +88,27 @@ CPPUNIT_TEST_FIXTURE(Test, testAddVerticalFrameOffsetsRTF)
 // i.e. table top should be ~2748, but was less, leading to an overlap.
 CPPUNIT_ASSERT_GREATER(nFlyBottom, nTableTop);
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testEndnoteAtSectionEnd)
+{
+// Given a document with at-section-end endnotes enabled:
+loadFromFile(u"endnote-at-section-end.docx");
+
+// Go to the second paragraph, which is inside Word's second section:
+uno::Reference xTextDocument(mxComponent, 
uno::UNO_QUERY);
+uno::Reference 
xParaEnumAccess(xTextDocument->getText(),
+  
uno::UNO_QUERY);
+uno::Reference xParaEnum = 
xParaEnumAccess->createEnumeration();
+xParaEnum->nextElement();
+uno::Reference xPara(xParaEnum->nextElement(), 
uno::UNO_QUERY);
+uno::Reference xSection;
+xPara->getPropertyValue("TextSection") >>= xSection;
+bool bEndnoteIsCollectAtTextEnd = false;
+xSection->getPropertyValue("EndnoteIsCollectAtTextEnd") >>= 
bEndnoteIsCollectAtTextEnd;
+// Without the accompanying fix in place, this test would have failed, 
endnotes were always at
+// document end.
+CPPUNIT_ASSERT(bEndnoteIsCollectAtTextEnd);
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git 
a/writerfilter/qa/cppunittests/dmapper/data/endnote-at-section-end.docx 
b/writerfilter/qa/cppunittests/dmapper/data/endnote-at-section-end.docx
new file mode 100644
index ..cf61262c7d59
Binary files /dev/null and 
b/writerfilter/qa/cppunittests/dmapper/data/endnote-at-section-end.docx differ
diff --git a/writerfilter/source/dmapper/PropertyMap.cxx 
b/writerfilter/source/dmapper/PropertyMap.cxx
index 73d53a7e7c96..14299eaf7a88 100644
--- a/writerfilter/source/dmapper/PropertyMap.cxx
+++ b/writerfilter/source/dmapper/PropertyMap.cxx
@@ -749,7 +749,7 @@ void SectionPropertyMap::DontBalanceTextColumns()
 }
 }
 
-void SectionPropertyMap::ApplySectionProperties( const uno::Reference< 
beans::XPropertySet >& xSection, DomainMapper_Impl& /*rDM_Impl*/ )
+void SectionPropertyMap::ApplySectionProperties( const uno::Reference< 
beans::XPropertySet >& xSection, DomainMapper_Impl& rDM_Impl )
 {
 try
 {
@@ -758,6 +758,11 @@ void SectionPropertyMap::ApplySectionProperties( const 
uno::Reference< beans::XP
 std::optional< PropertyMap::Property > pProp = getProperty( 
PROP_WRITING_MODE );
 if ( pProp )
 xSection->setPropertyValue( "WritingMode", pProp->second );
+
+if (rDM_Impl.GetSettingsTable()->GetEndnoteIsCollectAtSectionEnd())
+{
+xSection->setPropertyValue("EndnoteIsCollectAtTextEnd", 
uno::Any(true));
+}
 }
 }
 catch ( uno::Exception& )
diff --git a/writerfilter/source/dmapper/SettingsTable.cxx 
b/writerfilter/source/dmapper/SettingsTable.cxx
index b16846420682..604858a871f2 100644
--- a/writerfilter/source/dmapper/SettingsTable.cxx
+++ 

core.git: sw/qa sw/source

2024-05-28 Thread Miklos Vajna (via logerrit)
 sw/qa/writerfilter/dmapper/SettingsTable.cxx|   22 
 sw/qa/writerfilter/dmapper/data/endnote-at-section-end.docx |binary
 sw/source/writerfilter/dmapper/PropertyMap.cxx  |9 
 sw/source/writerfilter/dmapper/SettingsTable.cxx|   13 +++
 sw/source/writerfilter/dmapper/SettingsTable.hxx|2 +
 5 files changed, 45 insertions(+), 1 deletion(-)

New commits:
commit 2d2dd56e0b2dc708f1f758d7fc9a1263ff09b83c
Author: Miklos Vajna 
AuthorDate: Tue May 28 13:26:05 2024 +0200
Commit: Miklos Vajna 
CommitDate: Tue May 28 17:13:08 2024 +0200

tdf#160984 sw continuous endnotes: DOCX: import  pos == sectEnd

Word can have per-section endnotes, but if endnotes are collected at the
end of the section vs document end is a per-document setting.

The DOC import already handles this in wwSectionManager::InsertSection()
when it constructs an SwFormatEndAtTextEnd with FTNEND_ATTXTEND.

Fix the problem by doing the same in writerfilter: in case settings.xml
wants at-section-end endnotes, set EndnoteIsCollectAtTextEnd to true
when applying section properties.

The export side still needs doing.

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

diff --git a/sw/qa/writerfilter/dmapper/SettingsTable.cxx 
b/sw/qa/writerfilter/dmapper/SettingsTable.cxx
index 503b28d45c95..ef94a60fc544 100644
--- a/sw/qa/writerfilter/dmapper/SettingsTable.cxx
+++ b/sw/qa/writerfilter/dmapper/SettingsTable.cxx
@@ -11,6 +11,7 @@
 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -87,6 +88,27 @@ CPPUNIT_TEST_FIXTURE(Test, testAddVerticalFrameOffsetsRTF)
 // i.e. table top should be ~2748, but was less, leading to an overlap.
 CPPUNIT_ASSERT_GREATER(nFlyBottom, nTableTop);
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testEndnoteAtSectionEnd)
+{
+// Given a document with at-section-end endnotes enabled:
+loadFromFile(u"endnote-at-section-end.docx");
+
+// Go to the second paragraph, which is inside Word's second section:
+uno::Reference xTextDocument(mxComponent, 
uno::UNO_QUERY);
+uno::Reference 
xParaEnumAccess(xTextDocument->getText(),
+  
uno::UNO_QUERY);
+uno::Reference xParaEnum = 
xParaEnumAccess->createEnumeration();
+xParaEnum->nextElement();
+uno::Reference xPara(xParaEnum->nextElement(), 
uno::UNO_QUERY);
+uno::Reference xSection;
+xPara->getPropertyValue("TextSection") >>= xSection;
+bool bEndnoteIsCollectAtTextEnd = false;
+xSection->getPropertyValue("EndnoteIsCollectAtTextEnd") >>= 
bEndnoteIsCollectAtTextEnd;
+// Without the accompanying fix in place, this test would have failed, 
endnotes were always at
+// document end.
+CPPUNIT_ASSERT(bEndnoteIsCollectAtTextEnd);
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/writerfilter/dmapper/data/endnote-at-section-end.docx 
b/sw/qa/writerfilter/dmapper/data/endnote-at-section-end.docx
new file mode 100644
index ..cf61262c7d59
Binary files /dev/null and 
b/sw/qa/writerfilter/dmapper/data/endnote-at-section-end.docx differ
diff --git a/sw/source/writerfilter/dmapper/PropertyMap.cxx 
b/sw/source/writerfilter/dmapper/PropertyMap.cxx
index f52d37764402..02951c73cbcd 100644
--- a/sw/source/writerfilter/dmapper/PropertyMap.cxx
+++ b/sw/source/writerfilter/dmapper/PropertyMap.cxx
@@ -74,6 +74,8 @@
 #include 
 #include 
 
+#include 
+
 using namespace com::sun::star;
 
 namespace writerfilter::dmapper {
@@ -756,7 +758,7 @@ void SectionPropertyMap::DontBalanceTextColumns()
 }
 }
 
-void SectionPropertyMap::ApplySectionProperties( const uno::Reference< 
beans::XPropertySet >& xSection, DomainMapper_Impl& /*rDM_Impl*/ )
+void SectionPropertyMap::ApplySectionProperties( const uno::Reference< 
beans::XPropertySet >& xSection, DomainMapper_Impl& rDM_Impl )
 {
 try
 {
@@ -765,6 +767,11 @@ void SectionPropertyMap::ApplySectionProperties( const 
uno::Reference< beans::XP
 std::optional< PropertyMap::Property > pProp = getProperty( 
PROP_WRITING_MODE );
 if ( pProp )
 xSection->setPropertyValue( "WritingMode", pProp->second );
+
+if (rDM_Impl.GetSettingsTable()->GetEndnoteIsCollectAtSectionEnd())
+{
+
xSection->setPropertyValue(UNO_NAME_ENDNOTE_IS_COLLECT_AT_TEXT_END, 
uno::Any(true));
+}
 }
 }
 catch ( uno::Exception& )
diff --git a/sw/source/writerfilter/dmapper/SettingsTable.cxx 
b/sw/source/writerfilter/dmapper/SettingsTable.cxx
index 4d6fe6b13441..57f6566c2135 100644
--- a/sw/source/writerfilter/dmapper/SettingsTable.cxx
+++ b/sw/source/writerfilter/dmapper/SettingsTable.cxx
@@ -120,6 +120,8 @@ struct SettingsTable_Impl
 bool m_bGutterAtTop = false;
 bool 

core.git: sw/inc sw/source

2024-05-28 Thread Miklos Vajna (via logerrit)
 sw/inc/fmtftntx.hxx  |1 +
 sw/source/core/layout/atrfrm.cxx |8 
 2 files changed, 9 insertions(+)

New commits:
commit f4ec4f6068a1ca265dd25c479cc40c546ae9223e
Author: Miklos Vajna 
AuthorDate: Tue May 28 09:51:56 2024 +0200
Commit: Miklos Vajna 
CommitDate: Tue May 28 15:11:34 2024 +0200

sw doc model xml dump: show SwFormatEndAtTextEnd

Decides if endnotes are collected at section end or the normal doc end.
Previously only the pool item name was visible, not the value.

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

diff --git a/sw/inc/fmtftntx.hxx b/sw/inc/fmtftntx.hxx
index a5de432ccad7..16e63657abf7 100644
--- a/sw/inc/fmtftntx.hxx
+++ b/sw/inc/fmtftntx.hxx
@@ -110,6 +110,7 @@ public:
 }
 
 virtual SwFormatEndAtTextEnd* Clone( SfxItemPool *pPool = nullptr ) const 
override;
+void dumpAsXml(xmlTextWriterPtr pWriter) const override;
 };
 
 inline const SwFormatFootnoteAtTextEnd ::GetFootnoteAtTextEnd(bool 
bInP) const
diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx
index 67047d7b0bf9..0dee2d60520f 100644
--- a/sw/source/core/layout/atrfrm.cxx
+++ b/sw/source/core/layout/atrfrm.cxx
@@ -1993,6 +1993,14 @@ SwFormatEditInReadonly* SwFormatEditInReadonly::Clone( 
SfxItemPool* ) const
 return new SwFormatEditInReadonly( *this );
 }
 
+void SwFormatEndAtTextEnd::dumpAsXml(xmlTextWriterPtr pWriter) const
+{
+(void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatEndAtTextEnd"));
+(void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), 
BAD_CAST(OString::number(Which()).getStr()));
+(void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), 
BAD_CAST(OString::number(GetValue()).getStr()));
+(void)xmlTextWriterEndElement(pWriter);
+}
+
 SwFormatLayoutSplit* SwFormatLayoutSplit::Clone( SfxItemPool* ) const
 {
 return new SwFormatLayoutSplit( *this );


core.git: sw/source

2024-05-27 Thread Miklos Vajna (via logerrit)
 sw/source/core/txtnode/thints.cxx  |4 ++--
 sw/source/core/unocore/unoportenum.cxx |2 +-
 sw/source/core/unocore/unotext.cxx |4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

New commits:
commit 350a2dfa74bbc9d82f6555c0f3d679b6c53fe353
Author: Miklos Vajna 
AuthorDate: Mon May 27 11:05:37 2024 +0200
Commit: Miklos Vajna 
CommitDate: Tue May 28 00:21:50 2024 +0200

sw: rename SwIndexes to SwContentIndexes in comments

Leftover from commit 9fdb06d65a8f2c3401392bffee9c4639e178aada (rename
SwIndex->SwContentIndex, 2022-07-25).

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

diff --git a/sw/source/core/txtnode/thints.cxx 
b/sw/source/core/txtnode/thints.cxx
index 5da054405ef5..729a5443b03b 100644
--- a/sw/source/core/txtnode/thints.cxx
+++ b/sw/source/core/txtnode/thints.cxx
@@ -1421,7 +1421,7 @@ bool SwTextNode::InsertHint( SwTextAttr * const pAttr, 
const SetAttrMode nMode )
 assert(CH_TXTATR_BREAKWORD == 
m_Text[pAttr->GetStart()]
 || CH_TXTATR_INWORD == 
m_Text[pAttr->GetStart()]);
 m_Text = m_Text.replaceAt(pAttr->GetStart(), 1, 
u"");
-// Update SwIndexes
+// Update SwContentIndexes
 SwContentIndex aTmpIdx( this, pAttr->GetStart() );
 Update(aTmpIdx, 1, UpdateMode::Negative);
 }
@@ -1461,7 +1461,7 @@ bool SwTextNode::InsertHint( SwTextAttr * const pAttr, 
const SetAttrMode nMode )
 assert(CH_TXTATR_BREAKWORD == m_Text[pAttr->GetStart()]
 || CH_TXTATR_INWORD == m_Text[pAttr->GetStart()]);
 m_Text = m_Text.replaceAt(pAttr->GetStart(), 1, u"");
-// Update SwIndexes
+// Update SwContentIndexes
 SwContentIndex aTmpIdx( this, pAttr->GetStart() );
 Update(aTmpIdx, 1, UpdateMode::Negative);
 }
diff --git a/sw/source/core/unocore/unoportenum.cxx 
b/sw/source/core/unocore/unoportenum.cxx
index 58657677429c..d975f3c20960 100644
--- a/sw/source/core/unocore/unoportenum.cxx
+++ b/sw/source/core/unocore/unoportenum.cxx
@@ -200,7 +200,7 @@ namespace
 
 SwTextNode* pTextNode = rUnoCursor.GetPoint()->GetNode().GetTextNode();
 assert(pTextNode);
-// A text node already knows its marks via its SwIndexes.
+// A text node already knows its marks via its SwContentIndexes.
 o3tl::sorted_vector aSeenMarks;
 for (const SwContentIndex* pIndex = pTextNode->GetFirstIndex(); 
pIndex; pIndex = pIndex->GetNext())
 {
diff --git a/sw/source/core/unocore/unotext.cxx 
b/sw/source/core/unocore/unotext.cxx
index 39b2016335ba..fd2811f05743 100644
--- a/sw/source/core/unocore/unotext.cxx
+++ b/sw/source/core/unocore/unotext.cxx
@@ -1664,7 +1664,7 @@ SwXText::convertToTextFrame(
 xNewFrame->SwXFrame::setPropertyValue(rValue.Name, rValue.Value);
 }
 
-{   // has to be in a block to remove the SwIndexes before
+{   // has to be in a block to remove the SwContentIndexes before
 // DelFullPara is called
 const uno::Reference< text::XTextRange> xInsertTextRange =
 new SwXTextRange(*pStartPam, this);
@@ -1677,7 +1677,7 @@ SwXText::convertToTextFrame(
 assert(pTextNode);
 if (!pTextNode || !pTextNode->Len()) // don't remove if it contains 
text!
 {
-{   // has to be in a block to remove the SwIndexes before
+{   // has to be in a block to remove the SwContentIndexes before
 // DelFullPara is called
 SwPaM aMovePam( pStartPam->GetPointNode() );
 if (aMovePam.Move( fnMoveForward, GoInContent ))


core.git: Branch 'distro/collabora/co-24.04' - sw/qa sw/source

2024-05-27 Thread Miklos Vajna (via logerrit)
 sw/qa/core/layout/data/inline-endnote-section-delete.docx |binary
 sw/qa/core/layout/ftnfrm.cxx  |   31 ++
 sw/source/core/layout/ftnfrm.cxx  |4 +
 3 files changed, 34 insertions(+), 1 deletion(-)

New commits:
commit ba0f1432e2162d32103e20d2030cf79b3dd4e2f7
Author: Miklos Vajna 
AuthorDate: Mon May 27 09:41:18 2024 +0200
Commit: Caolán McNamara 
CommitDate: Mon May 27 14:31:05 2024 +0200

tdf#160984 sw continuous endnotes: fix crash on loading 
forum-mso-en-7731.docx

Regression from commit 1ae5ea3f78cca11ba18f2dd1a06f875263336a3b
(tdf#160984 sw continuous endnotes: enable DOCX import, 2024-05-21), the
bugdoc crashed in SwSectionFrame::GetEndSectFormat_().

What seems to happen is that the first endnote is added to page 1, then
more content is inserted, so the endnote is moved to page 2, which
leaves an empty endnote section on page 1, which is marked for deletion
in SwSectionFrame::MakeAll(), and will be deleted in
SwRootFrame::DeleteEmptySct_(). At some point (after marking for
deletion, before deletion) SwFootnoteBossFrame::AppendFootnote() tries
to find the first endnote section in the layout, and finds this section,
but it crashes because there is no SwSection attached to it, as marking
for deletion in SwSectionFrame::DelEmpty() clears that.

Fix the problem by ignoring to-be-deleted sections in
SwFootnoteBossFrame::AppendFootnote(): this way a new, usable section
will be created and the to-be-deleted section go away as the layout
finishes.

An alternative would be to check for SwSectionFrame::GetSection()
earlier, as we iterate on pages (hoping that this way we find a later
page that has a not-dead endnote section), but that leads to 6 pages
instead of 4 pages for the bugdoc, so don't go that way.

(cherry picked from commit 3f2d0414686a8f9a042413c47c4c8ffa5d61f436)

Change-Id: I9a21cbccb5a088314520c7ade55dbdf9966d1265
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168099
Tested-by: Jenkins CollaboraOffice 
Reviewed-by: Caolán McNamara 

diff --git a/sw/qa/core/layout/data/inline-endnote-section-delete.docx 
b/sw/qa/core/layout/data/inline-endnote-section-delete.docx
new file mode 100644
index ..bf3d3e60d890
Binary files /dev/null and 
b/sw/qa/core/layout/data/inline-endnote-section-delete.docx differ
diff --git a/sw/qa/core/layout/ftnfrm.cxx b/sw/qa/core/layout/ftnfrm.cxx
index a7640e26ca9a..98387be6a983 100644
--- a/sw/qa/core/layout/ftnfrm.cxx
+++ b/sw/qa/core/layout/ftnfrm.cxx
@@ -17,6 +17,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 /// Covers sw/source/core/layout/ftnfrm.cxx fixes.
 class Test : public SwModelTestBase
@@ -122,4 +124,33 @@ CPPUNIT_TEST_FIXTURE(Test, testInlineEndnotePosition)
 CPPUNIT_ASSERT_EQUAL(static_cast(269), nEndnoteContTopMargin);
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteSectionDelete)
+{
+// Given a document, ContinuousEndnotes is true, 3 pages, endnodes start 
on page 2:
+// When laying out that document:
+createSwDoc("inline-endnote-section-delete.docx");
+
+// First page: just body text:
+SwDoc* pDoc = getSwDoc();
+SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+auto pPage = pLayout->Lower()->DynCastPageFrame();
+CPPUNIT_ASSERT(pPage->GetLower()->IsBodyFrame());
+auto pBodyFrame = static_cast(pPage->GetLower());
+CPPUNIT_ASSERT(!pBodyFrame->GetLastLower()->IsSctFrame());
+// Second page: ends with endnotes:
+pPage = pPage->GetNext()->DynCastPageFrame();
+CPPUNIT_ASSERT(pPage->GetLower()->IsBodyFrame());
+pBodyFrame = static_cast(pPage->GetLower());
+CPPUNIT_ASSERT(pBodyFrame->GetLastLower()->IsSctFrame());
+auto pSection = static_cast(pBodyFrame->GetLastLower());
+CPPUNIT_ASSERT(pSection->IsEndNoteSection());
+// Third page: just endnotes:
+pPage = pPage->GetNext()->DynCastPageFrame();
+CPPUNIT_ASSERT(pPage->GetLower()->IsBodyFrame());
+pBodyFrame = static_cast(pPage->GetLower());
+CPPUNIT_ASSERT(pBodyFrame->GetLower()->IsSctFrame());
+pSection = static_cast(pBodyFrame->GetLower());
+CPPUNIT_ASSERT(pSection->IsEndNoteSection());
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/ftnfrm.cxx b/sw/source/core/layout/ftnfrm.cxx
index 46312f9f4e89..1c6b221cf511 100644
--- a/sw/source/core/layout/ftnfrm.cxx
+++ b/sw/source/core/layout/ftnfrm.cxx
@@ -1601,7 +1601,9 @@ void SwFootnoteBossFrame::AppendFootnote( SwContentFrame 
*pRef, SwTextFootnote *
 pEndnoteSection = pPage->GetEndNoteSection();
 }
 // If there are no endnotes sections yet, create one at the end of 
the document.
-if (!pEndnoteSection)
+// Ignore sections which are already marked for deletion, they 
don't have an SwSection
+   

core.git: Branch 'distro/collabora/co-24.04' - sw/qa sw/source

2024-05-27 Thread Miklos Vajna (via logerrit)
 sw/qa/core/layout/paintfrm.cxx |   10 ++
 sw/source/core/layout/paintfrm.cxx |9 -
 2 files changed, 18 insertions(+), 1 deletion(-)

New commits:
commit 69bbd6378ed7a7b7765948d5ec08673866947d5d
Author: Miklos Vajna 
AuthorDate: Fri May 24 10:51:31 2024 +0200
Commit: Caolán McNamara 
CommitDate: Mon May 27 14:30:44 2024 +0200

tdf#160984 sw continuous endnotes: fix the endnote separator length

See
,
Word has a longer separator line for the foot/endnote than Writer for
this bugdoc.

Writer defaults to 25% of the body frame width in the SwPageFootnoteInfo
ctor, and we don't seem to change that in the DOCX import. Word has a
static 2 inches setting, which is only reduced if it would go outside
the body frame.

Fix the problem by extending SwFootnoteContFrame::PaintLine() in the
DocumentSettingId::CONTINUOUS_ENDNOTES case to do the same.

I searched the OOXML spec and the MS implementer notes, they don't
specify this 2 inches length, but it seems static: the value doesn't
change with the page size. With this, the single-section bugdoc is now
rendered fine.

(cherry picked from commit 755f3bebd96ec7ae43b1dcf247f907b9c15c1995)

Change-Id: I3bb23680937580179b8d37c940ea14e0f80fc7f4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168088
Reviewed-by: Caolán McNamara 
Tested-by: Jenkins CollaboraOffice 

diff --git a/sw/qa/core/layout/paintfrm.cxx b/sw/qa/core/layout/paintfrm.cxx
index 8e7154db2501..a5213c57d639 100644
--- a/sw/qa/core/layout/paintfrm.cxx
+++ b/sw/qa/core/layout/paintfrm.cxx
@@ -177,6 +177,16 @@ CPPUNIT_TEST_FIXTURE(Test, 
testInlineEndnoteSeparatorPosition)
 // - Actual  : 2060
 // i.e. the upper spacing was too low.
 CPPUNIT_ASSERT_EQUAL(static_cast(2164), nEndnoteSeparatorY);
+
+// Also make sure the separator length is correct:
+auto nEndnoteSeparatorStart = getXPath(pXmlDoc, "//polygon/point[1]"_ostr, 
"x"_ostr).toInt32();
+auto nEndnoteSeparatorEnd = getXPath(pXmlDoc, "//polygon/point[2]"_ostr, 
"x"_ostr).toInt32();
+sal_Int32 nEndnoteSeparatorLength = nEndnoteSeparatorEnd - 
nEndnoteSeparatorStart;
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected: 2880
+// - Actual  : 2340
+// i.e. the separator wasn't 2 inches long, but was shorter vs Word.
+CPPUNIT_ASSERT_EQUAL(static_cast(2880), 
nEndnoteSeparatorLength);
 }
 }
 
diff --git a/sw/source/core/layout/paintfrm.cxx 
b/sw/source/core/layout/paintfrm.cxx
index b45226bbbcb6..89ea71f9acb7 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -5777,7 +5777,7 @@ void SwFootnoteContFrame::PaintLine( const SwRect& rRect,
 SwTwips nPrtWidth = aRectFnSet.GetWidth(getFramePrintArea());
 Fraction aFract( nPrtWidth, 1 );
 aFract *= rInf.GetWidth();
-const SwTwips nWidth = static_cast(aFract);
+SwTwips nWidth = static_cast(aFract);
 
 SwTwips nX = aRectFnSet.GetPrtLeft(*this);
 switch ( rInf.GetAdj() )
@@ -5808,6 +5808,13 @@ void SwFootnoteContFrame::PaintLine( const SwRect& rRect,
 // Word style: instead of fixed value, upper spacing is 60% of all 
space.
 auto nPrintAreaTop = 
static_cast(getFramePrintArea().Top());
 aPoint.setY(getFrameArea().Pos().Y() + nPrintAreaTop * 0.6);
+
+// Length is 2 inches, but don't paint outside the container frame.
+nWidth = o3tl::convert(2, o3tl::Length::in, o3tl::Length::twip);
+if (nWidth > nPrtWidth)
+{
+nWidth = nPrtWidth;
+}
 }
 oLineRect.emplace(aPoint, Size(nWidth, rInf.GetLineWidth()));
 }


core.git: Branch 'distro/collabora/co-24.04' - sw/qa sw/source

2024-05-27 Thread Miklos Vajna (via logerrit)
 sw/qa/core/layout/paintfrm.cxx |   20 
 sw/source/core/layout/paintfrm.cxx |   27 ---
 2 files changed, 40 insertions(+), 7 deletions(-)

New commits:
commit 461447cfdca85298435b0e029b1c1418789618ad
Author: Miklos Vajna 
AuthorDate: Thu May 23 15:31:05 2024 +0200
Commit: Caolán McNamara 
CommitDate: Mon May 27 14:30:26 2024 +0200

tdf#160984 sw continuous endnotes: fix the endnote separator position

See , the
total height of the endnote separator is now correct, but the
distribution of upper space, line width, lower space is still bad, when
compared to Word.

Our model is 2 spacings and a line width, while Word seems to simply
split the amount of available space: 60% goes above the separator and
the rest goes below.

Fix the problem by breaking up the monster expression for the separator
rectangle in SwFootnoteContFrame::PaintLine(), and then the compat +
horizontal case can do the 60% spacing in the Word compat mode.

The width of the separator is still not correct.

(cherry picked from commit f1d0b4e34a1f467e9f54baa7ac31ca28fdae3efb)

Change-Id: Ic065c138041892225b3c1b7d4bd64d4f1c625611
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168007
Tested-by: Jenkins CollaboraOffice 
Reviewed-by: Caolán McNamara 

diff --git a/sw/qa/core/layout/paintfrm.cxx b/sw/qa/core/layout/paintfrm.cxx
index b5990648b20f..8e7154db2501 100644
--- a/sw/qa/core/layout/paintfrm.cxx
+++ b/sw/qa/core/layout/paintfrm.cxx
@@ -158,6 +158,26 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitTableMergedBorder)
 // bottom border.
 CPPUNIT_ASSERT_EQUAL(static_cast(2), aHorizontalBorderEnds.size());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteSeparatorPosition)
+{
+// Given a document with a Word-style endnote separator:
+createSwDoc("inline-endnote-position.docx");
+SwDocShell* pDocShell = getSwDocShell();
+
+// When rendering that document:
+std::shared_ptr xMetaFile = pDocShell->GetPreviewMetaFile();
+
+// Then make sure the separator upper spacing is 60% of all space, 
matching Word:
+MetafileXmlDump aDumper;
+xmlDocUniquePtr pXmlDoc = dumpAndParse(aDumper, *xMetaFile);
+auto nEndnoteSeparatorY = getXPath(pXmlDoc, "//polygon/point[1]"_ostr, 
"y"_ostr).toInt32();
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected: 2164
+// - Actual  : 2060
+// i.e. the upper spacing was too low.
+CPPUNIT_ASSERT_EQUAL(static_cast(2164), nEndnoteSeparatorY);
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/paintfrm.cxx 
b/sw/source/core/layout/paintfrm.cxx
index ff5abcfcf898..b45226bbbcb6 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -5793,13 +5793,26 @@ void SwFootnoteContFrame::PaintLine( const SwRect& 
rRect,
 assert(false);
 }
 SwTwips nLineWidth = rInf.GetLineWidth();
-const SwRect aLineRect = aRectFnSet.IsVert() ?
-SwRect( 
Point(getFrameArea().Left()+getFrameArea().Width()-rInf.GetTopDist()-nLineWidth,
-  nX), Size( nLineWidth, nWidth ) )
-: SwRect( Point( nX, getFrameArea().Pos().Y() + rInf.GetTopDist() 
),
-Size( nWidth, rInf.GetLineWidth()));
-if ( aLineRect.HasArea() && rInf.GetLineStyle() != 
SvxBorderLineStyle::NONE)
-PaintBorderLine( rRect, aLineRect , pPage, (),
+std::optional oLineRect;
+if (aRectFnSet.IsVert())
+{
+
oLineRect.emplace(Point(getFrameArea().Left()+getFrameArea().Width()-rInf.GetTopDist()-nLineWidth,
+  nX), Size( nLineWidth, nWidth ) );
+}
+else
+{
+Point aPoint(nX, getFrameArea().Pos().Y() + rInf.GetTopDist());
+const IDocumentSettingAccess& rIDSA = 
GetFormat()->getIDocumentSettingAccess();
+if (rIDSA.get(DocumentSettingId::CONTINUOUS_ENDNOTES))
+{
+// Word style: instead of fixed value, upper spacing is 60% of all 
space.
+auto nPrintAreaTop = 
static_cast(getFramePrintArea().Top());
+aPoint.setY(getFrameArea().Pos().Y() + nPrintAreaTop * 0.6);
+}
+oLineRect.emplace(aPoint, Size(nWidth, rInf.GetLineWidth()));
+}
+if ( oLineRect->HasArea() && rInf.GetLineStyle() != 
SvxBorderLineStyle::NONE)
+PaintBorderLine( rRect, *oLineRect , pPage, (),
 rInf.GetLineStyle() );
 }
 


core.git: sw/qa sw/source

2024-05-27 Thread Miklos Vajna (via logerrit)
 sw/qa/core/layout/data/inline-endnote-section-delete.docx |binary
 sw/qa/core/layout/ftnfrm.cxx  |   31 ++
 sw/source/core/layout/ftnfrm.cxx  |4 +
 3 files changed, 34 insertions(+), 1 deletion(-)

New commits:
commit 3f2d0414686a8f9a042413c47c4c8ffa5d61f436
Author: Miklos Vajna 
AuthorDate: Mon May 27 09:41:18 2024 +0200
Commit: Miklos Vajna 
CommitDate: Mon May 27 11:27:34 2024 +0200

tdf#160984 sw continuous endnotes: fix crash on loading 
forum-mso-en-7731.docx

Regression from commit 1ae5ea3f78cca11ba18f2dd1a06f875263336a3b
(tdf#160984 sw continuous endnotes: enable DOCX import, 2024-05-21), the
bugdoc crashed in SwSectionFrame::GetEndSectFormat_().

What seems to happen is that the first endnote is added to page 1, then
more content is inserted, so the endnote is moved to page 2, which
leaves an empty endnote section on page 1, which is marked for deletion
in SwSectionFrame::MakeAll(), and will be deleted in
SwRootFrame::DeleteEmptySct_(). At some point (after marking for
deletion, before deletion) SwFootnoteBossFrame::AppendFootnote() tries
to find the first endnote section in the layout, and finds this section,
but it crashes because there is no SwSection attached to it, as marking
for deletion in SwSectionFrame::DelEmpty() clears that.

Fix the problem by ignoring to-be-deleted sections in
SwFootnoteBossFrame::AppendFootnote(): this way a new, usable section
will be created and the to-be-deleted section go away as the layout
finishes.

An alternative would be to check for SwSectionFrame::GetSection()
earlier, as we iterate on pages (hoping that this way we find a later
page that has a not-dead endnote section), but that leads to 6 pages
instead of 4 pages for the bugdoc, so don't go that way.

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

diff --git a/sw/qa/core/layout/data/inline-endnote-section-delete.docx 
b/sw/qa/core/layout/data/inline-endnote-section-delete.docx
new file mode 100644
index ..bf3d3e60d890
Binary files /dev/null and 
b/sw/qa/core/layout/data/inline-endnote-section-delete.docx differ
diff --git a/sw/qa/core/layout/ftnfrm.cxx b/sw/qa/core/layout/ftnfrm.cxx
index a7640e26ca9a..98387be6a983 100644
--- a/sw/qa/core/layout/ftnfrm.cxx
+++ b/sw/qa/core/layout/ftnfrm.cxx
@@ -17,6 +17,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 /// Covers sw/source/core/layout/ftnfrm.cxx fixes.
 class Test : public SwModelTestBase
@@ -122,4 +124,33 @@ CPPUNIT_TEST_FIXTURE(Test, testInlineEndnotePosition)
 CPPUNIT_ASSERT_EQUAL(static_cast(269), nEndnoteContTopMargin);
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteSectionDelete)
+{
+// Given a document, ContinuousEndnotes is true, 3 pages, endnodes start 
on page 2:
+// When laying out that document:
+createSwDoc("inline-endnote-section-delete.docx");
+
+// First page: just body text:
+SwDoc* pDoc = getSwDoc();
+SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+auto pPage = pLayout->Lower()->DynCastPageFrame();
+CPPUNIT_ASSERT(pPage->GetLower()->IsBodyFrame());
+auto pBodyFrame = static_cast(pPage->GetLower());
+CPPUNIT_ASSERT(!pBodyFrame->GetLastLower()->IsSctFrame());
+// Second page: ends with endnotes:
+pPage = pPage->GetNext()->DynCastPageFrame();
+CPPUNIT_ASSERT(pPage->GetLower()->IsBodyFrame());
+pBodyFrame = static_cast(pPage->GetLower());
+CPPUNIT_ASSERT(pBodyFrame->GetLastLower()->IsSctFrame());
+auto pSection = static_cast(pBodyFrame->GetLastLower());
+CPPUNIT_ASSERT(pSection->IsEndNoteSection());
+// Third page: just endnotes:
+pPage = pPage->GetNext()->DynCastPageFrame();
+CPPUNIT_ASSERT(pPage->GetLower()->IsBodyFrame());
+pBodyFrame = static_cast(pPage->GetLower());
+CPPUNIT_ASSERT(pBodyFrame->GetLower()->IsSctFrame());
+pSection = static_cast(pBodyFrame->GetLower());
+CPPUNIT_ASSERT(pSection->IsEndNoteSection());
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/ftnfrm.cxx b/sw/source/core/layout/ftnfrm.cxx
index 548d8228063e..bb35d1c1025c 100644
--- a/sw/source/core/layout/ftnfrm.cxx
+++ b/sw/source/core/layout/ftnfrm.cxx
@@ -1626,7 +1626,9 @@ void SwFootnoteBossFrame::AppendFootnote( SwContentFrame 
*pRef, SwTextFootnote *
 pEndnoteSection = pPage->GetEndNoteSection();
 }
 // If there are no endnotes sections yet, create one at the end of 
the document.
-if (!pEndnoteSection)
+// Ignore sections which are already marked for deletion, they 
don't have an SwSection
+// anymore, so not usable for us.
+if (!pEndnoteSection || 

core.git: include/svx svx/source

2024-05-27 Thread Miklos Vajna (via logerrit)
 include/svx/fmview.hxx |   10 ++--
 svx/source/form/fmview.cxx |  106 ++---
 2 files changed, 58 insertions(+), 58 deletions(-)

New commits:
commit 2ef33247b7a3c07dde18d3cd6fd989fcb8ea4ddc
Author: Miklos Vajna 
AuthorDate: Mon May 27 08:11:33 2024 +0200
Commit: Miklos Vajna 
CommitDate: Mon May 27 10:45:40 2024 +0200

svx: prefix members of FmFormView

See tdf#94879 for motivation.

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

diff --git a/include/svx/fmview.hxx b/include/svx/fmview.hxx
index a1a08de5e56b..e601047eff00 100644
--- a/include/svx/fmview.hxx
+++ b/include/svx/fmview.hxx
@@ -53,8 +53,8 @@ namespace com::sun::star::form {
 
 class SVXCORE_DLLPUBLIC FmFormView : public E3dView
 {
-rtl::Reference pImpl;
-FmFormShell*pFormShell;
+rtl::Reference m_pImpl;
+FmFormShell*m_pFormShell;
 
 void Init();
 
@@ -128,11 +128,11 @@ public:
 
 SVX_DLLPRIVATE void ChangeDesignMode(bool bDesign);
 
-SVX_DLLPRIVATE FmXFormView* GetImpl() const { return pImpl.get(); }
-SVX_DLLPRIVATE FmFormShell* GetFormShell() const { return pFormShell; }
+SVX_DLLPRIVATE FmXFormView* GetImpl() const { return m_pImpl.get(); }
+SVX_DLLPRIVATE FmFormShell* GetFormShell() const { return m_pFormShell; }
 
 struct FormShellAccess { friend class FmFormShell; private: 
FormShellAccess() { } };
- void SetFormShell( FmFormShell* pShell, FormShellAccess ) { pFormShell = 
pShell; }
+ void SetFormShell( FmFormShell* pShell, FormShellAccess ) { m_pFormShell 
= pShell; }
 
 struct ImplAccess { friend class FmXFormView; private: ImplAccess() { } };
 void SetMoveOutside( bool _bMoveOutside, ImplAccess ) { 
E3dView::SetMoveOutside( _bMoveOutside ); }
diff --git a/svx/source/form/fmview.cxx b/svx/source/form/fmview.cxx
index 2a07073d66b9..a26895653833 100644
--- a/svx/source/form/fmview.cxx
+++ b/svx/source/form/fmview.cxx
@@ -72,8 +72,8 @@ FmFormView::FmFormView(
 
 void FmFormView::Init()
 {
-pFormShell = nullptr;
-pImpl = new FmXFormView(this);
+m_pFormShell = nullptr;
+m_pImpl = new FmXFormView(this);
 
 // set model
 SdrModel* pModel = ();
@@ -114,10 +114,10 @@ void FmFormView::Init()
 
 FmFormView::~FmFormView()
 {
-if (pFormShell)
-suppress_fun_call_w_exception(pFormShell->SetView(nullptr));
+if (m_pFormShell)
+suppress_fun_call_w_exception(m_pFormShell->SetView(nullptr));
 
-pImpl->notifyViewDying();
+m_pImpl->notifyViewDying();
 }
 
 FmFormPage* FmFormView::GetCurPage()
@@ -131,23 +131,23 @@ void FmFormView::MarkListHasChanged()
 {
 E3dView::MarkListHasChanged();
 
-if ( !(pFormShell && IsDesignMode()) )
+if ( !(m_pFormShell && IsDesignMode()) )
 return;
 
 FmFormObj* pObj = getMarkedGrid();
-if ( pImpl->m_pMarkedGrid && pImpl->m_pMarkedGrid != pObj )
+if ( m_pImpl->m_pMarkedGrid && m_pImpl->m_pMarkedGrid != pObj )
 {
-pImpl->m_pMarkedGrid = nullptr;
-if ( pImpl->m_xWindow.is() )
+m_pImpl->m_pMarkedGrid = nullptr;
+if ( m_pImpl->m_xWindow.is() )
 {
-pImpl->m_xWindow->removeFocusListener(pImpl);
-pImpl->m_xWindow = nullptr;
+m_pImpl->m_xWindow->removeFocusListener(m_pImpl);
+m_pImpl->m_xWindow = nullptr;
 }
 SetMoveOutside(false);
 //OLMRefreshAllIAOManagers();
 }
 
-pFormShell->GetImpl()->SetSelectionDelayed_Lock();
+m_pFormShell->GetImpl()->SetSelectionDelayed_Lock();
 }
 
 namespace
@@ -179,7 +179,7 @@ void FmFormView::AddDeviceToPaintView(OutputDevice& 
rNewDev, vcl::Window* pWindo
 // #i39269# / 2004-12-20 / frank.schoenh...@sun.com
 const SdrPageWindow* pPageWindow = findPageWindow( this,  );
 if ( pPageWindow )
-pImpl->addWindow( *pPageWindow );
+m_pImpl->addWindow( *pPageWindow );
 }
 
 
@@ -187,7 +187,7 @@ void FmFormView::DeleteDeviceFromPaintView(OutputDevice& 
rNewDev)
 {
 const SdrPageWindow* pPageWindow = findPageWindow( this,  );
 if ( pPageWindow )
-pImpl->removeWindow( pPageWindow->GetControlContainer() );
+m_pImpl->removeWindow( pPageWindow->GetControlContainer() );
 
 E3dView::DeleteDeviceFromPaintView(rNewDev);
 }
@@ -211,10 +211,10 @@ void FmFormView::ChangeDesignMode(bool bDesign)
 DeactivateControls( GetSdrPageView() );
 
 // --- 2. simulate a deactivation (the shell will handle some things there 
...?)
-if ( pFormShell && pFormShell->GetImpl() )
-pFormShell->GetImpl()->viewDeactivated_Lock(*this);
+if ( m_pFormShell && m_pFormShell->GetImpl() )
+m_pFormShell->GetImpl()->viewDeactivated_Lock(*this);
 else
-pImpl->Deactivate();
+m_pImpl->Deactivate();
 
 // --- 3. activate all controls, if we're switching to alive mode
 if ( 

core.git: sw/CppunitTest_sw_writerfilter_dmapper.mk sw/CppunitTest_sw_writerfilter_filter.mk sw/CppunitTest_sw_writerfilter_filters_test.mk sw/CppunitTest_sw_writerfilter_misc.mk sw/CppunitTest_sw_wri

2024-05-24 Thread Miklos Vajna (via logerrit)
 sw/CppunitTest_sw_writerfilter_dmapper.mk   |   22 
 sw/CppunitTest_sw_writerfilter_filter.mk|2 -
 sw/CppunitTest_sw_writerfilter_filters_test.mk  |2 -
 sw/CppunitTest_sw_writerfilter_misc.mk  |2 -
 sw/CppunitTest_sw_writerfilter_ooxml.mk |2 -
 sw/CppunitTest_sw_writerfilter_rtftok.mk|   14 +-
 sw/qa/writerfilter/dmapper/CellColorHandler.cxx |2 -
 sw/qa/writerfilter/dmapper/DomainMapper.cxx |2 -
 sw/qa/writerfilter/dmapper/DomainMapperTableHandler.cxx |2 -
 sw/qa/writerfilter/dmapper/DomainMapperTableManager.cxx |2 -
 sw/qa/writerfilter/dmapper/DomainMapper_Impl.cxx|2 -
 sw/qa/writerfilter/dmapper/GraphicImport.cxx|2 -
 sw/qa/writerfilter/dmapper/PropertyMap.cxx  |2 -
 sw/qa/writerfilter/dmapper/SdtHelper.cxx|2 -
 sw/qa/writerfilter/dmapper/SettingsTable.cxx|2 -
 sw/qa/writerfilter/dmapper/TableManager.cxx |2 -
 sw/qa/writerfilter/dmapper/TextEffectsHandler.cxx   |2 -
 sw/qa/writerfilter/filter/WriterFilter.cxx  |2 -
 sw/qa/writerfilter/filters-test/filters-test.cxx|3 --
 sw/qa/writerfilter/ooxml/ooxml.cxx  |2 -
 sw/qa/writerfilter/rtftok/rtfdispatchflag.cxx   |2 -
 sw/qa/writerfilter/rtftok/rtfdispatchsymbol.cxx |2 -
 sw/qa/writerfilter/rtftok/rtfdispatchvalue.cxx  |2 -
 sw/qa/writerfilter/rtftok/rtfdocumentimpl.cxx   |2 -
 sw/qa/writerfilter/rtftok/rtfsdrimport.cxx  |2 -
 sw/qa/writerfilter/rtftok/rtfsprm.cxx   |2 -
 sw/qa/writerfilter/rtftok/rtftokenizer.cxx  |2 -
 27 files changed, 43 insertions(+), 44 deletions(-)

New commits:
commit 8112883acf0015066f21dece7e1109dbda3e4cae
Author: Miklos Vajna 
AuthorDate: Fri May 24 16:07:55 2024 +0200
Commit: Miklos Vajna 
CommitDate: Fri May 24 17:34:09 2024 +0200

sw qa: rename writerfilter/cppunittests to just writerfilter

15:47  noelgrandin: any objections to go further with your 
writerfilter rename and turn sw/qa/writerfilter/cppunittests/* into 
sw/qa/writerfilter/* ? (suggest to either do it now or not at all if we're past 
the libreoffice-24-8 branch-off)
15:59  vmiklos, not at all, go for it

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

diff --git a/sw/CppunitTest_sw_writerfilter_dmapper.mk 
b/sw/CppunitTest_sw_writerfilter_dmapper.mk
index ecae5cf7db7e..d865706c2b50 100644
--- a/sw/CppunitTest_sw_writerfilter_dmapper.mk
+++ b/sw/CppunitTest_sw_writerfilter_dmapper.mk
@@ -17,17 +17,17 @@ $(eval $(call 
gb_CppunitTest_use_externals,sw_writerfilter_dmapper,\
 ))
 
 $(eval $(call gb_CppunitTest_add_exception_objects,sw_writerfilter_dmapper, \
-sw/qa/writerfilter/cppunittests/dmapper/CellColorHandler \
-sw/qa/writerfilter/cppunittests/dmapper/DomainMapperTableHandler \
-sw/qa/writerfilter/cppunittests/dmapper/DomainMapperTableManager \
-sw/qa/writerfilter/cppunittests/dmapper/DomainMapper \
-sw/qa/writerfilter/cppunittests/dmapper/DomainMapper_Impl \
-sw/qa/writerfilter/cppunittests/dmapper/GraphicImport \
-sw/qa/writerfilter/cppunittests/dmapper/TableManager \
-sw/qa/writerfilter/cppunittests/dmapper/TextEffectsHandler \
-sw/qa/writerfilter/cppunittests/dmapper/PropertyMap \
-sw/qa/writerfilter/cppunittests/dmapper/SdtHelper \
-sw/qa/writerfilter/cppunittests/dmapper/SettingsTable \
+sw/qa/writerfilter/dmapper/CellColorHandler \
+sw/qa/writerfilter/dmapper/DomainMapperTableHandler \
+sw/qa/writerfilter/dmapper/DomainMapperTableManager \
+sw/qa/writerfilter/dmapper/DomainMapper \
+sw/qa/writerfilter/dmapper/DomainMapper_Impl \
+sw/qa/writerfilter/dmapper/GraphicImport \
+sw/qa/writerfilter/dmapper/TableManager \
+sw/qa/writerfilter/dmapper/TextEffectsHandler \
+sw/qa/writerfilter/dmapper/PropertyMap \
+sw/qa/writerfilter/dmapper/SdtHelper \
+sw/qa/writerfilter/dmapper/SettingsTable \
 ))
 
 $(eval $(call gb_CppunitTest_use_libraries,sw_writerfilter_dmapper, \
diff --git a/sw/CppunitTest_sw_writerfilter_filter.mk 
b/sw/CppunitTest_sw_writerfilter_filter.mk
index ad61c66f1ed4..e627d43d2180 100644
--- a/sw/CppunitTest_sw_writerfilter_filter.mk
+++ b/sw/CppunitTest_sw_writerfilter_filter.mk
@@ -17,7 +17,7 @@ $(eval $(call 
gb_CppunitTest_use_externals,sw_writerfilter_filter,\
 ))
 
 $(eval $(call gb_CppunitTest_add_exception_objects,sw_writerfilter_filter, \
-sw/qa/writerfilter/cppunittests/filter/WriterFilter \
+sw/qa/writerfilter/filter/WriterFilter \
 ))
 
 $(eval $(call gb_CppunitTest_use_libraries,sw_writerfilter_filter, \
diff --git a/sw/CppunitTest_sw_writerfilter_filters_test.mk 

core.git: sw/inc sw/source

2024-05-24 Thread Miklos Vajna (via logerrit)
 sw/inc/contentindex.hxx|2 +-
 sw/source/core/txtnode/ndtxt.cxx   |2 +-
 sw/source/core/unocore/unotext.cxx |4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

New commits:
commit 6de49dee825c6bd093007b4c954f97812c3fdb47
Author: Miklos Vajna 
AuthorDate: Fri May 24 13:09:36 2024 +0200
Commit: Miklos Vajna 
CommitDate: Fri May 24 14:22:07 2024 +0200

sw: rename SwIndex to SwContentIndex in comments

Leftover from commit 9fdb06d65a8f2c3401392bffee9c4639e178aada (rename
SwIndex->SwContentIndex, 2022-07-25).

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

diff --git a/sw/inc/contentindex.hxx b/sw/inc/contentindex.hxx
index 873e1512ca4f..ea54b1c052a2 100644
--- a/sw/inc/contentindex.hxx
+++ b/sw/inc/contentindex.hxx
@@ -44,7 +44,7 @@ private:
 SwContentIndex * m_pNext;
 SwContentIndex * m_pPrev;
 
-/// points to the SwRangeRedline (if any) that contains this SwIndex, via 
SwPosition and SwPaM
+/// points to the SwRangeRedline (if any) that contains this 
SwContentIndex, via SwPosition and SwPaM
 SwRangeRedline * m_pRangeRedline = nullptr;
 
 /// Pointer to a mark that owns this position to allow fast lookup of 
marks of an SwContentIndexReg.
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 34619f0c7dfb..1d71a1cd8169 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -1455,7 +1455,7 @@ void SwTextNode::Update(
 if (!(eMode & UpdateMode::Negative) && !(eMode & UpdateMode::Delete))
 {
 std::vector vMyRedlines;
-// walk the list of SwIndex attached to me and see if any of them are 
redlines
+// walk the list of SwContentIndex attached to me and see if any of 
them are redlines
 const SwContentIndex* pContentNodeIndex = GetFirstIndex();
 while (pContentNodeIndex)
 {
diff --git a/sw/source/core/unocore/unotext.cxx 
b/sw/source/core/unocore/unotext.cxx
index 50d9f75db63f..39b2016335ba 100644
--- a/sw/source/core/unocore/unotext.cxx
+++ b/sw/source/core/unocore/unotext.cxx
@@ -1579,7 +1579,7 @@ SwXText::convertToTextFrame(
 (pStartStartNode != GetStartNode()))
 {
 // if not - remove the additional paragraphs and throw
-oAnchorCheckPam.reset(); // clear SwIndex before deleting nodes
+oAnchorCheckPam.reset(); // clear SwContentIndex before deleting 
nodes
 if (bParaBeforeInserted)
 {
 SwCursor aDelete(*pStartPam->GetPoint(), nullptr);
@@ -1653,7 +1653,7 @@ SwXText::convertToTextFrame(
 }
 }
 }
-oAnchorCheckPam.reset(); // clear SwIndex before deleting nodes
+oAnchorCheckPam.reset(); // clear SwContentIndex before deleting nodes
 
 const rtl::Reference xNewFrame =
 SwXTextFrame::CreateXTextFrame(*m_pImpl->m_pDoc, nullptr);


core.git: sw/qa sw/source

2024-05-24 Thread Miklos Vajna (via logerrit)
 sw/qa/uitest/data/keep-aspect-ratio.odt |binary
 sw/qa/uitest/ui/frmdlg/frmdlg.py|   20 
 sw/source/ui/frmdlg/frmpage.cxx |6 +-
 sw/source/uibase/inc/frmpage.hxx|1 +
 4 files changed, 26 insertions(+), 1 deletion(-)

New commits:
commit a3150fc8a59662ce8630cfc64fec9cd083ac7d36
Author: Miklos Vajna 
AuthorDate: Fri May 24 12:06:55 2024 +0200
Commit: Miklos Vajna 
CommitDate: Fri May 24 13:58:07 2024 +0200

tdf#145972 sw image dialog: fix bad rel width w/ pt units and kept aspect 
ratio

Regression from commit 02c435082058ecf7f9d4d73cb47d31d0218dc10d (sw keep
aspect ratio: add filter for this setting, 2021-06-07), once UI units
are set to poins (instead of cms), the image dialog for the bugdoc was
showing 5% width instead of 48%.

48% is roughtly correct, visually the image is taking half of the body
frame width. Previously the bad rel size didn't happen because we didn't
save the "keep aspect ratio" to documents, so it was off by the time the
dialog was initialized.

Fix the problem by introducing a new flag, so we can differentiate
between the user changine the width or height vs the dialog being
initialized. RelSizeClickHdl() is meant to adjust the other axis in the
user case, and this is not wanted in the init case.

A higher level fix would be to make sure once aspect ratio is kept,
that ratio is stored in documents explicitly, so we can say 50% wide
with e.g. 4:3 ratio, that would avoid all this trouble by even looking
at the calculated sizes when we want to work with percents. This storing
of the aspect ratio is not done here.

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

diff --git a/sw/qa/uitest/data/keep-aspect-ratio.odt 
b/sw/qa/uitest/data/keep-aspect-ratio.odt
new file mode 100644
index ..2545b34e91f7
Binary files /dev/null and b/sw/qa/uitest/data/keep-aspect-ratio.odt differ
diff --git a/sw/qa/uitest/ui/frmdlg/frmdlg.py b/sw/qa/uitest/ui/frmdlg/frmdlg.py
index aa2d4fba7aff..a37062c1d392 100644
--- a/sw/qa/uitest/ui/frmdlg/frmdlg.py
+++ b/sw/qa/uitest/ui/frmdlg/frmdlg.py
@@ -150,4 +150,24 @@ class Test(UITestCase):
 # complexity.
 self.assertEqual(visible, "false")
 
+def test_keep_aspect_ratio_init(self):
+# Change from inch to pt to hit the rounding error. 6 means Point, see
+# officecfg/registry/schema/org/openoffice/Office/Writer.xcs.
+with 
self.ui_test.set_config('/org.openoffice.Office.Writer/Layout/Other/MeasureUnit',
 6):
+# Given a document with an image, width is relative:
+with 
self.ui_test.load_file(get_url_for_data_file("keep-aspect-ratio.odt")) as 
xComponent:
+xComponent.CurrentController.select(xComponent.DrawPage[0])
+# Wait until SwTextShell is replaced with SwDrawShell after 
120 ms, as set in the SwView
+# ctor.
+time.sleep(0.2)
+# When opening the image properties dialog:
+with 
self.ui_test.execute_dialog_through_command(".uno:FrameDialog") as xDialog:
+xWidth = xDialog.getChild("width")
+frame_width = get_state_as_dict(xWidth)["Value"]
+# Then make sure the width is 48%:
+# Without the accompanying fix in place, this test would have 
failed with:
+# AssertionError: '5' != '48'
+# i.e. the reported size was close to zero instead of ~half of 
the page width.
+self.assertEqual(frame_width, "48")
+
 # vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/sw/source/ui/frmdlg/frmpage.cxx b/sw/source/ui/frmdlg/frmpage.cxx
index 589af7dbb0a0..bd58f2ab7246 100644
--- a/sw/source/ui/frmdlg/frmpage.cxx
+++ b/sw/source/ui/frmdlg/frmpage.cxx
@@ -2182,7 +2182,7 @@ IMPL_LINK( SwFramePage, ModifyHdl, 
weld::MetricSpinButton&, rEdit, void )
 {
 SwTwips nWidth  = static_cast< SwTwips 
>(m_xWidthED->DenormalizePercent(m_xWidthED->get_value(FieldUnit::TWIP)));
 SwTwips nHeight = static_cast< SwTwips 
>(m_xHeightED->DenormalizePercent(m_xHeightED->get_value(FieldUnit::TWIP)));
-if (m_xFixedRatioCB->get_active())
+if (m_xFixedRatioCB->get_active() && !m_bIgnoreFixedRatio)
 {
 if ( == m_xWidthED->get())
 {
@@ -2385,14 +2385,18 @@ void SwFramePage::Init(const SfxItemSet& rSet)
 !m_xRelWidthCB->get_active())
 {
 m_xRelWidthCB->set_active(true);
+m_bIgnoreFixedRatio = true;
 RelSizeClickHdl(*m_xRelWidthCB);
+m_bIgnoreFixedRatio = false;
 m_xWidthED->set_value(rSize.GetWidthPercent(), FieldUnit::PERCENT);
 }
 if (rSize.GetHeightPercent() && rSize.GetHeightPercent() != 
SwFormatFrameSize::SYNCED &&
 

core.git: sw/qa sw/source

2024-05-24 Thread Miklos Vajna (via logerrit)
 sw/qa/core/layout/paintfrm.cxx |   10 ++
 sw/source/core/layout/paintfrm.cxx |9 -
 2 files changed, 18 insertions(+), 1 deletion(-)

New commits:
commit 755f3bebd96ec7ae43b1dcf247f907b9c15c1995
Author: Miklos Vajna 
AuthorDate: Fri May 24 10:51:31 2024 +0200
Commit: Miklos Vajna 
CommitDate: Fri May 24 12:36:21 2024 +0200

tdf#160984 sw continuous endnotes: fix the endnote separator length

See
,
Word has a longer separator line for the foot/endnote than Writer for
this bugdoc.

Writer defaults to 25% of the body frame width in the SwPageFootnoteInfo
ctor, and we don't seem to change that in the DOCX import. Word has a
static 2 inches setting, which is only reduced if it would go outside
the body frame.

Fix the problem by extending SwFootnoteContFrame::PaintLine() in the
DocumentSettingId::CONTINUOUS_ENDNOTES case to do the same.

I searched the OOXML spec and the MS implementer notes, they don't
specify this 2 inches length, but it seems static: the value doesn't
change with the page size. With this, the single-section bugdoc is now
rendered fine.

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

diff --git a/sw/qa/core/layout/paintfrm.cxx b/sw/qa/core/layout/paintfrm.cxx
index 8e7154db2501..a5213c57d639 100644
--- a/sw/qa/core/layout/paintfrm.cxx
+++ b/sw/qa/core/layout/paintfrm.cxx
@@ -177,6 +177,16 @@ CPPUNIT_TEST_FIXTURE(Test, 
testInlineEndnoteSeparatorPosition)
 // - Actual  : 2060
 // i.e. the upper spacing was too low.
 CPPUNIT_ASSERT_EQUAL(static_cast(2164), nEndnoteSeparatorY);
+
+// Also make sure the separator length is correct:
+auto nEndnoteSeparatorStart = getXPath(pXmlDoc, "//polygon/point[1]"_ostr, 
"x"_ostr).toInt32();
+auto nEndnoteSeparatorEnd = getXPath(pXmlDoc, "//polygon/point[2]"_ostr, 
"x"_ostr).toInt32();
+sal_Int32 nEndnoteSeparatorLength = nEndnoteSeparatorEnd - 
nEndnoteSeparatorStart;
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected: 2880
+// - Actual  : 2340
+// i.e. the separator wasn't 2 inches long, but was shorter vs Word.
+CPPUNIT_ASSERT_EQUAL(static_cast(2880), 
nEndnoteSeparatorLength);
 }
 }
 
diff --git a/sw/source/core/layout/paintfrm.cxx 
b/sw/source/core/layout/paintfrm.cxx
index b139a75094da..a0d5f0d8a629 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -5772,7 +5772,7 @@ void SwFootnoteContFrame::PaintLine( const SwRect& rRect,
 SwTwips nPrtWidth = aRectFnSet.GetWidth(getFramePrintArea());
 Fraction aFract( nPrtWidth, 1 );
 aFract *= rInf.GetWidth();
-const SwTwips nWidth = static_cast(aFract);
+SwTwips nWidth = static_cast(aFract);
 
 SwTwips nX = aRectFnSet.GetPrtLeft(*this);
 switch ( rInf.GetAdj() )
@@ -5803,6 +5803,13 @@ void SwFootnoteContFrame::PaintLine( const SwRect& rRect,
 // Word style: instead of fixed value, upper spacing is 60% of all 
space.
 auto nPrintAreaTop = 
static_cast(getFramePrintArea().Top());
 aPoint.setY(getFrameArea().Pos().Y() + nPrintAreaTop * 0.6);
+
+// Length is 2 inches, but don't paint outside the container frame.
+nWidth = o3tl::convert(2, o3tl::Length::in, o3tl::Length::twip);
+if (nWidth > nPrtWidth)
+{
+nWidth = nPrtWidth;
+}
 }
 oLineRect.emplace(aPoint, Size(nWidth, rInf.GetLineWidth()));
 }


core.git: sw/qa sw/source

2024-05-23 Thread Miklos Vajna (via logerrit)
 sw/qa/core/layout/paintfrm.cxx |   20 
 sw/source/core/layout/paintfrm.cxx |   27 ---
 2 files changed, 40 insertions(+), 7 deletions(-)

New commits:
commit f1d0b4e34a1f467e9f54baa7ac31ca28fdae3efb
Author: Miklos Vajna 
AuthorDate: Thu May 23 15:31:05 2024 +0200
Commit: Miklos Vajna 
CommitDate: Thu May 23 21:01:31 2024 +0200

tdf#160984 sw continuous endnotes: fix the endnote separator position

See , the
total height of the endnote separator is now correct, but the
distribution of upper space, line width, lower space is still bad, when
compared to Word.

Our model is 2 spacings and a line width, while Word seems to simply
split the amount of available space: 60% goes above the separator and
the rest goes below.

Fix the problem by breaking up the monster expression for the separator
rectangle in SwFootnoteContFrame::PaintLine(), and then the compat +
horizontal case can do the 60% spacing in the Word compat mode.

The width of the separator is still not correct.

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

diff --git a/sw/qa/core/layout/paintfrm.cxx b/sw/qa/core/layout/paintfrm.cxx
index b5990648b20f..8e7154db2501 100644
--- a/sw/qa/core/layout/paintfrm.cxx
+++ b/sw/qa/core/layout/paintfrm.cxx
@@ -158,6 +158,26 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitTableMergedBorder)
 // bottom border.
 CPPUNIT_ASSERT_EQUAL(static_cast(2), aHorizontalBorderEnds.size());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteSeparatorPosition)
+{
+// Given a document with a Word-style endnote separator:
+createSwDoc("inline-endnote-position.docx");
+SwDocShell* pDocShell = getSwDocShell();
+
+// When rendering that document:
+std::shared_ptr xMetaFile = pDocShell->GetPreviewMetaFile();
+
+// Then make sure the separator upper spacing is 60% of all space, 
matching Word:
+MetafileXmlDump aDumper;
+xmlDocUniquePtr pXmlDoc = dumpAndParse(aDumper, *xMetaFile);
+auto nEndnoteSeparatorY = getXPath(pXmlDoc, "//polygon/point[1]"_ostr, 
"y"_ostr).toInt32();
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected: 2164
+// - Actual  : 2060
+// i.e. the upper spacing was too low.
+CPPUNIT_ASSERT_EQUAL(static_cast(2164), nEndnoteSeparatorY);
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/paintfrm.cxx 
b/sw/source/core/layout/paintfrm.cxx
index 8c0f4f876847..b139a75094da 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -5788,13 +5788,26 @@ void SwFootnoteContFrame::PaintLine( const SwRect& 
rRect,
 assert(false);
 }
 SwTwips nLineWidth = rInf.GetLineWidth();
-const SwRect aLineRect = aRectFnSet.IsVert() ?
-SwRect( 
Point(getFrameArea().Left()+getFrameArea().Width()-rInf.GetTopDist()-nLineWidth,
-  nX), Size( nLineWidth, nWidth ) )
-: SwRect( Point( nX, getFrameArea().Pos().Y() + rInf.GetTopDist() 
),
-Size( nWidth, rInf.GetLineWidth()));
-if ( aLineRect.HasArea() && rInf.GetLineStyle() != 
SvxBorderLineStyle::NONE)
-PaintBorderLine( rRect, aLineRect , pPage, (),
+std::optional oLineRect;
+if (aRectFnSet.IsVert())
+{
+
oLineRect.emplace(Point(getFrameArea().Left()+getFrameArea().Width()-rInf.GetTopDist()-nLineWidth,
+  nX), Size( nLineWidth, nWidth ) );
+}
+else
+{
+Point aPoint(nX, getFrameArea().Pos().Y() + rInf.GetTopDist());
+const IDocumentSettingAccess& rIDSA = 
GetFormat()->getIDocumentSettingAccess();
+if (rIDSA.get(DocumentSettingId::CONTINUOUS_ENDNOTES))
+{
+// Word style: instead of fixed value, upper spacing is 60% of all 
space.
+auto nPrintAreaTop = 
static_cast(getFramePrintArea().Top());
+aPoint.setY(getFrameArea().Pos().Y() + nPrintAreaTop * 0.6);
+}
+oLineRect.emplace(aPoint, Size(nWidth, rInf.GetLineWidth()));
+}
+if ( oLineRect->HasArea() && rInf.GetLineStyle() != 
SvxBorderLineStyle::NONE)
+PaintBorderLine( rRect, *oLineRect , pPage, (),
 rInf.GetLineStyle() );
 }
 


core.git: Branch 'distro/collabora/co-24.04' - sw/inc sw/qa sw/source

2024-05-23 Thread Miklos Vajna (via logerrit)
 sw/inc/pagedesc.hxx |2 
 sw/qa/core/layout/data/inline-endnote-position.docx |binary
 sw/qa/core/layout/ftnfrm.cxx|   20 
 sw/source/core/layout/ftnfrm.cxx|   49 +++-
 sw/source/filter/ww8/docxattributeoutput.cxx|   10 +++-
 5 files changed, 77 insertions(+), 4 deletions(-)

New commits:
commit dbc5e22e4e1ae730f70664472a3d4d72688d629e
Author: Miklos Vajna 
AuthorDate: Wed May 22 13:56:40 2024 +0200
Commit: Caolán McNamara 
CommitDate: Thu May 23 17:10:31 2024 +0200

tdf#160984 sw continuous endnotes: fix the endnote container's top margin

Comparing the Word vs Writer output for the bugdoc, the vertical
position of the endnote text is not correct: the y pos should be larger
than it is, see the red reference at e.g.
.

Seems this is caused by the different height of the rectangle around the
endnote separator: the top margin is 124 twips in Writer, which is a
hardcoded default from the SwPageFootnoteInfo ctor, while Word has this
separator as a special character, inside a paragraph, which inherits the
height of the default paragraph style.

Fix the problem by extending sw::FootnoteSeparatorHeight() to also work
from RES_POOLCOLL_STANDARD in the Word compat case. Note that it's not
enough to take the font size (11pt in this case) from the paragraph
style, we want to work with the real font, which knows the spacing
between lines (15% in this case). SwFont::GetHeight() has this logic,
it's also what e.g. SwTextFrame::FormatEmpty() uses.

Note that footnotes have the same problem, but given that they grow from
the bottom of the page, the text position was correct, even if the
separator height is incorrect. Also, the separator line itself is not
changed in this commit, we just make sure that the height is OK, so text
below the line has the correct position.

(cherry picked from commit d1ddd136a1b0e452492464d58715eaec144fd811)

Change-Id: If1f4757908355abc81ee711de5ab9db4c751354c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167984
Tested-by: Jenkins CollaboraOffice 
Tested-by: Caolán McNamara 
Reviewed-by: Caolán McNamara 

diff --git a/sw/inc/pagedesc.hxx b/sw/inc/pagedesc.hxx
index ddc7e659a5bb..d9b58a4bb357 100644
--- a/sw/inc/pagedesc.hxx
+++ b/sw/inc/pagedesc.hxx
@@ -399,7 +399,7 @@ public:
 namespace sw {
 class PageFootnoteHint final : public SfxHint {};
 
-SW_DLLPUBLIC SwTwips FootnoteSeparatorHeight(SwPageFootnoteInfo const&);
+SW_DLLPUBLIC SwTwips FootnoteSeparatorHeight(SwDoc& rDoc, 
SwPageFootnoteInfo const&);
 }
 
 typedef boost::multi_index_container<
diff --git a/sw/qa/core/layout/data/inline-endnote-position.docx 
b/sw/qa/core/layout/data/inline-endnote-position.docx
new file mode 100644
index ..3905208f9f0e
Binary files /dev/null and 
b/sw/qa/core/layout/data/inline-endnote-position.docx differ
diff --git a/sw/qa/core/layout/ftnfrm.cxx b/sw/qa/core/layout/ftnfrm.cxx
index 1cf31809e5a7..a7640e26ca9a 100644
--- a/sw/qa/core/layout/ftnfrm.cxx
+++ b/sw/qa/core/layout/ftnfrm.cxx
@@ -102,4 +102,24 @@ CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteAndSection)
 CPPUNIT_ASSERT_EQUAL(2, nToplevelSections);
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testInlineEndnotePosition)
+{
+// Given a document, ContinuousEndnotes is true:
+createSwDoc("inline-endnote-position.docx");
+
+// When laying out that document:
+xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+// Then make sure the endnote separator (line + spacing around it) is 
large enough, so the
+// endnote text below the separator has the correct position:
+sal_Int32 nEndnoteContTopMargin
+= parseDump("//column/ftncont/infos/prtBounds"_ostr, 
"top"_ostr).toInt32();
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected: 269
+// - Actual  : 124
+// i.e. the top margin wasn't the default font size with its spacing, but 
the Writer default,
+// which shifted endnote text up, incorrectly.
+CPPUNIT_ASSERT_EQUAL(static_cast(269), nEndnoteContTopMargin);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/ftnfrm.cxx b/sw/source/core/layout/ftnfrm.cxx
index 61a8385d51fc..46312f9f4e89 100644
--- a/sw/source/core/layout/ftnfrm.cxx
+++ b/sw/source/core/layout/ftnfrm.cxx
@@ -42,9 +42,41 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
 
 #define ENDNOTE 0x8000
 
+namespace
+{
+/// Calculates the height of the line that hosts the separator line (the top 
margin of the
+/// container), based on the default paragraph style in rDoc.
+bool FootnoteSeparatorHeightFromParagraph(SwDoc& rDoc, SwTwips& rHeight)
+{
+const SwTextFormatColl* 

core.git: Branch 'distro/collabora/co-24.04' - writerfilter/qa writerfilter/source

2024-05-23 Thread Miklos Vajna (via logerrit)
 writerfilter/qa/cppunittests/filter/WriterFilter.cxx  |   
26 ++
 writerfilter/qa/cppunittests/filter/data/inline-endnote-and-footnote.docx 
|binary
 writerfilter/source/filter/WriterFilter.cxx   |
1 
 3 files changed, 27 insertions(+)

New commits:
commit 10b1f037288f107357bd4402ff65528f76544b0c
Author: Miklos Vajna 
AuthorDate: Tue May 21 08:15:53 2024 +0200
Commit: Caolán McNamara 
CommitDate: Thu May 23 15:59:22 2024 +0200

tdf#160984 sw continuous endnotes: enable DOCX import

This was working for DOC already.

For DOCX, this was already enabled once with commit
f9982c24066d6dd2f938cc20176af0f196bc018f (tdf#58521 DOCX import: enable
ContinuousEndnotes compat flag, 2021-07-13), but then it was reverted
later with commit commit eeda1b35a6e87d5349545464da33d997c52f15e3
(Revert "tdf#58521 DOCX import: enable ContinuousEndnotes compat flag",
2021-08-10), because of tdf#143456.

Enable it again, now that the section-based layout seems good enough to
handle larger number of endnotes, e.g. the 48 endnotes from tdf#143456.

(cherry picked from commit 1ae5ea3f78cca11ba18f2dd1a06f875263336a3b)

Change-Id: Id221f31f9208e84db2c358546d4d6ceea991b6b3
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167924
Reviewed-by: Caolán McNamara 
Tested-by: Jenkins CollaboraOffice 

diff --git a/writerfilter/qa/cppunittests/filter/WriterFilter.cxx 
b/writerfilter/qa/cppunittests/filter/WriterFilter.cxx
index ae741085277c..be9139c5c229 100644
--- a/writerfilter/qa/cppunittests/filter/WriterFilter.cxx
+++ b/writerfilter/qa/cppunittests/filter/WriterFilter.cxx
@@ -50,6 +50,32 @@ CPPUNIT_TEST_FIXTURE(Test, testDoNotMirrorRtlDrawObjs)
 // i.e. the shape was on the left margin.
 CPPUNIT_ASSERT_GREATER(nBodyRight, nShapeLeft);
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteAndFootnoteDOCX)
+{
+// Given a DOCX file with an endnote and then a footnote:
+loadFromFile(u"inline-endnote-and-footnote.docx");
+
+// When laying out that document:
+uno::Reference xModel(mxComponent, uno::UNO_QUERY);
+css::uno::Reference xDumper(xModel->getCurrentController(), 
uno::UNO_QUERY);
+OString aDump = xDumper->dump("layout").toUtf8();
+auto pCharBuffer = reinterpret_cast(aDump.getStr());
+xmlDocUniquePtr pXmlDoc(xmlParseDoc(pCharBuffer));
+
+// Then make sure the footnote is below the endnote:
+// Without the accompanying fix in place, this test would have failed with:
+// - xpath should match exactly 1 node
+// i.e. the endnote was also in the footnote container, not at the end of 
the body text.
+sal_Int32 nEndnoteTop
+= getXPath(pXmlDoc, 
"/root/page/body/section/column/ftncont/ftn/infos/bounds"_ostr,
+   "top"_ostr)
+  .toInt32();
+sal_Int32 nFootnoteTop
+= getXPath(pXmlDoc, "/root/page/ftncont/ftn/infos/bounds"_ostr, 
"top"_ostr).toInt32();
+// Endnote at the end of body text, footnote at page bottom.
+CPPUNIT_ASSERT_LESS(nFootnoteTop, nEndnoteTop);
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git 
a/writerfilter/qa/cppunittests/filter/data/inline-endnote-and-footnote.docx 
b/writerfilter/qa/cppunittests/filter/data/inline-endnote-and-footnote.docx
new file mode 100644
index ..84343b8afa45
Binary files /dev/null and 
b/writerfilter/qa/cppunittests/filter/data/inline-endnote-and-footnote.docx 
differ
diff --git a/writerfilter/source/filter/WriterFilter.cxx 
b/writerfilter/source/filter/WriterFilter.cxx
index 44efc0c42cfc..f7654681f6ee 100644
--- a/writerfilter/source/filter/WriterFilter.cxx
+++ b/writerfilter/source/filter/WriterFilter.cxx
@@ -332,6 +332,7 @@ void WriterFilter::setTargetDocument(const 
uno::Reference& xDo
 // rely on default for HyphenateURLs=false
 // rely on default for 
APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH=true
 xSettings->setPropertyValue("DoNotMirrorRtlDrawObjs", uno::Any(true));
+xSettings->setPropertyValue("ContinuousEndnotes", uno::Any(true));
 }
 
 void WriterFilter::setSourceDocument(const uno::Reference& 
xDoc)


core.git: sw/qa

2024-05-23 Thread Miklos Vajna (via logerrit)
 sw/qa/extras/rtfexport/rtfexport8.cxx |  540 --
 1 file changed, 322 insertions(+), 218 deletions(-)

New commits:
commit a4ec8307e342bd83e287b197ffac822ac7e9f599
Author: Miklos Vajna 
AuthorDate: Thu May 23 08:06:53 2024 +0200
Commit: Miklos Vajna 
CommitDate: Thu May 23 09:46:38 2024 +0200

CppunitTest_sw_rtfexport8: avoid DECLARE_RTFEXPORT_TEST

No need to go via Writer-specific macros here.

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

diff --git a/sw/qa/extras/rtfexport/rtfexport8.cxx 
b/sw/qa/extras/rtfexport/rtfexport8.cxx
index e05eb817d07f..33219edcfe9d 100644
--- a/sw/qa/extras/rtfexport/rtfexport8.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport8.cxx
@@ -53,133 +53,191 @@ public:
 }
 };
 
-DECLARE_RTFEXPORT_TEST(testTdf155663, "piccrop.rtf")
+CPPUNIT_TEST_FIXTURE(Test, testTdf155663)
 {
-auto const xShape(getShape(1));
-if (!isExported())
-{
-CPPUNIT_ASSERT_EQUAL(sal_Int32(2004), xShape->getSize().Height);
-CPPUNIT_ASSERT_EQUAL(sal_Int32(2004), xShape->getSize().Width);
-}
-else // bit of rounding loss?
-{
-CPPUNIT_ASSERT_EQUAL(sal_Int32(2013), xShape->getSize().Height);
-CPPUNIT_ASSERT_EQUAL(sal_Int32(2013), xShape->getSize().Width);
-}
-CPPUNIT_ASSERT_EQUAL(sal_Int32(123), 
getProperty(xShape, "GraphicCrop").Top);
-CPPUNIT_ASSERT_EQUAL(sal_Int32(123),
- getProperty(xShape, 
"GraphicCrop").Bottom);
-CPPUNIT_ASSERT_EQUAL(sal_Int32(123),
- getProperty(xShape, 
"GraphicCrop").Left);
-CPPUNIT_ASSERT_EQUAL(sal_Int32(123),
- getProperty(xShape, 
"GraphicCrop").Right);
+auto verify = [this]() {
+auto const xShape(getShape(1));
+if (!isExported())
+{
+CPPUNIT_ASSERT_EQUAL(sal_Int32(2004), xShape->getSize().Height);
+CPPUNIT_ASSERT_EQUAL(sal_Int32(2004), xShape->getSize().Width);
+}
+else // bit of rounding loss?
+{
+CPPUNIT_ASSERT_EQUAL(sal_Int32(2013), xShape->getSize().Height);
+CPPUNIT_ASSERT_EQUAL(sal_Int32(2013), xShape->getSize().Width);
+}
+CPPUNIT_ASSERT_EQUAL(sal_Int32(123),
+ getProperty(xShape, 
"GraphicCrop").Top);
+CPPUNIT_ASSERT_EQUAL(sal_Int32(123),
+ getProperty(xShape, 
"GraphicCrop").Bottom);
+CPPUNIT_ASSERT_EQUAL(sal_Int32(123),
+ getProperty(xShape, 
"GraphicCrop").Left);
+CPPUNIT_ASSERT_EQUAL(sal_Int32(123),
+ getProperty(xShape, 
"GraphicCrop").Right);
+};
+createSwDoc("piccrop.rtf");
+verify();
+saveAndReload(mpFilter);
+verify();
 }
 
-DECLARE_RTFEXPORT_TEST(testTdf158586_0, "tdf158586_pageBreak0.rtf")
+CPPUNIT_TEST_FIXTURE(Test, testTdf158586_0)
 {
-// The specified page break must be lost because it is in a text frame
-CPPUNIT_ASSERT_EQUAL(1, getPages());
-CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
-
-// There should be no empty paragraph at the start
-xmlDocUniquePtr pLayout = parseLayoutDump();
-assertXPath(pLayout, "//anchored"_ostr, 1);
-assertXPathContent(pLayout, "/root/page[1]/body//txt"_ostr, "First page");
+auto verify = [this]() {
+// The specified page break must be lost because it is in a text frame
+CPPUNIT_ASSERT_EQUAL(1, getPages());
+CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
+
+// There should be no empty paragraph at the start
+xmlDocUniquePtr pLayout = parseLayoutDump();
+assertXPath(pLayout, "//anchored"_ostr, 1);
+assertXPathContent(pLayout, "/root/page[1]/body//txt"_ostr, "First 
page");
+};
+createSwDoc("tdf158586_pageBreak0.rtf");
+verify();
+saveAndReload(mpFilter);
+verify();
 }
 
-DECLARE_RTFEXPORT_TEST(testTdf158586_0B, "tdf158586_pageBreak0B.rtf")
+CPPUNIT_TEST_FIXTURE(Test, testTdf158586_0B)
 {
-// The specified page break must be lost because it is in a text frame
-CPPUNIT_ASSERT_EQUAL(1, getPages());
-CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
-
-// There should be no empty paragraph at the start
-xmlDocUniquePtr pLayout = parseLayoutDump();
-assertXPath(pLayout, "//anchored"_ostr, 1);
-assertXPathContent(pLayout, "/root/page[1]/body//txt"_ostr, "First page");
+auto verify = [this]() {
+// The specified page break must be lost because it is in a text frame
+CPPUNIT_ASSERT_EQUAL(1, getPages());
+CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
+
+// There should be no empty paragraph at the start
+xmlDocUniquePtr pLayout = parseLayoutDump();
+assertXPath(pLayout, "//anchored"_ostr, 1);
+assertXPathContent(pLayout, "/root/page[1]/body//txt"_ostr, "First 
page");
+};

core.git: Branch 'distro/collabora/co-24.04' - sw/qa sw/source xmloff/qa

2024-05-23 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 991341f9f69fded9c9573d91b2d65fc6a37b3132
Author: Miklos Vajna 
AuthorDate: Wed May 22 08:47:32 2024 +0200
Commit: Miklos Vajna 
CommitDate: Thu May 23 09:20:46 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
(cherry picked from commit 3046bd0e30406d37813ce3eaa65f71f5ed10ab13)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167980
Tested-by: Jenkins CollaboraOffice 

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 

core.git: sw/inc sw/qa sw/source

2024-05-22 Thread Miklos Vajna (via logerrit)
 sw/inc/pagedesc.hxx |2 
 sw/qa/core/layout/data/inline-endnote-position.docx |binary
 sw/qa/core/layout/ftnfrm.cxx|   20 
 sw/source/core/layout/ftnfrm.cxx|   49 +++-
 sw/source/filter/ww8/docxattributeoutput.cxx|   10 +++-
 5 files changed, 77 insertions(+), 4 deletions(-)

New commits:
commit d1ddd136a1b0e452492464d58715eaec144fd811
Author: Miklos Vajna 
AuthorDate: Wed May 22 13:56:40 2024 +0200
Commit: Miklos Vajna 
CommitDate: Wed May 22 17:50:10 2024 +0200

tdf#160984 sw continuous endnotes: fix the endnote container's top margin

Comparing the Word vs Writer output for the bugdoc, the vertical
position of the endnote text is not correct: the y pos should be larger
than it is, see the red reference at e.g.
.

Seems this is caused by the different height of the rectangle around the
endnote separator: the top margin is 124 twips in Writer, which is a
hardcoded default from the SwPageFootnoteInfo ctor, while Word has this
separator as a special character, inside a paragraph, which inherits the
height of the default paragraph style.

Fix the problem by extending sw::FootnoteSeparatorHeight() to also work
from RES_POOLCOLL_STANDARD in the Word compat case. Note that it's not
enough to take the font size (11pt in this case) from the paragraph
style, we want to work with the real font, which knows the spacing
between lines (15% in this case). SwFont::GetHeight() has this logic,
it's also what e.g. SwTextFrame::FormatEmpty() uses.

Note that footnotes have the same problem, but given that they grow from
the bottom of the page, the text position was correct, even if the
separator height is incorrect. Also, the separator line itself is not
changed in this commit, we just make sure that the height is OK, so text
below the line has the correct position.

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

diff --git a/sw/inc/pagedesc.hxx b/sw/inc/pagedesc.hxx
index 3ec919ce3c83..a8241f15f6f0 100644
--- a/sw/inc/pagedesc.hxx
+++ b/sw/inc/pagedesc.hxx
@@ -399,7 +399,7 @@ public:
 namespace sw {
 class PageFootnoteHint final : public SfxHint {};
 
-SW_DLLPUBLIC SwTwips FootnoteSeparatorHeight(SwPageFootnoteInfo const&);
+SW_DLLPUBLIC SwTwips FootnoteSeparatorHeight(SwDoc& rDoc, 
SwPageFootnoteInfo const&);
 }
 
 typedef boost::multi_index_container<
diff --git a/sw/qa/core/layout/data/inline-endnote-position.docx 
b/sw/qa/core/layout/data/inline-endnote-position.docx
new file mode 100644
index ..3905208f9f0e
Binary files /dev/null and 
b/sw/qa/core/layout/data/inline-endnote-position.docx differ
diff --git a/sw/qa/core/layout/ftnfrm.cxx b/sw/qa/core/layout/ftnfrm.cxx
index 1cf31809e5a7..a7640e26ca9a 100644
--- a/sw/qa/core/layout/ftnfrm.cxx
+++ b/sw/qa/core/layout/ftnfrm.cxx
@@ -102,4 +102,24 @@ CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteAndSection)
 CPPUNIT_ASSERT_EQUAL(2, nToplevelSections);
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testInlineEndnotePosition)
+{
+// Given a document, ContinuousEndnotes is true:
+createSwDoc("inline-endnote-position.docx");
+
+// When laying out that document:
+xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+// Then make sure the endnote separator (line + spacing around it) is 
large enough, so the
+// endnote text below the separator has the correct position:
+sal_Int32 nEndnoteContTopMargin
+= parseDump("//column/ftncont/infos/prtBounds"_ostr, 
"top"_ostr).toInt32();
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected: 269
+// - Actual  : 124
+// i.e. the top margin wasn't the default font size with its spacing, but 
the Writer default,
+// which shifted endnote text up, incorrectly.
+CPPUNIT_ASSERT_EQUAL(static_cast(269), nEndnoteContTopMargin);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/ftnfrm.cxx b/sw/source/core/layout/ftnfrm.cxx
index b7851a131e44..548d8228063e 100644
--- a/sw/source/core/layout/ftnfrm.cxx
+++ b/sw/source/core/layout/ftnfrm.cxx
@@ -42,9 +42,41 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
 
 #define ENDNOTE 0x8000
 
+namespace
+{
+/// Calculates the height of the line that hosts the separator line (the top 
margin of the
+/// container), based on the default paragraph style in rDoc.
+bool FootnoteSeparatorHeightFromParagraph(SwDoc& rDoc, SwTwips& rHeight)
+{
+const SwTextFormatColl* pDefaultParaFormat
+= 
rDoc.getIDocumentStylePoolAccess().GetTextCollFromPool(RES_POOLCOLL_STANDARD);
+if 

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: 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 080afd6a345e5dffd924100b5a3ff9c028f5b094
Author: Miklos Vajna 
AuthorDate: Wed May 22 08:47:32 2024 +0200
Commit: Miklos Vajna 
CommitDate: Wed May 22 10:27:36 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 

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 549681ca7227..a3c9ac84e7c2 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 1679af04bc1f..f95e07e42578 100644
--- a/xmloff/qa/unit/text.cxx
+++ b/xmloff/qa/unit/text.cxx
@@ -508,11 +508,11 @@ CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testRelativeWidth)
 
 xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr);

core.git: include/svx svx/source

2024-05-21 Thread Miklos Vajna (via logerrit)
 include/svx/svdundo.hxx   |2 +-
 svx/source/svdraw/svdundo.cxx |   10 +-
 2 files changed, 6 insertions(+), 6 deletions(-)

New commits:
commit f2ba39c5e7ae28a832e707667a0a61736f65ebda
Author: Miklos Vajna 
AuthorDate: Tue May 21 08:32:27 2024 +0200
Commit: Miklos Vajna 
CommitDate: Tue May 21 13:05:42 2024 +0200

svx: prefix members of SdrUndoDelPage

See tdf#94879 for motivation.

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

diff --git a/include/svx/svdundo.hxx b/include/svx/svdundo.hxx
index 5af5c584eda1..e1b778064e6d 100644
--- a/include/svx/svdundo.hxx
+++ b/include/svx/svdundo.hxx
@@ -594,7 +594,7 @@ class SVXCORE_DLLPUBLIC SdrUndoDelPage final : public 
SdrUndoPageList
 {
 // When deleting a MasterPage, we remember all relations of the
 // Character Page with the MasterPage in this UndoGroup.
-std::unique_ptr pUndoGroup;
+std::unique_ptr m_pUndoGroup;
 std::unique_ptr mpFillBitmapItem;
 bool mbHasFillBitmap;
 
diff --git a/svx/source/svdraw/svdundo.cxx b/svx/source/svdraw/svdundo.cxx
index 1b52ee945957..bec090c6339c 100644
--- a/svx/source/svdraw/svdundo.cxx
+++ b/svx/source/svdraw/svdundo.cxx
@@ -1408,12 +1408,12 @@ SdrUndoDelPage::SdrUndoDelPage(SdrPage& rNewPg)
 
 if(mxPage.get() == )
 {
-if(!pUndoGroup)
+if(!m_pUndoGroup)
 {
-pUndoGroup.reset( new SdrUndoGroup(m_rMod) );
+m_pUndoGroup.reset( new SdrUndoGroup(m_rMod) );
 }
 
-
pUndoGroup->AddAction(m_rMod.GetSdrUndoFactory().CreateUndoPageRemoveMasterPage(*pDrawPage));
+
m_pUndoGroup->AddAction(m_rMod.GetSdrUndoFactory().CreateUndoPageRemoveMasterPage(*pDrawPage));
 }
 }
 }
@@ -1428,10 +1428,10 @@ void SdrUndoDelPage::Undo()
 if (bool(mpFillBitmapItem))
 restoreFillBitmap();
 ImpInsertPage(nPageNum);
-if (pUndoGroup!=nullptr)
+if (m_pUndoGroup!=nullptr)
 {
 // recover master page relationships
-pUndoGroup->Undo();
+m_pUndoGroup->Undo();
 }
 }
 


core.git: sw/qa sw/source

2024-05-21 Thread Miklos Vajna (via logerrit)
 sw/qa/writerfilter/cppunittests/filter/WriterFilter.cxx  | 
  26 ++
 sw/qa/writerfilter/cppunittests/filter/data/inline-endnote-and-footnote.docx 
|binary
 sw/source/writerfilter/filter/WriterFilter.cxx   | 
   1 
 3 files changed, 27 insertions(+)

New commits:
commit 1ae5ea3f78cca11ba18f2dd1a06f875263336a3b
Author: Miklos Vajna 
AuthorDate: Tue May 21 08:15:53 2024 +0200
Commit: Miklos Vajna 
CommitDate: Tue May 21 10:42:40 2024 +0200

tdf#160984 sw continuous endnotes: enable DOCX import

This was working for DOC already.

For DOCX, this was already enabled once with commit
f9982c24066d6dd2f938cc20176af0f196bc018f (tdf#58521 DOCX import: enable
ContinuousEndnotes compat flag, 2021-07-13), but then it was reverted
later with commit commit eeda1b35a6e87d5349545464da33d997c52f15e3
(Revert "tdf#58521 DOCX import: enable ContinuousEndnotes compat flag",
2021-08-10), because of tdf#143456.

Enable it again, now that the section-based layout seems good enough to
handle larger number of endnotes, e.g. the 48 endnotes from tdf#143456.

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

diff --git a/sw/qa/writerfilter/cppunittests/filter/WriterFilter.cxx 
b/sw/qa/writerfilter/cppunittests/filter/WriterFilter.cxx
index 10b8cab57a45..e084f0fa52ee 100644
--- a/sw/qa/writerfilter/cppunittests/filter/WriterFilter.cxx
+++ b/sw/qa/writerfilter/cppunittests/filter/WriterFilter.cxx
@@ -50,6 +50,32 @@ CPPUNIT_TEST_FIXTURE(Test, testDoNotMirrorRtlDrawObjs)
 // i.e. the shape was on the left margin.
 CPPUNIT_ASSERT_GREATER(nBodyRight, nShapeLeft);
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteAndFootnoteDOCX)
+{
+// Given a DOCX file with an endnote and then a footnote:
+loadFromFile(u"inline-endnote-and-footnote.docx");
+
+// When laying out that document:
+uno::Reference xModel(mxComponent, uno::UNO_QUERY);
+css::uno::Reference xDumper(xModel->getCurrentController(), 
uno::UNO_QUERY);
+OString aDump = xDumper->dump("layout").toUtf8();
+auto pCharBuffer = reinterpret_cast(aDump.getStr());
+xmlDocUniquePtr pXmlDoc(xmlParseDoc(pCharBuffer));
+
+// Then make sure the footnote is below the endnote:
+// Without the accompanying fix in place, this test would have failed with:
+// - xpath should match exactly 1 node
+// i.e. the endnote was also in the footnote container, not at the end of 
the body text.
+sal_Int32 nEndnoteTop
+= getXPath(pXmlDoc, 
"/root/page/body/section/column/ftncont/ftn/infos/bounds"_ostr,
+   "top"_ostr)
+  .toInt32();
+sal_Int32 nFootnoteTop
+= getXPath(pXmlDoc, "/root/page/ftncont/ftn/infos/bounds"_ostr, 
"top"_ostr).toInt32();
+// Endnote at the end of body text, footnote at page bottom.
+CPPUNIT_ASSERT_LESS(nFootnoteTop, nEndnoteTop);
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git 
a/sw/qa/writerfilter/cppunittests/filter/data/inline-endnote-and-footnote.docx 
b/sw/qa/writerfilter/cppunittests/filter/data/inline-endnote-and-footnote.docx
new file mode 100644
index ..84343b8afa45
Binary files /dev/null and 
b/sw/qa/writerfilter/cppunittests/filter/data/inline-endnote-and-footnote.docx 
differ
diff --git a/sw/source/writerfilter/filter/WriterFilter.cxx 
b/sw/source/writerfilter/filter/WriterFilter.cxx
index 742ae2bbeee2..ee8131f95ae3 100644
--- a/sw/source/writerfilter/filter/WriterFilter.cxx
+++ b/sw/source/writerfilter/filter/WriterFilter.cxx
@@ -333,6 +333,7 @@ void WriterFilter::setTargetDocument(const 
uno::Reference& xDo
 // rely on default for HyphenateURLs=false
 // rely on default for 
APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH=true
 xSettings->setPropertyValue("DoNotMirrorRtlDrawObjs", uno::Any(true));
+xSettings->setPropertyValue("ContinuousEndnotes", uno::Any(true));
 }
 
 void WriterFilter::setSourceDocument(const uno::Reference& 
xDoc)


core.git: Branch 'distro/collabora/co-24.04' - desktop/source

2024-05-17 Thread Miklos Vajna (via logerrit)
 desktop/source/lib/init.cxx |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

New commits:
commit 63ba90e6aea1554d6ee2d50b9439312a4b7ee483
Author: Miklos Vajna 
AuthorDate: Fri May 17 13:54:26 2024 +0200
Commit: Caolán McNamara 
CommitDate: Fri May 17 15:24:31 2024 +0200

desktop: fix warning C4100: 'pThis': unreferenced formal parameter

SAL_UNUSED_PARAMETER expands to nothing in the Windows case, though not
sure why this started to matter only now.

Change-Id: I7f7369c650af0585cb742c1fb4e7a111e270df63
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167775
Reviewed-by: Caolán McNamara 
Tested-by: Jenkins CollaboraOffice 

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 8edd138cc907..a61eb3ff0879 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -7289,7 +7289,7 @@ static void doc_setViewTimezone(SAL_UNUSED_PARAMETER 
LibreOfficeKitDocument* /*p
 }
 }
 
-static void doc_setViewReadOnly(SAL_UNUSED_PARAMETER LibreOfficeKitDocument* 
pThis, int nId, const bool readOnly)
+static void doc_setViewReadOnly(LibreOfficeKitDocument* /*pThis*/, int nId, 
const bool readOnly)
 {
 comphelper::ProfileZone aZone("doc_setViewReadOnly");
 
@@ -7299,7 +7299,7 @@ static void doc_setViewReadOnly(SAL_UNUSED_PARAMETER 
LibreOfficeKitDocument* pTh
 SfxLokHelper::setViewReadOnly(nId, readOnly);
 }
 
-static void doc_setAllowChangeComments(SAL_UNUSED_PARAMETER 
LibreOfficeKitDocument* pThis, int nId, const bool allow)
+static void doc_setAllowChangeComments(LibreOfficeKitDocument* /*pThis*/, int 
nId, const bool allow)
 {
 comphelper::ProfileZone aZone("doc_setAllowChangeComments");
 


core.git: Branch 'distro/collabora/co-24.04' - sw/qa sw/source

2024-05-17 Thread Miklos Vajna (via logerrit)
 sw/qa/filter/ww8/ww8.cxx  |7 ++-
 sw/source/core/inc/frame.hxx  |3 +++
 sw/source/core/layout/findfrm.cxx |   11 +++
 sw/source/filter/ww8/ww8par.cxx   |7 ---
 4 files changed, 20 insertions(+), 8 deletions(-)

New commits:
commit 135e86e7e3bafdb0ab39a372a989854eefefe30c
Author: Miklos Vajna 
AuthorDate: Thu May 16 08:46:36 2024 +0200
Commit: Caolán McNamara 
CommitDate: Fri May 17 12:03:49 2024 +0200

tdf#160984 sw continuous endnotes, DOC import: enable this unconditionally

DOC files with <= 2 endnotes were imported fine, but not if they had
more endnotes.

This was added in commit dc11f5b151e1a2ea2623fc8cf806a400763955d9
(tdf#143445 DOC import: limit the usage of the CONTINUOUS_ENDNOTES
compat flag, 2023-05-23), because mapping endnotes to footnotes was a
dead-end.

The limitation can be dropped: I checked that the tdf#143445 bugdoc with
all its 72 endnotes is laid out reasonably.

Also add a new SwFrame::DynCastColumnFrame() to easily get a column
frame from a frame using our own RTTI, if we have it anyway.

(cherry picked from commit d74fb6b571304b41c13b7a6dcdd2b853bfca7210)

Change-Id: If7fd856f5dc5f1feb1366fca69a2ad6b3602044d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167763
Tested-by: Jenkins CollaboraOffice 
Reviewed-by: Caolán McNamara 

diff --git a/sw/qa/filter/ww8/ww8.cxx b/sw/qa/filter/ww8/ww8.cxx
index af19051a03e5..4cbbfe5fbf31 100644
--- a/sw/qa/filter/ww8/ww8.cxx
+++ b/sw/qa/filter/ww8/ww8.cxx
@@ -30,6 +30,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 namespace
 {
@@ -298,7 +300,10 @@ CPPUNIT_TEST_FIXTURE(Test, test3Endnotes)
 SwDoc* pDoc = getSwDoc();
 SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
 SwPageFrame* pPage = pLayout->GetLastPage();
-SwFootnoteContFrame* pFootnoteCont = pPage->FindFootnoteCont();
+SwContentFrame* pLastContent = pPage->FindLastBodyContent();
+SwFrame* pSectionFrame = pLastContent->GetNext();
+auto pColumnFrame = pSectionFrame->GetLower()->DynCastColumnFrame();
+SwFootnoteContFrame* pFootnoteCont = pColumnFrame->FindFootnoteCont();
 int nEndnotes = 0;
 for (SwFrame* pLower = pFootnoteCont->GetLower(); pLower; pLower = 
pLower->GetNext())
 {
diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx
index a86358508182..b662adc89086 100644
--- a/sw/source/core/inc/frame.hxx
+++ b/sw/source/core/inc/frame.hxx
@@ -40,6 +40,7 @@ namespace drawinglayer::processor2d { class BaseProcessor2D; }
 class SwLayoutFrame;
 class SwRootFrame;
 class SwPageFrame;
+class SwColumnFrame;
 class SwBodyFrame;
 class SwFlyFrame;
 class SwSectionFrame;
@@ -876,6 +877,8 @@ public:
 const SwTextFrame* DynCastTextFrame() const;
 SwPageFrame* DynCastPageFrame();
 const SwPageFrame* DynCastPageFrame() const;
+SwColumnFrame* DynCastColumnFrame();
+const SwColumnFrame* DynCastColumnFrame() const;
 inline bool IsNoTextFrame() const;
 // Frames where its PrtArea depends on their neighbors and that are
 // positioned in the content flow
diff --git a/sw/source/core/layout/findfrm.cxx 
b/sw/source/core/layout/findfrm.cxx
index 378e451b9f89..4efa25e553e6 100644
--- a/sw/source/core/layout/findfrm.cxx
+++ b/sw/source/core/layout/findfrm.cxx
@@ -18,6 +18,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1973,4 +1974,14 @@ const SwPageFrame* SwFrame::DynCastPageFrame() const
 return IsPageFrame() ? static_cast(this) : nullptr;
 }
 
+SwColumnFrame* SwFrame::DynCastColumnFrame()
+{
+return IsColumnFrame() ? static_cast(this) : nullptr;
+}
+
+const SwColumnFrame* SwFrame::DynCastColumnFrame() const
+{
+return IsColumnFrame() ? static_cast(this) : nullptr;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index c88990a5f663..3f18c2058122 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -5195,13 +5195,6 @@ ErrCode SwWW8ImplReader::CoreLoad(WW8Glossary const 
*pGloss)
 if( m_xWDop->nEdn )
 aInfo.m_nFootnoteOffset = m_xWDop->nEdn - 1;
 m_rDoc.SetEndNoteInfo( aInfo );
-
-if (m_xSBase->GetEndnoteCount() > 2)
-{
-// This compatibility flag only works in easy cases, disable it 
for anything non-trivial
-// for now.
-
m_rDoc.getIDocumentSettingAccess().set(DocumentSettingId::CONTINUOUS_ENDNOTES, 
false);
-}
 }
 
 if (m_xWwFib->m_lcbPlcfhdd)


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: 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 b969e692000f50aafacc2eb577f545b8836dcc26
Author: Miklos Vajna 
AuthorDate: Fri May 17 08:07:23 2024 +0200
Commit: Miklos Vajna 
CommitDate: Fri May 17 09:21:37 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

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 ea27716aaeed..6e8112308002 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 'distro/collabora/co-24.04' - sw/qa sw/source

2024-05-16 Thread Miklos Vajna (via logerrit)
 sw/qa/core/layout/data/inline-endnote-and-section.odt |binary
 sw/qa/core/layout/ftnfrm.cxx  |   18 ++
 sw/source/core/layout/ftnfrm.cxx  |   16 +++-
 3 files changed, 33 insertions(+), 1 deletion(-)

New commits:
commit a8216967ebe242c379b7df1267836c4ec5a566a4
Author: Miklos Vajna 
AuthorDate: Wed May 15 13:25:13 2024 +0200
Commit: Caolán McNamara 
CommitDate: Thu May 16 16:02:17 2024 +0200

tdf#161083 sw continuous endnotes: fix layout with a section at doc end

Open the bugdoc, notice warnings like:

warn:legacy.osl:15059:15059:sw/source/core/layout/wsfrm.cxx:910: Frame tree 
is inconsistent.

Which means we try to insert the new section frame under body frame, but
the insert point is behind a frame which is not a direct child of the
body frame.

This went wrong in commit 6885dcd7ec7b82a946d8344bfc27a3e88eecc44a
(tdf#160984 sw continuous endnotes: switch to a section-based layout,
2024-05-14), where I didn't consider the case of having a continuous
section break at the Word doc end, which maps to a section frame before
the section frame of the endnotes in Writer.

Fix the problem by walking up the parent chain till we find the last
direct child of the body frame, which is typically not required, except
when having one or more (nested) section frames at the end of the
document.

Interestingly tdf#143456 had the same problem, which was the bugdoc to
trigger the revert of the old continuous endnotes code for DOCX in
eeda1b35a6e87d5349545464da33d997c52f15e3 (Revert "tdf#58521 DOCX import:
enable ContinuousEndnotes compat flag", 2021-08-10).

(cherry picked from commit 82dd81a9d2049ac95535880fc67c1867f90e1427)

Change-Id: I664672b91087217008a42120e8201c39e2a0a423
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167728
Reviewed-by: Caolán McNamara 
Tested-by: Caolán McNamara 
Tested-by: Jenkins CollaboraOffice 

diff --git a/sw/qa/core/layout/data/inline-endnote-and-section.odt 
b/sw/qa/core/layout/data/inline-endnote-and-section.odt
new file mode 100644
index ..4518904f6009
Binary files /dev/null and 
b/sw/qa/core/layout/data/inline-endnote-and-section.odt differ
diff --git a/sw/qa/core/layout/ftnfrm.cxx b/sw/qa/core/layout/ftnfrm.cxx
index 71fd3fd67150..1cf31809e5a7 100644
--- a/sw/qa/core/layout/ftnfrm.cxx
+++ b/sw/qa/core/layout/ftnfrm.cxx
@@ -84,4 +84,22 @@ CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteAndFootnote)
 CPPUNIT_ASSERT_LESS(nFootnoteTop, nEndnoteTop);
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteAndSection)
+{
+// Given a document ending with a section, ContinuousEndnotes is true:
+createSwDoc("inline-endnote-and-section.odt");
+
+// When laying out that document:
+xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+// Then make sure the endnote section is after the section at the end of 
the document, not
+// inside it:
+int nToplevelSections = countXPathNodes(pXmlDoc, 
"/root/page/body/section"_ostr);
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected: 2
+// - Actual  : 1
+// and we even crashed on shutdown.
+CPPUNIT_ASSERT_EQUAL(2, nToplevelSections);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/ftnfrm.cxx b/sw/source/core/layout/ftnfrm.cxx
index 4be87ee57ccd..61a8385d51fc 100644
--- a/sw/source/core/layout/ftnfrm.cxx
+++ b/sw/source/core/layout/ftnfrm.cxx
@@ -1560,7 +1560,21 @@ void SwFootnoteBossFrame::AppendFootnote( SwContentFrame 
*pRef, SwTextFootnote *
 {
 SwSection* pSwSection = 
pDoc->GetEndNoteInfo().GetSwSection(*pDoc);
 pEndnoteSection = new SwSectionFrame(*pSwSection, pPage);
-pEndnoteSection->InsertBehind(pPage->FindBodyCont(), 
pPage->FindLastBodyContent());
+SwLayoutFrame* pParent = pPage->FindBodyCont();
+SwFrame* pBefore = pPage->FindLastBodyContent();
+while (pBefore)
+{
+// Check if the last content frame is directly under the 
body frame or there is
+// something in-between, e.g. a section frame.
+if (pBefore->GetUpper() == pParent)
+{
+break;
+}
+
+// If so, insert behind the parent of the content frame, 
not inside the parent.
+pBefore = pBefore->GetUpper();
+}
+pEndnoteSection->InsertBehind(pParent, pBefore);
 pEndnoteSection->Init();
 pEndnoteSection->SetEndNoteSection(true);
 }


core.git: Branch 'distro/collabora/co-24.04' - sw/qa sw/source

2024-05-16 Thread Miklos Vajna (via logerrit)
 sw/qa/core/layout/data/inline-endnote-and-footnote.doc |binary
 sw/qa/core/layout/ftnfrm.cxx   |   21 +++
 sw/source/core/layout/flowfrm.cxx  |   37 -
 sw/source/core/layout/ftnfrm.cxx   |   45 ++---
 sw/source/core/text/txtftn.cxx |   10 ---
 5 files changed, 83 insertions(+), 30 deletions(-)

New commits:
commit ad3586d6c6b03d588a45610e1f091f83b16b83a2
Author: Miklos Vajna 
AuthorDate: Tue May 14 08:28:33 2024 +0200
Commit: Caolán McNamara 
CommitDate: Thu May 16 15:57:41 2024 +0200

tdf#160984 sw continuous endnotes: switch to a section-based layout

The original layout added in commit
4814e8caa5f06c4fe438dfd7d7315e4a2410ea18 (tdf#124601 sw: add
ContinuousEndnotes layout compat option, 2019-09-30) puts endnotes to
the footnote container on the last page, which fixes the page count but
the endnote position is wrong: should be after the body text, not at the
bottom of the page.

Now that we can have an endnote section (with one or more section frames
at a layout level), we have a container that can span over multiple
pages, is at the end of the document and is inline.

Fix the bad position by:

1) Reverting the layout changes from the old approach, which gives us a
   bad position for the endnote.

2) Creating an endnote section frame on demand in
   SwFootnoteBossFrame::AppendFootnote().

3) Moving part of the endnote to a next page works out of the box, but
   moving part of the endnote to a previous page needs explicit handling
   in SwFlowFrame::MoveBwd(), similar to how SwFrame::GetPrevSctLeaf()
   does this in the simple section case. This needs explicit handling,
   because the body frame of the endnote section is empty, all content goes
   to its endnote container.

Note that this just reimplements the compat flag, but its enablement
(only for DOC import, only for <= 2 endnotes) stays unchanged for now.

(cherry picked from commit 6885dcd7ec7b82a946d8344bfc27a3e88eecc44a)

Change-Id: I8b271895aeff378418aed8705fe6b99a69232bd2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167727
Tested-by: Jenkins CollaboraOffice 
Tested-by: Caolán McNamara 
Reviewed-by: Caolán McNamara 

diff --git a/sw/qa/core/layout/data/inline-endnote-and-footnote.doc 
b/sw/qa/core/layout/data/inline-endnote-and-footnote.doc
new file mode 100644
index ..39c5636e1e12
Binary files /dev/null and 
b/sw/qa/core/layout/data/inline-endnote-and-footnote.doc differ
diff --git a/sw/qa/core/layout/ftnfrm.cxx b/sw/qa/core/layout/ftnfrm.cxx
index 4c874202da3f..71fd3fd67150 100644
--- a/sw/qa/core/layout/ftnfrm.cxx
+++ b/sw/qa/core/layout/ftnfrm.cxx
@@ -63,4 +63,25 @@ CPPUNIT_TEST_FIXTURE(Test, testFlySplitFootnoteLayout)
 CPPUNIT_ASSERT(pPage->FindFootnoteCont());
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteAndFootnote)
+{
+// Given a DOC file with an endnote and then a footnote:
+createSwDoc("inline-endnote-and-footnote.doc");
+
+// When laying out that document:
+xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+// Then make sure the footnote is below the endnote:
+// Without the accompanying fix in place, this test would have failed with:
+// - xpath should match exactly 1 node
+// i.e. the endnote was also in the footnote container, not at the end of 
the body text.
+sal_Int32 nEndnoteTop
+= 
parseDump("/root/page/body/section/column/ftncont/ftn/infos/bounds"_ostr, 
"top"_ostr)
+  .toInt32();
+sal_Int32 nFootnoteTop
+= parseDump("/root/page/ftncont/ftn/infos/bounds"_ostr, 
"top"_ostr).toInt32();
+// Endnote at the end of body text, footnote at page bottom.
+CPPUNIT_ASSERT_LESS(nFootnoteTop, nEndnoteTop);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/flowfrm.cxx 
b/sw/source/core/layout/flowfrm.cxx
index 37fd20b323d7..1cb5cf7bf47a 100644
--- a/sw/source/core/layout/flowfrm.cxx
+++ b/sw/source/core/layout/flowfrm.cxx
@@ -2257,18 +2257,47 @@ bool SwFlowFrame::MoveBwd( bool  )
 const bool bEndnote = pFootnote->GetAttr()->GetFootnote().IsEndNote();
 const IDocumentSettingAccess& rSettings
 = pFootnote->GetAttrSet()->GetDoc()->getIDocumentSettingAccess();
-if( bEndnote && pFootnote->IsInSct() )
+bool bContEndnotes = 
rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES);
+if( bEndnote && pFootnote->IsInSct() && !bContEndnotes)
 {
 SwSectionFrame* pSect = pFootnote->FindSctFrame();
 if( pSect->IsEndnAtEnd() )
 // Endnotes at the end of the section.
 pRef = pSect->FindLastContent( SwFindMode::LastCnt );
 }
-else if (bEndnote && 
rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES))
+else 

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: sw/qa

2024-05-16 Thread Miklos Vajna (via logerrit)
 sw/qa/extras/rtfexport/rtfexport7.cxx | 1348 --
 1 file changed, 822 insertions(+), 526 deletions(-)

New commits:
commit 55eb6fc8b83fe2f846a4f7448271a5b0fe03fbfc
Author: Miklos Vajna 
AuthorDate: Thu May 16 08:00:20 2024 +0200
Commit: Miklos Vajna 
CommitDate: Thu May 16 08:48:06 2024 +0200

CppunitTest_sw_rtfexport7: avoid DECLARE_RTFEXPORT_TEST

No need to go via Writer-specific macros here.

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

diff --git a/sw/qa/extras/rtfexport/rtfexport7.cxx 
b/sw/qa/extras/rtfexport/rtfexport7.cxx
index d0803d6bcb74..57162cf30df1 100644
--- a/sw/qa/extras/rtfexport/rtfexport7.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport7.cxx
@@ -43,29 +43,41 @@ public:
 }
 };
 
-DECLARE_RTFEXPORT_TEST(testPictureWrapPolygon, "picture-wrap-polygon.rtf")
+CPPUNIT_TEST_FIXTURE(Test, testPictureWrapPolygon)
 {
-// The problem was that the wrap polygon was ignored during import.
-drawing::PointSequenceSequence aSeqSeq
-= getProperty(getShape(1), 
"ContourPolyPolygon");
-// This was 0: the polygon list was empty.
-CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aSeqSeq.getLength());
-
-drawing::PointSequence aSeq = aSeqSeq[0];
-CPPUNIT_ASSERT_EQUAL(sal_Int32(11), aSeq.getLength());
-
-// The shape also didn't have negative top / left coordinates.
-CPPUNIT_ASSERT_EQUAL(sal_Int32(convertTwipToMm100(-1177)),
- getProperty(getShape(1), 
"HoriOrientPosition"));
-CPPUNIT_ASSERT_EQUAL(sal_Int32(convertTwipToMm100(-67)),
- getProperty(getShape(1), 
"VertOrientPosition"));
+auto verify = [this]() {
+// The problem was that the wrap polygon was ignored during import.
+drawing::PointSequenceSequence aSeqSeq
+= getProperty(getShape(1), 
"ContourPolyPolygon");
+// This was 0: the polygon list was empty.
+CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aSeqSeq.getLength());
+
+drawing::PointSequence aSeq = aSeqSeq[0];
+CPPUNIT_ASSERT_EQUAL(sal_Int32(11), aSeq.getLength());
+
+// The shape also didn't have negative top / left coordinates.
+CPPUNIT_ASSERT_EQUAL(sal_Int32(convertTwipToMm100(-1177)),
+ getProperty(getShape(1), 
"HoriOrientPosition"));
+CPPUNIT_ASSERT_EQUAL(sal_Int32(convertTwipToMm100(-67)),
+ getProperty(getShape(1), 
"VertOrientPosition"));
+};
+createSwDoc("picture-wrap-polygon.rtf");
+verify();
+saveAndReload(mpFilter);
+verify();
 }
 
-DECLARE_RTFEXPORT_TEST(testTdf113408, "tdf113408.rtf")
+CPPUNIT_TEST_FIXTURE(Test, testTdf113408)
 {
-// This was 0, left margin was not inherited from style properly.
-CPPUNIT_ASSERT_EQUAL(static_cast(1270),
- getProperty(getParagraph(1), 
"ParaLeftMargin"));
+auto verify = [this]() {
+// This was 0, left margin was not inherited from style properly.
+CPPUNIT_ASSERT_EQUAL(static_cast(1270),
+ getProperty(getParagraph(1), 
"ParaLeftMargin"));
+};
+createSwDoc("tdf113408.rtf");
+verify();
+saveAndReload(mpFilter);
+verify();
 }
 
 CPPUNIT_TEST_FIXTURE(Test, testAbi10039)
@@ -85,30 +97,42 @@ CPPUNIT_TEST_FIXTURE(Test, testAbi10076)
 // Just make sure that we don't crash after exporting a fully calculated 
layout.
 }
 
-DECLARE_RTFEXPORT_TEST(testEm, "em.rtf")
+CPPUNIT_TEST_FIXTURE(Test, testEm)
 {
-// Test all possible cc* control words.
-CPPUNIT_ASSERT_EQUAL(text::FontEmphasis::NONE,
- getProperty(getRun(getParagraph(1), 1), 
"CharEmphasis"));
-CPPUNIT_ASSERT_EQUAL(text::FontEmphasis::DOT_ABOVE,
- getProperty(getRun(getParagraph(1), 2), 
"CharEmphasis"));
-CPPUNIT_ASSERT_EQUAL(text::FontEmphasis::ACCENT_ABOVE,
- getProperty(getRun(getParagraph(1), 3), 
"CharEmphasis"));
-// This was missing.
-CPPUNIT_ASSERT_EQUAL(text::FontEmphasis::CIRCLE_ABOVE,
- getProperty(getRun(getParagraph(1), 4), 
"CharEmphasis"));
-// This one, too.
-CPPUNIT_ASSERT_EQUAL(text::FontEmphasis::DOT_BELOW,
- getProperty(getRun(getParagraph(1), 5), 
"CharEmphasis"));
+auto verify = [this]() {
+// Test all possible cc* control words.
+CPPUNIT_ASSERT_EQUAL(text::FontEmphasis::NONE,
+ getProperty(getRun(getParagraph(1), 
1), "CharEmphasis"));
+CPPUNIT_ASSERT_EQUAL(text::FontEmphasis::DOT_ABOVE,
+ getProperty(getRun(getParagraph(1), 
2), "CharEmphasis"));
+CPPUNIT_ASSERT_EQUAL(text::FontEmphasis::ACCENT_ABOVE,
+ getProperty(getRun(getParagraph(1), 
3), "CharEmphasis"));
+// This was missing.
+

core.git: sw/qa sw/source

2024-05-15 Thread Miklos Vajna (via logerrit)
 sw/qa/core/layout/data/inline-endnote-and-section.odt |binary
 sw/qa/core/layout/ftnfrm.cxx  |   18 ++
 sw/source/core/layout/ftnfrm.cxx  |   16 +++-
 3 files changed, 33 insertions(+), 1 deletion(-)

New commits:
commit 82dd81a9d2049ac95535880fc67c1867f90e1427
Author: Miklos Vajna 
AuthorDate: Wed May 15 13:25:13 2024 +0200
Commit: Miklos Vajna 
CommitDate: Wed May 15 16:54:05 2024 +0200

tdf#161083 sw continuous endnotes: fix layout with a section at doc end

Open the bugdoc, notice warnings like:

warn:legacy.osl:15059:15059:sw/source/core/layout/wsfrm.cxx:910: Frame tree 
is inconsistent.

Which means we try to insert the new section frame under body frame, but
the insert point is behind a frame which is not a direct child of the
body frame.

This went wrong in commit 6885dcd7ec7b82a946d8344bfc27a3e88eecc44a
(tdf#160984 sw continuous endnotes: switch to a section-based layout,
2024-05-14), where I didn't consider the case of having a continuous
section break at the Word doc end, which maps to a section frame before
the section frame of the endnotes in Writer.

Fix the problem by walking up the parent chain till we find the last
direct child of the body frame, which is typically not required, except
when having one or more (nested) section frames at the end of the
document.

Interestingly tdf#143456 had the same problem, which was the bugdoc to
trigger the revert of the old continuous endnotes code for DOCX in
eeda1b35a6e87d5349545464da33d997c52f15e3 (Revert "tdf#58521 DOCX import:
enable ContinuousEndnotes compat flag", 2021-08-10).

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

diff --git a/sw/qa/core/layout/data/inline-endnote-and-section.odt 
b/sw/qa/core/layout/data/inline-endnote-and-section.odt
new file mode 100644
index ..4518904f6009
Binary files /dev/null and 
b/sw/qa/core/layout/data/inline-endnote-and-section.odt differ
diff --git a/sw/qa/core/layout/ftnfrm.cxx b/sw/qa/core/layout/ftnfrm.cxx
index 71fd3fd67150..1cf31809e5a7 100644
--- a/sw/qa/core/layout/ftnfrm.cxx
+++ b/sw/qa/core/layout/ftnfrm.cxx
@@ -84,4 +84,22 @@ CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteAndFootnote)
 CPPUNIT_ASSERT_LESS(nFootnoteTop, nEndnoteTop);
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteAndSection)
+{
+// Given a document ending with a section, ContinuousEndnotes is true:
+createSwDoc("inline-endnote-and-section.odt");
+
+// When laying out that document:
+xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+// Then make sure the endnote section is after the section at the end of 
the document, not
+// inside it:
+int nToplevelSections = countXPathNodes(pXmlDoc, 
"/root/page/body/section"_ostr);
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected: 2
+// - Actual  : 1
+// and we even crashed on shutdown.
+CPPUNIT_ASSERT_EQUAL(2, nToplevelSections);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/ftnfrm.cxx b/sw/source/core/layout/ftnfrm.cxx
index e03519ed3040..b7851a131e44 100644
--- a/sw/source/core/layout/ftnfrm.cxx
+++ b/sw/source/core/layout/ftnfrm.cxx
@@ -1585,7 +1585,21 @@ void SwFootnoteBossFrame::AppendFootnote( SwContentFrame 
*pRef, SwTextFootnote *
 {
 SwSection* pSwSection = 
pDoc->GetEndNoteInfo().GetSwSection(*pDoc);
 pEndnoteSection = new SwSectionFrame(*pSwSection, pPage);
-pEndnoteSection->InsertBehind(pPage->FindBodyCont(), 
pPage->FindLastBodyContent());
+SwLayoutFrame* pParent = pPage->FindBodyCont();
+SwFrame* pBefore = pPage->FindLastBodyContent();
+while (pBefore)
+{
+// Check if the last content frame is directly under the 
body frame or there is
+// something in-between, e.g. a section frame.
+if (pBefore->GetUpper() == pParent)
+{
+break;
+}
+
+// If so, insert behind the parent of the content frame, 
not inside the parent.
+pBefore = pBefore->GetUpper();
+}
+pEndnoteSection->InsertBehind(pParent, pBefore);
 pEndnoteSection->Init();
 pEndnoteSection->SetEndNoteSection(true);
 }


core.git: Branch 'distro/collabora/co-24.04' - sw/qa sw/source

2024-05-15 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 07c93a65d2c8579adb100b7ae0c312e1872a1f37
Author: Miklos Vajna 
AuthorDate: Tue May 14 13:49:51 2024 +0200
Commit: Caolán McNamara 
CommitDate: Wed May 15 13:45:49 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.

(cherry picked from commit 6025ac371bd5cd07c0af550d78db323ad394173b)

Change-Id: Ieb93facd8b2e7f6412fd20873c10ce6c8b775619
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167690
Tested-by: Jenkins CollaboraOffice 
Tested-by: Caolán McNamara 
Reviewed-by: Caolán McNamara 

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: sw/qa sw/source

2024-05-15 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 6025ac371bd5cd07c0af550d78db323ad394173b
Author: Miklos Vajna 
AuthorDate: Tue May 14 13:49:51 2024 +0200
Commit: Miklos Vajna 
CommitDate: Wed May 15 13:08:02 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

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 50dd45579e4b..ea27716aaeed 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: sw/qa sw/source

2024-05-14 Thread Miklos Vajna (via logerrit)
 sw/qa/core/layout/data/inline-endnote-and-footnote.doc |binary
 sw/qa/core/layout/ftnfrm.cxx   |   21 +++
 sw/source/core/layout/flowfrm.cxx  |   37 -
 sw/source/core/layout/ftnfrm.cxx   |   45 ++---
 sw/source/core/text/txtftn.cxx |   10 ---
 5 files changed, 83 insertions(+), 30 deletions(-)

New commits:
commit 6885dcd7ec7b82a946d8344bfc27a3e88eecc44a
Author: Miklos Vajna 
AuthorDate: Tue May 14 08:28:33 2024 +0200
Commit: Miklos Vajna 
CommitDate: Tue May 14 12:08:31 2024 +0200

tdf#160984 sw continuous endnotes: switch to a section-based layout

The original layout added in commit
4814e8caa5f06c4fe438dfd7d7315e4a2410ea18 (tdf#124601 sw: add
ContinuousEndnotes layout compat option, 2019-09-30) puts endnotes to
the footnote container on the last page, which fixes the page count but
the endnote position is wrong: should be after the body text, not at the
bottom of the page.

Now that we can have an endnote section (with one or more section frames
at a layout level), we have a container that can span over multiple
pages, is at the end of the document and is inline.

Fix the bad position by:

1) Reverting the layout changes from the old approach, which gives us a
   bad position for the endnote.

2) Creating an endnote section frame on demand in
   SwFootnoteBossFrame::AppendFootnote().

3) Moving part of the endnote to a next page works out of the box, but
   moving part of the endnote to a previous page needs explicit handling
   in SwFlowFrame::MoveBwd(), similar to how SwFrame::GetPrevSctLeaf()
   does this in the simple section case. This needs explicit handling,
   because the body frame of the endnote section is empty, all content goes
   to its endnote container.

Note that this just reimplements the compat flag, but its enablement
(only for DOC import, only for <= 2 endnotes) stays unchanged for now.

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

diff --git a/sw/qa/core/layout/data/inline-endnote-and-footnote.doc 
b/sw/qa/core/layout/data/inline-endnote-and-footnote.doc
new file mode 100644
index ..39c5636e1e12
Binary files /dev/null and 
b/sw/qa/core/layout/data/inline-endnote-and-footnote.doc differ
diff --git a/sw/qa/core/layout/ftnfrm.cxx b/sw/qa/core/layout/ftnfrm.cxx
index 4c874202da3f..71fd3fd67150 100644
--- a/sw/qa/core/layout/ftnfrm.cxx
+++ b/sw/qa/core/layout/ftnfrm.cxx
@@ -63,4 +63,25 @@ CPPUNIT_TEST_FIXTURE(Test, testFlySplitFootnoteLayout)
 CPPUNIT_ASSERT(pPage->FindFootnoteCont());
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteAndFootnote)
+{
+// Given a DOC file with an endnote and then a footnote:
+createSwDoc("inline-endnote-and-footnote.doc");
+
+// When laying out that document:
+xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+// Then make sure the footnote is below the endnote:
+// Without the accompanying fix in place, this test would have failed with:
+// - xpath should match exactly 1 node
+// i.e. the endnote was also in the footnote container, not at the end of 
the body text.
+sal_Int32 nEndnoteTop
+= 
parseDump("/root/page/body/section/column/ftncont/ftn/infos/bounds"_ostr, 
"top"_ostr)
+  .toInt32();
+sal_Int32 nFootnoteTop
+= parseDump("/root/page/ftncont/ftn/infos/bounds"_ostr, 
"top"_ostr).toInt32();
+// Endnote at the end of body text, footnote at page bottom.
+CPPUNIT_ASSERT_LESS(nFootnoteTop, nEndnoteTop);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/flowfrm.cxx 
b/sw/source/core/layout/flowfrm.cxx
index 37fd20b323d7..1cb5cf7bf47a 100644
--- a/sw/source/core/layout/flowfrm.cxx
+++ b/sw/source/core/layout/flowfrm.cxx
@@ -2257,18 +2257,47 @@ bool SwFlowFrame::MoveBwd( bool  )
 const bool bEndnote = pFootnote->GetAttr()->GetFootnote().IsEndNote();
 const IDocumentSettingAccess& rSettings
 = pFootnote->GetAttrSet()->GetDoc()->getIDocumentSettingAccess();
-if( bEndnote && pFootnote->IsInSct() )
+bool bContEndnotes = 
rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES);
+if( bEndnote && pFootnote->IsInSct() && !bContEndnotes)
 {
 SwSectionFrame* pSect = pFootnote->FindSctFrame();
 if( pSect->IsEndnAtEnd() )
 // Endnotes at the end of the section.
 pRef = pSect->FindLastContent( SwFindMode::LastCnt );
 }
-else if (bEndnote && 
rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES))
+else if (bEndnote && bContEndnotes)
 {
 // Endnotes at the end of the document.
-SwPageFrame* pPage = 

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

2024-05-14 Thread Miklos Vajna (via logerrit)
 sw/CppunitTest_sw_core_layout.mk  |1 
 sw/qa/core/layout/calcmove.cxx|   44 ++
 sw/qa/core/layout/data/ignore-top-margin.docx |binary
 sw/source/core/inc/frame.hxx  |3 +
 sw/source/core/layout/calcmove.cxx|   32 ++
 sw/source/core/layout/flowfrm.cxx |5 ++
 6 files changed, 85 insertions(+)

New commits:
commit abd90828cf101581a07b9d1c371a8c3156521e9f
Author: Miklos Vajna 
AuthorDate: Tue May 7 08:13:37 2024 +0200
Commit: Michael Stahl 
CommitDate: Tue May 14 11:15:21 2024 +0200

tdf#160952 sw: ignore top margin of para on non-first pages with newer DOCX

The 2nd page of the bugdoc has a single paragraph, with a non-zero top
margin. This is ignored in Word, but wasn't ignored in Writer.

Experimenting with the document, it looks like old Word files also don't
ignore this top margin: it started when the compat mode is upgraded
(from binary DOC or Word 2010) to Word 2023 or newer. Also the top
margin is only ignored for the first paragraph on the page, and only in
case it's not on the first page.

Fix the problem by introducing a new SwFrame::IsCollapseUpper() function
to decide if the upper margin should be collapsed or not, and then by
using it in SwFlowFrame::CalcUpperSpace() at one place where we read the
top margin from the doc model. Take advantage of the fact that we have
related, existing compat flags that tell us if we're in "Word >= 2013"
compat mode: see e.g. GetFlyAnchorBottom(), which explains
DocumentSettingId::TAB_OVER_MARGIN is a good indicator that this is a
"Word <= 2010" document. Also, DocumentSettingId::TAB_OVER_SPACING is an
indicator that this is a Word document, so we want the "TabOverSpacing
&& !TabOverMargin" case.

This doesn't change all reads of the upper spacing of a text node, but
is enough to avoid the unwanted top spacing, as demonstrated by the
bugdoc.

Change-Id: Ibdebdf5f0555256a0b6ed85d07079f14ef69a576
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167252
Reviewed-by: Miklos Vajna 
Tested-by: Jenkins
(cherry picked from commit 6200d89b905d51776ff4f3c8a84f338655ffaa7f)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167221
Reviewed-by: Michael Stahl 

diff --git a/sw/CppunitTest_sw_core_layout.mk b/sw/CppunitTest_sw_core_layout.mk
index 5eb874400d53..d64a43f7d3fb 100644
--- a/sw/CppunitTest_sw_core_layout.mk
+++ b/sw/CppunitTest_sw_core_layout.mk
@@ -14,6 +14,7 @@ $(eval $(call gb_CppunitTest_CppunitTest,sw_core_layout))
 $(eval $(call gb_CppunitTest_use_common_precompiled_header,sw_core_layout))
 
 $(eval $(call gb_CppunitTest_add_exception_objects,sw_core_layout, \
+sw/qa/core/layout/calcmove \
 sw/qa/core/layout/fly \
 sw/qa/core/layout/flycnt \
 sw/qa/core/layout/frmtool \
diff --git a/sw/qa/core/layout/calcmove.cxx b/sw/qa/core/layout/calcmove.cxx
new file mode 100644
index ..3e4deec52ae8
--- /dev/null
+++ b/sw/qa/core/layout/calcmove.cxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-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/.
+ */
+
+#include 
+
+#include 
+
+namespace
+{
+/// Covers sw/source/core/layout/calcmove.cxx fixes.
+class Test : public SwModelTestBase
+{
+public:
+Test()
+: SwModelTestBase("/sw/qa/core/layout/data/")
+{
+}
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testIgnoreTopMargin)
+{
+// Given a DOCX (>= Word 2013) file, with 2 pages:
+// When loading that document:
+createSwDoc("ignore-top-margin.docx");
+
+// Then make sure that the paragraph on the 2nd page has no top margin:
+xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+sal_Int32 nParaTopMargin
+= getXPath(pXmlDoc, "/root/page[2]/body/txt/infos/prtBounds"_ostr, 
"top"_ostr).toInt32();
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected: 0
+// - Actual  : 2400
+// 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);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/core/layout/data/ignore-top-margin.docx 
b/sw/qa/core/layout/data/ignore-top-margin.docx
new file mode 100644
index ..d05a1358db1e
Binary files /dev/null and b/sw/qa/core/layout/data/ignore-top-margin.docx 
differ
diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx
index 604488a18c9f..a86358508182 100644
--- a/sw/source/core/inc/frame.hxx
+++ b/sw/source/core/inc/frame.hxx
@@ -948,6 +948,9 @@ public:
 virtual void 

core.git: Branch 'distro/collabora/co-24.04' - sw/qa

2024-05-14 Thread Miklos Vajna (via logerrit)
 sw/qa/extras/layout/layout3.cxx |6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

New commits:
commit 48ee8fb96540e68a17599b5db505f9b056dc09f3
Author: Miklos Vajna 
AuthorDate: Mon May 13 08:37:22 2024 +0200
Commit: Caolán McNamara 
CommitDate: Tue May 14 10:25:05 2024 +0200

tdf#160984 sw continuous endnotes: fix CppunitTest_sw_layoutwriter3

These are similar to commit ab3416cad1dd4e706432f9b1a3592cec823c76b0
(tdf#160984 sw continuous endnotes: fix
testContinuousEndnotesMoveBackwards, 2024-05-10).

I've manually verified that the use-case still works as intended, so fix
the failing tests by relaxing the assert a bit: now we accept endnotes
directly under the page frame or under the column frame as well.

This way these tests won't break when we switch to section-based
continuous endnotes.

(cherry picked from commit 9c7acbc937b3b341c10187b837e09cc20399f04e)

Change-Id: Ib98d6277534cc2e934595f19927836744eec64d5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167624
Tested-by: Jenkins CollaboraOffice 
Reviewed-by: Caolán McNamara 

diff --git a/sw/qa/extras/layout/layout3.cxx b/sw/qa/extras/layout/layout3.cxx
index 98c77b18ecdf..d553162f1636 100644
--- a/sw/qa/extras/layout/layout3.cxx
+++ b/sw/qa/extras/layout/layout3.cxx
@@ -1315,7 +1315,7 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf124601)
 // i.e. there was a separate endnote page, even when the 
ContinuousEndnotes compat option was
 // on.
 assertXPath(pXmlDoc, "/root/page"_ostr, 2);
-assertXPath(pXmlDoc, "/root/page[2]/ftncont"_ostr, 1);
+assertXPath(pXmlDoc, "/root/page[2]//ftncont"_ostr, 1);
 }
 
 CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf124601b)
@@ -1425,7 +1425,7 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, 
testContinuousEndnotesInsertPageAtStart)
 // - Expected: 1
 // - Actual  : 0
 // i.e. the footnote container remained on page 2.
-assertXPath(pXmlDoc, "/root/page[3]/ftncont"_ostr, 1);
+assertXPath(pXmlDoc, "/root/page[3]//ftncont"_ostr, 1);
 }
 
 CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testContinuousEndnotesDeletePageAtStart)
@@ -1452,7 +1452,7 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, 
testContinuousEndnotesDeletePageAtStart)
 // - Actual  : 2
 // i.e. the endnote remained on an (otherwise) empty 2nd page.
 assertXPath(pXmlDoc, "/root/page"_ostr, 1);
-assertXPath(pXmlDoc, "/root/page[1]/ftncont"_ostr, 1);
+assertXPath(pXmlDoc, "/root/page[1]//ftncont"_ostr, 1);
 }
 
 CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf128399)


core.git: sw/qa

2024-05-13 Thread Miklos Vajna (via logerrit)
 sw/qa/extras/layout/layout3.cxx |6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

New commits:
commit 9c7acbc937b3b341c10187b837e09cc20399f04e
Author: Miklos Vajna 
AuthorDate: Mon May 13 08:37:22 2024 +0200
Commit: Miklos Vajna 
CommitDate: Mon May 13 12:15:08 2024 +0200

tdf#160984 sw continuous endnotes: fix CppunitTest_sw_layoutwriter3

These are similar to commit ab3416cad1dd4e706432f9b1a3592cec823c76b0
(tdf#160984 sw continuous endnotes: fix
testContinuousEndnotesMoveBackwards, 2024-05-10).

I've manually verified that the use-case still works as intended, so fix
the failing tests by relaxing the assert a bit: now we accept endnotes
directly under the page frame or under the column frame as well.

This way these tests won't break when we switch to section-based
continuous endnotes.

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

diff --git a/sw/qa/extras/layout/layout3.cxx b/sw/qa/extras/layout/layout3.cxx
index e907f6bc8ebf..329c81847313 100644
--- a/sw/qa/extras/layout/layout3.cxx
+++ b/sw/qa/extras/layout/layout3.cxx
@@ -1444,7 +1444,7 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf124601)
 // i.e. there was a separate endnote page, even when the 
ContinuousEndnotes compat option was
 // on.
 assertXPath(pXmlDoc, "/root/page"_ostr, 2);
-assertXPath(pXmlDoc, "/root/page[2]/ftncont"_ostr, 1);
+assertXPath(pXmlDoc, "/root/page[2]//ftncont"_ostr, 1);
 }
 
 CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf124601b)
@@ -1554,7 +1554,7 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, 
testContinuousEndnotesInsertPageAtStart)
 // - Expected: 1
 // - Actual  : 0
 // i.e. the footnote container remained on page 2.
-assertXPath(pXmlDoc, "/root/page[3]/ftncont"_ostr, 1);
+assertXPath(pXmlDoc, "/root/page[3]//ftncont"_ostr, 1);
 }
 
 CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testContinuousEndnotesDeletePageAtStart)
@@ -1581,7 +1581,7 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, 
testContinuousEndnotesDeletePageAtStart)
 // - Actual  : 2
 // i.e. the endnote remained on an (otherwise) empty 2nd page.
 assertXPath(pXmlDoc, "/root/page"_ostr, 1);
-assertXPath(pXmlDoc, "/root/page[1]/ftncont"_ostr, 1);
+assertXPath(pXmlDoc, "/root/page[1]//ftncont"_ostr, 1);
 }
 
 CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf128399)


core.git: Branch 'distro/collabora/co-24.04' - sw/qa

2024-05-13 Thread Miklos Vajna (via logerrit)
 sw/qa/core/layout/layout.cxx |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

New commits:
commit b6f42a6006dd0b0e4234ed5e0f536b7f4d8a
Author: Miklos Vajna 
AuthorDate: Fri May 10 08:07:41 2024 +0200
Commit: Caolán McNamara 
CommitDate: Mon May 13 12:06:55 2024 +0200

tdf#160984 sw continuous endnotes: fix testContinuousEndnotesMoveBackwards

Once continuous endnotes are in a section, this failed, even if the
generated layout is an improvement.

The layout will put the endnotes to a section, which will be directly
after the end of the body text, which is closer to what Word does, but
makes the test fail, since the foot/endnote container is no longer
directly under the page frame (the new tree is page -> body -> section
-> column -> ftncont).

Fix the problem by relaxing the assert to only check which pages have
footnote containers, which passes with and without the move to
section-based continuous endnotes, but still fails if endnotes go to
their own page, which was the original problem to be tested (endnotes
remained on page 3 and didn't move backwards).

The assert for the number of pages can remain unchanged.

(cherry picked from commit ab3416cad1dd4e706432f9b1a3592cec823c76b0)

Change-Id: I9a46803463c82dac317c303721de30fae48c6924
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167579
Reviewed-by: Caolán McNamara 
Tested-by: Jenkins CollaboraOffice 

diff --git a/sw/qa/core/layout/layout.cxx b/sw/qa/core/layout/layout.cxx
index 5971e870304d..9cae825b38b4 100644
--- a/sw/qa/core/layout/layout.cxx
+++ b/sw/qa/core/layout/layout.cxx
@@ -179,9 +179,9 @@ CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, 
testContinuousEndnotesMoveBackwards)
 // - Expected: 0
 // - Actual  : 1
 // i.e. there were unexpected endnotes on page 1.
-assertXPath(pLayout, "/root/page[1]/ftncont"_ostr, 0);
+assertXPath(pLayout, "/root/page[1]//ftncont"_ostr, 0);
 // All endnotes are in a container on page 2.
-assertXPath(pLayout, "/root/page[2]/ftncont"_ostr, 1);
+assertXPath(pLayout, "/root/page[2]//ftncont"_ostr, 1);
 }
 
 CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, testAnchorPositionBasedOnParagraph)


core.git: include/svx svx/source

2024-05-13 Thread Miklos Vajna (via logerrit)
 include/svx/svdundo.hxx   |   10 +++
 svx/source/svdraw/svdundo.cxx |   56 +-
 2 files changed, 33 insertions(+), 33 deletions(-)

New commits:
commit 74bd51629eed7eb34aef9acbb93c110525f8ef7d
Author: Miklos Vajna 
AuthorDate: Mon May 13 08:33:27 2024 +0200
Commit: Miklos Vajna 
CommitDate: Mon May 13 10:32:50 2024 +0200

svx: prefix members of SdrUndoAttrObj

See tdf#94879 for motivation.

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

diff --git a/include/svx/svdundo.hxx b/include/svx/svdundo.hxx
index 824f36f06efc..5af5c584eda1 100644
--- a/include/svx/svdundo.hxx
+++ b/include/svx/svdundo.hxx
@@ -155,17 +155,17 @@ class SVXCORE_DLLPUBLIC SdrUndoAttrObj : public SdrUndoObj
 // FIXME: Or should we better remember the StyleSheetNames?
 rtl::Reference< SfxStyleSheet > mxUndoStyleSheet;
 rtl::Reference< SfxStyleSheet > mxRedoStyleSheet;
-bool bStyleSheet;
-bool bHaveToTakeRedoSet;
+bool m_bStyleSheet;
+bool m_bHaveToTakeRedoSet;
 
 // When assigning TextItems to a drawing object with text:
-std::optional pTextUndo;
+std::optional m_pTextUndo;
 // #i8508#
 // The text rescue mechanism needs also to be implemented for redo actions.
-std::optional pTextRedo;
+std::optional m_pTextRedo;
 
 // If we have a group object:
-std::unique_ptr pUndoGroup;
+std::unique_ptr m_pUndoGroup;
 
 protected:
 // Helper to ensure StyleSheet is in pool (provided by SdrModel from 
SdrObject)
diff --git a/svx/source/svdraw/svdundo.cxx b/svx/source/svdraw/svdundo.cxx
index 18b248ba5960..1b52ee945957 100644
--- a/svx/source/svdraw/svdundo.cxx
+++ b/svx/source/svdraw/svdundo.cxx
@@ -250,9 +250,9 @@ void 
SdrUndoAttrObj::ensureStyleSheetInStyleSheetPool(SfxStyleSheetBasePool& rSt
 
 SdrUndoAttrObj::SdrUndoAttrObj(SdrObject& rNewObj, bool bStyleSheet1, bool 
bSaveText)
 : SdrUndoObj(rNewObj)
-, bHaveToTakeRedoSet(true)
+, m_bHaveToTakeRedoSet(true)
 {
-bStyleSheet = bStyleSheet1;
+m_bStyleSheet = bStyleSheet1;
 
 SdrObjList* pOL = rNewObj.GetSubList();
 bool bIsGroup(pOL!=nullptr && pOL->GetObjCount());
@@ -261,11 +261,11 @@ SdrUndoAttrObj::SdrUndoAttrObj(SdrObject& rNewObj, bool 
bStyleSheet1, bool bSave
 if(bIsGroup)
 {
 // it's a group object!
-pUndoGroup.reset(new SdrUndoGroup(mxObj->getSdrModelFromSdrObject()));
+m_pUndoGroup.reset(new 
SdrUndoGroup(mxObj->getSdrModelFromSdrObject()));
 
 for (const rtl::Reference& pObj : *pOL)
 {
-pUndoGroup->AddAction(
+m_pUndoGroup->AddAction(
 std::make_unique(*pObj, bStyleSheet1));
 }
 }
@@ -275,14 +275,14 @@ SdrUndoAttrObj::SdrUndoAttrObj(SdrObject& rNewObj, bool 
bStyleSheet1, bool bSave
 
 moUndoSet.emplace( mxObj->GetMergedItemSet() );
 
-if(bStyleSheet)
+if(m_bStyleSheet)
 mxUndoStyleSheet = mxObj->GetStyleSheet();
 
 if(bSaveText)
 {
 auto p = mxObj->GetOutlinerParaObject();
 if(p)
-pTextUndo = *p;
+m_pTextUndo = *p;
 }
 }
 
@@ -290,9 +290,9 @@ SdrUndoAttrObj::~SdrUndoAttrObj()
 {
 moUndoSet.reset();
 moRedoSet.reset();
-pUndoGroup.reset();
-pTextUndo.reset();
-pTextRedo.reset();
+m_pUndoGroup.reset();
+m_pTextUndo.reset();
+m_pTextRedo.reset();
 }
 
 void SdrUndoAttrObj::Undo()
@@ -303,27 +303,27 @@ void SdrUndoAttrObj::Undo()
 // Trigger PageChangeCall
 ImpShowPageOfThisObject();
 
-if(!pUndoGroup || bIs3DScene)
+if(!m_pUndoGroup || bIs3DScene)
 {
-if(bHaveToTakeRedoSet)
+if(m_bHaveToTakeRedoSet)
 {
-bHaveToTakeRedoSet = false;
+m_bHaveToTakeRedoSet = false;
 
 moRedoSet.emplace( mxObj->GetMergedItemSet() );
 
-if(bStyleSheet)
+if(m_bStyleSheet)
 mxRedoStyleSheet = mxObj->GetStyleSheet();
 
-if(pTextUndo)
+if(m_pTextUndo)
 {
 // #i8508#
 auto p = mxObj->GetOutlinerParaObject();
 if(p)
-pTextRedo = *p;
+m_pTextRedo = *p;
 }
 }
 
-if(bStyleSheet)
+if(m_bStyleSheet)
 {
 mxRedoStyleSheet = mxObj->GetStyleSheet();
 SfxStyleSheet* pSheet = mxUndoStyleSheet.get();
@@ -392,15 +392,15 @@ void SdrUndoAttrObj::Undo()
 
 mxObj->GetProperties().BroadcastItemChange(aItemChange);
 
-if(pTextUndo)
+if(m_pTextUndo)
 {
-mxObj->SetOutlinerParaObject(*pTextUndo);
+mxObj->SetOutlinerParaObject(*m_pTextUndo);
 }
 }
 
-if(pUndoGroup)
+if(m_pUndoGroup)
 {
-pUndoGroup->Undo();
+m_pUndoGroup->Undo();
 }
 }
 
@@ 

core.git: Branch 'distro/collabora/co-24.04' - sw/source

2024-05-10 Thread Miklos Vajna (via logerrit)
 sw/source/core/inc/pagefrm.hxx|1 +
 sw/source/core/inc/sectfrm.hxx|4 
 sw/source/core/layout/findfrm.cxx |   23 +++
 sw/source/core/layout/sectfrm.cxx |1 +
 4 files changed, 29 insertions(+)

New commits:
commit e747e6df648a7ff076663ab376a4dbbc041b5180
Author: Miklos Vajna 
AuthorDate: Thu May 9 08:20:21 2024 +0200
Commit: Caolán McNamara 
CommitDate: Fri May 10 16:03:56 2024 +0200

tdf#160984 sw continuous endnotes: add a way to find the endnote section 
start

Existing code with endnotes on separate page at the end of the document
works by searching for a current or next page that is an endnote page in
SwFootnoteBossFrame::AppendFootnote(), and in case none is found, then
an endnote page is created.

Add similar infrastructure for the inline endnotes case: here we want to
find the first page that has an endnotes section, which also requires
being able to tell if a section is an endnotes one.

The newly introduced SwPageFrame::GetEndNoteSection() is not yet used in
SwFootnoteBossFrame::AppendFootnote(), though.

(cherry picked from commit 8bae684c93bd23bbe98707ba9cf75d1a39427131)

Change-Id: Ib08267f9bf6c7b06576624e3fa8e90e8b8b1b232
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167478
Tested-by: Caolán McNamara 
Reviewed-by: Caolán McNamara 
Tested-by: Jenkins CollaboraOffice 

diff --git a/sw/source/core/inc/pagefrm.hxx b/sw/source/core/inc/pagefrm.hxx
index 54458032f188..054495eeea80 100644
--- a/sw/source/core/inc/pagefrm.hxx
+++ b/sw/source/core/inc/pagefrm.hxx
@@ -204,6 +204,7 @@ public:
 bool IsEndNotePage() const  { return m_bEndNotePage; }
 void SetFootnotePage( bool b )   { m_bFootnotePage = 
b; }
 void SetEndNotePage( bool b )   { m_bEndNotePage = b; }
+SwSectionFrame* GetEndNoteSection();
 
 sal_uInt16 GetPhyPageNum() const{ return m_nPhyPageNum;}
 void SetPhyPageNum( sal_uInt16 nNum )   { m_nPhyPageNum = nNum;}
diff --git a/sw/source/core/inc/sectfrm.hxx b/sw/source/core/inc/sectfrm.hxx
index 3debf367f05a..ac57bd815d5f 100644
--- a/sw/source/core/inc/sectfrm.hxx
+++ b/sw/source/core/inc/sectfrm.hxx
@@ -52,6 +52,8 @@ class SW_DLLPUBLIC SwSectionFrame final: public 
SwLayoutFrame, public SwFlowFram
 SwSection* m_pSection;
 bool m_bFootnoteAtEnd; // footnotes at the end of section
 bool m_bEndnAtEnd; // endnotes at the end of section
+/// If this is a section for endnotes, then the SwSection is not backed by 
an SwSectionNode.
+bool m_bEndNoteSection = false;
 bool m_bContentLock; // content locked
 bool m_bOwnFootnoteNum; // special numbering of footnotes
 bool m_bFootnoteLock; // ftn, don't leave this section bwd
@@ -171,6 +173,8 @@ public:
 
 void SetFootnoteLock( bool bNew ) { m_bFootnoteLock = bNew; }
 bool IsFootnoteLock() const { return m_bFootnoteLock; }
+void SetEndNoteSection(bool bEndNoteSection) { m_bEndNoteSection = 
bEndNoteSection; }
+bool IsEndNoteSection() const { return m_bEndNoteSection; }
 };
 
 inline const SwSectionFrame *SwSectionFrame::GetFollow() const
diff --git a/sw/source/core/layout/findfrm.cxx 
b/sw/source/core/layout/findfrm.cxx
index 0dd64c6aecff..378e451b9f89 100644
--- a/sw/source/core/layout/findfrm.cxx
+++ b/sw/source/core/layout/findfrm.cxx
@@ -65,6 +65,29 @@ SwContentFrame *SwPageFrame::FindLastBodyContent()
 return pRet;
 }
 
+SwSectionFrame* SwPageFrame::GetEndNoteSection()
+{
+SwLayoutFrame* pBody = FindBodyCont();
+if (!pBody)
+{
+return nullptr;
+}
+
+SwFrame* pLast = pBody->GetLastLower();
+if (!pLast || !pLast->IsSctFrame())
+{
+return nullptr;
+}
+
+auto pLastSection = static_cast(pLast);
+if (!pLastSection->IsEndNoteSection())
+{
+return nullptr;
+}
+
+return pLastSection;
+}
+
 /**
  * Checks if the frame contains one or more ContentFrame's anywhere in his
  * subsidiary structure; if so the first found ContentFrame is returned.
diff --git a/sw/source/core/layout/sectfrm.cxx 
b/sw/source/core/layout/sectfrm.cxx
index 3967a1f56442..78278da9cb38 100644
--- a/sw/source/core/layout/sectfrm.cxx
+++ b/sw/source/core/layout/sectfrm.cxx
@@ -94,6 +94,7 @@ SwSectionFrame::SwSectionFrame( SwSectionFrame , bool 
bMaster ) :
 m_bOwnFootnoteNum( false ),
 m_bFootnoteLock( false )
 {
+m_bEndNoteSection = rSect.m_bEndNoteSection;
 StartListening(rSect.GetFormat()->GetNotifier());
 
 mnFrameType = SwFrameType::Section;


core.git: sw/qa

2024-05-10 Thread Miklos Vajna (via logerrit)
 sw/qa/core/layout/layout.cxx |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

New commits:
commit ab3416cad1dd4e706432f9b1a3592cec823c76b0
Author: Miklos Vajna 
AuthorDate: Fri May 10 08:07:41 2024 +0200
Commit: Miklos Vajna 
CommitDate: Fri May 10 09:05:24 2024 +0200

tdf#160984 sw continuous endnotes: fix testContinuousEndnotesMoveBackwards

Once continuous endnotes are in a section, this failed, even if the
generated layout is an improvement.

The layout will put the endnotes to a section, which will be directly
after the end of the body text, which is closer to what Word does, but
makes the test fail, since the foot/endnote container is no longer
directly under the page frame (the new tree is page -> body -> section
-> column -> ftncont).

Fix the problem by relaxing the assert to only check which pages have
footnote containers, which passes with and without the move to
section-based continuous endnotes, but still fails if endnotes go to
their own page, which was the original problem to be tested (endnotes
remained on page 3 and didn't move backwards).

The assert for the number of pages can remain unchanged.

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

diff --git a/sw/qa/core/layout/layout.cxx b/sw/qa/core/layout/layout.cxx
index 5971e870304d..9cae825b38b4 100644
--- a/sw/qa/core/layout/layout.cxx
+++ b/sw/qa/core/layout/layout.cxx
@@ -179,9 +179,9 @@ CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, 
testContinuousEndnotesMoveBackwards)
 // - Expected: 0
 // - Actual  : 1
 // i.e. there were unexpected endnotes on page 1.
-assertXPath(pLayout, "/root/page[1]/ftncont"_ostr, 0);
+assertXPath(pLayout, "/root/page[1]//ftncont"_ostr, 0);
 // All endnotes are in a container on page 2.
-assertXPath(pLayout, "/root/page[2]/ftncont"_ostr, 1);
+assertXPath(pLayout, "/root/page[2]//ftncont"_ostr, 1);
 }
 
 CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, testAnchorPositionBasedOnParagraph)


core.git: Branch 'distro/collabora/co-24.04' - sw/inc sw/source

2024-05-09 Thread Miklos Vajna (via logerrit)
 sw/inc/ftninfo.hxx|5 +
 sw/source/core/doc/docftn.cxx |   19 +++
 sw/source/core/doc/docnew.cxx |1 +
 3 files changed, 25 insertions(+)

New commits:
commit 3ac458599fd3dd532c9b4cc02ffa446d1a0e3dc2
Author: Miklos Vajna 
AuthorDate: Wed May 8 08:59:47 2024 +0200
Commit: Caolán McNamara 
CommitDate: Thu May 9 17:12:24 2024 +0200

tdf#160984 sw continuous endnotes: introduce an endnote section

Word lays out endnotes at the end of the document inline after body
text, Writer puts them on one or more separate endnote pages.

There was already an attempt in the past to resolve this difference, see
commit 4814e8caa5f06c4fe438dfd7d7315e4a2410ea18 (tdf#124601 sw: add
ContinuousEndnotes layout compat option, 2019-09-30). The approach back
then was to map such endnotes to footnotes, so the extra, unwanted page
doesn't appear. This turned out to be not working too well, the compat
option is only enabled for DOC, and even there commit
dc11f5b151e1a2ea2623fc8cf806a400763955d9 (tdf#143445 DOC import: limit
the usage of the CONTINUOUS_ENDNOTES compat flag, 2023-05-23) limited
the usage of the compat flag to 1 or 2 endnotes only.

Coming back to this, try a new approach: create a section that more or
less exists only at a layout level and put endnotes into that section.
This allows reusing all the complex logic on how to lay out endnotes
inline, on one or more pages. The plan is that this new approach is more
robust, can replace the old continuous endnotes layout code and then can
be enabled for DOCX as well.

This commit just introduces the backing section format and SwSection for
that special "endnotes section" (it's special because SwSection is
usually owned by an SwSectionNode, but here there is no doc model node
for the SwSection), SwFootnoteBossFrame::AppendFootnote() doesn't try to
use the new SwEndNoteInfo::GetSwSection() yet.

(cherry picked from commit 90f19126fa405a0632eae4ee8525b66bbce12625)

Change-Id: Ib32f04ceb6f46c682a5d36bdcea206d2c4017227
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167387
Reviewed-by: Caolán McNamara 
Tested-by: Jenkins CollaboraOffice 

diff --git a/sw/inc/ftninfo.hxx b/sw/inc/ftninfo.hxx
index 17742687c944..c5490ed885d0 100644
--- a/sw/inc/ftninfo.hxx
+++ b/sw/inc/ftninfo.hxx
@@ -28,12 +28,14 @@ class SwTextFormatColl;
 class SwPageDesc;
 class SwCharFormat;
 class SwDoc;
+class SwSection;
 
 class SW_DLLPUBLIC SwEndNoteInfo : public SwClient
 {
 mutable sw::WriterMultiListener m_aDepends;
 mutable SwTextFormatColl* m_pTextFormatColl;
 mutable SwPageDesc* m_pPageDesc;
+mutable std::unique_ptr m_pSwSection;
 mutable SwCharFormat* m_pCharFormat;
 mutable SwCharFormat* m_pAnchorFormat;
 OUString m_sPrefix;
@@ -51,6 +53,9 @@ public:
 bool KnowsPageDesc() const;
 bool DependsOn(const SwPageDesc*) const;
 
+SwSection* GetSwSection(SwDoc& rDoc) const;
+void ResetSwSection();
+
 void SetFootnoteTextColl(SwTextFormatColl& rColl);
 SwTextFormatColl* GetFootnoteTextColl() const { return m_pTextFormatColl; 
} // can be 0.
 
diff --git a/sw/source/core/doc/docftn.cxx b/sw/source/core/doc/docftn.cxx
index 16f6694c94c5..f211dcdcc9f4 100644
--- a/sw/source/core/doc/docftn.cxx
+++ b/sw/source/core/doc/docftn.cxx
@@ -35,6 +35,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 SwEndNoteInfo& SwEndNoteInfo::operator=(const SwEndNoteInfo& rInfo)
 {
@@ -130,6 +132,23 @@ void SwEndNoteInfo::ChgPageDesc(SwPageDesc* pDesc)
 m_aDepends.StartListening(m_pPageDesc);
 }
 
+SwSection* SwEndNoteInfo::GetSwSection(SwDoc& rDoc) const
+{
+if (!m_pSwSection)
+{
+SwSectionFormat* pFormat = rDoc.MakeSectionFormat();
+pFormat->SetFormatName(UNO_NAME_ENDNOTE);
+pFormat->SetFormatAttr(SwFormatEndAtTextEnd(FTNEND_ATTXTEND));
+m_pSwSection.reset(new SwSection(SectionType::Content, 
pFormat->GetName(), *pFormat));
+}
+return m_pSwSection.get();
+}
+
+void SwEndNoteInfo::ResetSwSection()
+{
+m_pSwSection.reset();
+}
+
 void SwEndNoteInfo::SetFootnoteTextColl(SwTextFormatColl& rFormat)
 {
 m_aDepends.EndListening(m_pTextFormatColl);
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index d6e885e8219a..bb0cd32d2c19 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -503,6 +503,7 @@ SwDoc::~SwDoc()
 // do not have any dependencies anymore.
 m_pNodes->DelNodes( SwNodeIndex(*m_pNodes), m_pNodes->Count() );
 rUndoNodes.DelNodes( SwNodeIndex( rUndoNodes ), rUndoNodes.Count() );
+mpEndNoteInfo->ResetSwSection();
 
 // clear TOX after nodes - TOXMarks are gone now so SwTOXType has no 
clients
 for (const auto& pType : *mpTOXTypes)


core.git: Branch 'distro/collabora/co-24.04' - sw/source

2024-05-09 Thread Miklos Vajna (via logerrit)
 sw/source/uibase/shells/drwbassh.cxx |   18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

New commits:
commit 0f7127aa6019363d15a167ab492ba06e0347174a
Author: Miklos Vajna 
AuthorDate: Thu May 9 13:09:43 2024 +0200
Commit: Caolán McNamara 
CommitDate: Thu May 9 14:59:53 2024 +0200

sw: fix -Wshadow warnings


/home/vmiklos/git/libreoffice/co-24.04/sw/source/uibase/shells/drwbassh.cxx: In 
lambda function:

/home/vmiklos/git/libreoffice/co-24.04/sw/source/uibase/shells/drwbassh.cxx:656:38:
 error: declaration of ‘aTitle’ shadows a previous local [-Werror=shadow]
  656 | OUString aTitle;
  |  ^~

/home/vmiklos/git/libreoffice/co-24.04/sw/source/uibase/shells/drwbassh.cxx:643:26:
 note: shadowed declaration is here
  643 | OUString aTitle(pSelected->GetTitle());
  |  ^~

/home/vmiklos/git/libreoffice/co-24.04/sw/source/uibase/shells/drwbassh.cxx:657:38:
 error: declaration of ‘aDescription’ shadows a previous local [-Werror=shadow]
  657 | OUString aDescription;
  |  ^~~~

/home/vmiklos/git/libreoffice/co-24.04/sw/source/uibase/shells/drwbassh.cxx:644:26:
 note: shadowed declaration is here
  644 | OUString 
aDescription(pSelected->GetDescription());
  |  ^~~~

/home/vmiklos/git/libreoffice/co-24.04/sw/source/uibase/shells/drwbassh.cxx:658:34:
 error: declaration of ‘isDecorative’ shadows a previous local [-Werror=shadow]
  658 | bool isDecorative;
  |  ^~~~

/home/vmiklos/git/libreoffice/co-24.04/sw/source/uibase/shells/drwbassh.cxx:645:22:
 note: shadowed declaration is here
  645 | bool 
isDecorative(pSelected->IsDecorative());
  |  ^~~~
cc1plus: all warnings being treated as errors

Change-Id: I9f62f028d29a4014628435163f8ff9174251bfb2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167382
Tested-by: Jenkins CollaboraOffice 
Reviewed-by: Caolán McNamara 

diff --git a/sw/source/uibase/shells/drwbassh.cxx 
b/sw/source/uibase/shells/drwbassh.cxx
index ebd1eb3ce705..c98e97eb7aba 100644
--- a/sw/source/uibase/shells/drwbassh.cxx
+++ b/sw/source/uibase/shells/drwbassh.cxx
@@ -653,17 +653,17 @@ void SwDrawBaseShell::Execute(SfxRequest const )
 {
 if (nResult == RET_OK)
 {
-OUString aTitle;
-OUString aDescription;
-bool isDecorative;
+OUString aNewTitle;
+OUString aNewDescription;
+bool newIsDecorative;
 
-pDlg->GetTitle(aTitle);
-pDlg->GetDescription(aDescription);
-pDlg->IsDecorative(isDecorative);
+pDlg->GetTitle(aNewTitle);
+pDlg->GetDescription(aNewDescription);
+pDlg->IsDecorative(newIsDecorative);
 
-pSelected->SetTitle(aTitle);
-pSelected->SetDescription(aDescription);
-pSelected->SetDecorative(isDecorative);
+pSelected->SetTitle(aNewTitle);
+pSelected->SetDescription(aNewDescription);
+pSelected->SetDecorative(newIsDecorative);
 
 pSh->SetModified();
 }


core.git: Branch 'distro/collabora/co-24.04' - sd/source

2024-05-09 Thread Miklos Vajna (via logerrit)
 sd/source/ui/view/drviews2.cxx |   18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

New commits:
commit 943913f74c26210ebf3ed04f36412e3c45b76f0e
Author: Miklos Vajna 
AuthorDate: Thu May 9 11:52:13 2024 +0200
Commit: Szymon Kłos 
CommitDate: Thu May 9 12:06:48 2024 +0200

sd: fix -Wshadow warnings


/home/vmiklos/git/libreoffice/co-24.04/sd/source/ui/view/drviews2.cxx: In 
lambda function:

/home/vmiklos/git/libreoffice/co-24.04/sd/source/ui/view/drviews2.cxx:2713:38: 
error: declaration of ‘aTitle’ shadows a previous local [-Werror=shadow]
 2713 | OUString aTitle;
  |  ^~

/home/vmiklos/git/libreoffice/co-24.04/sd/source/ui/view/drviews2.cxx:2700:26: 
note: shadowed declaration is here
 2700 | OUString aTitle(pSelected->GetTitle());
  |  ^~

/home/vmiklos/git/libreoffice/co-24.04/sd/source/ui/view/drviews2.cxx:2714:38: 
error: declaration of ‘aDescription’ shadows a previous local [-Werror=shadow]
 2714 | OUString aDescription;
  |  ^~~~

/home/vmiklos/git/libreoffice/co-24.04/sd/source/ui/view/drviews2.cxx:2701:26: 
note: shadowed declaration is here
 2701 | OUString 
aDescription(pSelected->GetDescription());
  |  ^~~~

/home/vmiklos/git/libreoffice/co-24.04/sd/source/ui/view/drviews2.cxx:2715:34: 
error: declaration of ‘isDecorative’ shadows a previous local [-Werror=shadow]
 2715 | bool isDecorative;
  |  ^~~~

/home/vmiklos/git/libreoffice/co-24.04/sd/source/ui/view/drviews2.cxx:2702:22: 
note: shadowed declaration is here
 2702 | bool 
isDecorative(pSelected->IsDecorative());
  |  ^~~~
cc1plus: all warnings being treated as errors

Change-Id: I036105d084010c66b8aab75befdef590408b25ec
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167381
Tested-by: Jenkins CollaboraOffice 
Reviewed-by: Szymon Kłos 

diff --git a/sd/source/ui/view/drviews2.cxx b/sd/source/ui/view/drviews2.cxx
index a7ed100977bf..d149c9633d7f 100644
--- a/sd/source/ui/view/drviews2.cxx
+++ b/sd/source/ui/view/drviews2.cxx
@@ -2710,17 +2710,17 @@ void DrawViewShell::FuTemporary(SfxRequest& rReq)
 {
 if (nResult == RET_OK)
 {
-OUString aTitle;
-OUString aDescription;
-bool isDecorative;
+OUString aNewTitle;
+OUString aNewDescription;
+bool newIsDecorative;
 
-pDlg->GetTitle(aTitle);
-pDlg->GetDescription(aDescription);
-pDlg->IsDecorative(isDecorative);
+pDlg->GetTitle(aNewTitle);
+pDlg->GetDescription(aNewDescription);
+pDlg->IsDecorative(newIsDecorative);
 
-pSelected->SetTitle(aTitle);
-pSelected->SetDescription(aDescription);
-pSelected->SetDecorative(isDecorative);
+pSelected->SetTitle(aNewTitle);
+pSelected->SetDescription(aNewDescription);
+pSelected->SetDecorative(newIsDecorative);
 }
 pDlg->disposeOnce();
 }


core.git: sw/source

2024-05-09 Thread Miklos Vajna (via logerrit)
 sw/source/core/inc/pagefrm.hxx|1 +
 sw/source/core/inc/sectfrm.hxx|4 
 sw/source/core/layout/findfrm.cxx |   23 +++
 sw/source/core/layout/sectfrm.cxx |1 +
 4 files changed, 29 insertions(+)

New commits:
commit 8bae684c93bd23bbe98707ba9cf75d1a39427131
Author: Miklos Vajna 
AuthorDate: Thu May 9 08:20:21 2024 +0200
Commit: Miklos Vajna 
CommitDate: Thu May 9 09:35:03 2024 +0200

tdf#160984 sw continuous endnotes: add a way to find the endnote section 
start

Existing code with endnotes on separate page at the end of the document
works by searching for a current or next page that is an endnote page in
SwFootnoteBossFrame::AppendFootnote(), and in case none is found, then
an endnote page is created.

Add similar infrastructure for the inline endnotes case: here we want to
find the first page that has an endnotes section, which also requires
being able to tell if a section is an endnotes one.

The newly introduced SwPageFrame::GetEndNoteSection() is not yet used in
SwFootnoteBossFrame::AppendFootnote(), though.

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

diff --git a/sw/source/core/inc/pagefrm.hxx b/sw/source/core/inc/pagefrm.hxx
index 23d77b1c8f74..be55221b2bef 100644
--- a/sw/source/core/inc/pagefrm.hxx
+++ b/sw/source/core/inc/pagefrm.hxx
@@ -204,6 +204,7 @@ public:
 bool IsEndNotePage() const  { return m_bEndNotePage; }
 void SetFootnotePage( bool b )   { m_bFootnotePage = 
b; }
 void SetEndNotePage( bool b )   { m_bEndNotePage = b; }
+SwSectionFrame* GetEndNoteSection();
 
 sal_uInt16 GetPhyPageNum() const{ return m_nPhyPageNum;}
 void SetPhyPageNum( sal_uInt16 nNum )   { m_nPhyPageNum = nNum;}
diff --git a/sw/source/core/inc/sectfrm.hxx b/sw/source/core/inc/sectfrm.hxx
index 9dbf9f4df9cc..12646d08ebad 100644
--- a/sw/source/core/inc/sectfrm.hxx
+++ b/sw/source/core/inc/sectfrm.hxx
@@ -52,6 +52,8 @@ class SAL_DLLPUBLIC_RTTI SwSectionFrame final: public 
SwLayoutFrame, public SwFl
 SwSection* m_pSection;
 bool m_bFootnoteAtEnd; // footnotes at the end of section
 bool m_bEndnAtEnd; // endnotes at the end of section
+/// If this is a section for endnotes, then the SwSection is not backed by 
an SwSectionNode.
+bool m_bEndNoteSection = false;
 bool m_bContentLock; // content locked
 bool m_bOwnFootnoteNum; // special numbering of footnotes
 bool m_bFootnoteLock; // ftn, don't leave this section bwd
@@ -171,6 +173,8 @@ public:
 
 void SetFootnoteLock( bool bNew ) { m_bFootnoteLock = bNew; }
 bool IsFootnoteLock() const { return m_bFootnoteLock; }
+void SetEndNoteSection(bool bEndNoteSection) { m_bEndNoteSection = 
bEndNoteSection; }
+bool IsEndNoteSection() const { return m_bEndNoteSection; }
 };
 
 inline const SwSectionFrame *SwSectionFrame::GetFollow() const
diff --git a/sw/source/core/layout/findfrm.cxx 
b/sw/source/core/layout/findfrm.cxx
index a86a7afefc87..60ca1fe7d326 100644
--- a/sw/source/core/layout/findfrm.cxx
+++ b/sw/source/core/layout/findfrm.cxx
@@ -65,6 +65,29 @@ SwContentFrame *SwPageFrame::FindLastBodyContent()
 return pRet;
 }
 
+SwSectionFrame* SwPageFrame::GetEndNoteSection()
+{
+SwLayoutFrame* pBody = FindBodyCont();
+if (!pBody)
+{
+return nullptr;
+}
+
+SwFrame* pLast = pBody->GetLastLower();
+if (!pLast || !pLast->IsSctFrame())
+{
+return nullptr;
+}
+
+auto pLastSection = static_cast(pLast);
+if (!pLastSection->IsEndNoteSection())
+{
+return nullptr;
+}
+
+return pLastSection;
+}
+
 /**
  * Checks if the frame contains one or more ContentFrame's anywhere in his
  * subsidiary structure; if so the first found ContentFrame is returned.
diff --git a/sw/source/core/layout/sectfrm.cxx 
b/sw/source/core/layout/sectfrm.cxx
index 3967a1f56442..78278da9cb38 100644
--- a/sw/source/core/layout/sectfrm.cxx
+++ b/sw/source/core/layout/sectfrm.cxx
@@ -94,6 +94,7 @@ SwSectionFrame::SwSectionFrame( SwSectionFrame , bool 
bMaster ) :
 m_bOwnFootnoteNum( false ),
 m_bFootnoteLock( false )
 {
+m_bEndNoteSection = rSect.m_bEndNoteSection;
 StartListening(rSect.GetFormat()->GetNotifier());
 
 mnFrameType = SwFrameType::Section;


core.git: Branch 'distro/collabora/co-24.04' - sw/qa sw/source

2024-05-09 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 47c917bcdbffd6423f50a3d970ed45ce06b9061e
Author: Miklos Vajna 
AuthorDate: Tue Apr 30 08:44:59 2024 +0200
Commit: Miklos Vajna 
CommitDate: Thu May 9 09:33:22 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 
(cherry picked from commit 32616609c788aa1cf0837af0f387390a23de1766)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167375
Tested-by: Jenkins CollaboraOffice 

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: Changes to 'refs/tags/cp-24.04.2-1'

2024-05-08 Thread Miklos Vajna (via logerrit)
Tag 'cp-24.04.2-1' created by Aron Budea  at 
2024-05-08 15:21 +

cp-24.04.2-1

Changes since cp-24.04.1-4-81:
---
 0 files changed
---


core.git: Branch 'distro/collabora/co-24.04' - sw/CppunitTest_sw_core_layout.mk sw/qa sw/source

2024-05-08 Thread Miklos Vajna (via logerrit)
 sw/CppunitTest_sw_core_layout.mk  |1 
 sw/qa/core/layout/calcmove.cxx|   44 ++
 sw/qa/core/layout/data/ignore-top-margin.docx |binary
 sw/source/core/inc/frame.hxx  |3 +
 sw/source/core/layout/calcmove.cxx|   32 ++
 sw/source/core/layout/flowfrm.cxx |5 ++
 6 files changed, 85 insertions(+)

New commits:
commit 4fe480d314ceb100f4679626fee3d60dd82a6bc6
Author: Miklos Vajna 
AuthorDate: Tue May 7 08:13:37 2024 +0200
Commit: Caolán McNamara 
CommitDate: Wed May 8 15:12:18 2024 +0200

tdf#160952 sw: ignore top margin of para on non-first pages with newer DOCX

The 2nd page of the bugdoc has a single paragraph, with a non-zero top
margin. This is ignored in Word, but wasn't ignored in Writer.

Experimenting with the document, it looks like old Word files also don't
ignore this top margin: it started when the compat mode is upgraded
(from binary DOC or Word 2010) to Word 2013 or newer. Also the top
margin is only ignored for the first paragraph on the page, and only in
case it's not on the first page.

Fix the problem by introducing a new SwFrame::IsCollapseUpper() function
to decide if the upper margin should be collapsed or not, and then by
using it in SwFlowFrame::CalcUpperSpace() at one place where we read the
top margin from the doc model. Take advantage of the fact that we have
related, existing compat flags that tell us if we're in "Word >= 2013"
compat mode: see e.g. GetFlyAnchorBottom(), which explains
DocumentSettingId::TAB_OVER_MARGIN is a good indicator that this is a
"Word <= 2010" document. Also, DocumentSettingId::TAB_OVER_SPACING is an
indicator that this is a Word document, so we want the "TabOverSpacing
&& !TabOverMargin" case.

This doesn't change all reads of the upper spacing of a text node, but
is enough to avoid the unwanted top spacing, as demonstrated by the
bugdoc.

(cherry picked from commit 6200d89b905d51776ff4f3c8a84f338655ffaa7f)

Change-Id: Ibdebdf5f0555256a0b6ed85d07079f14ef69a576
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167306
Reviewed-by: Caolán McNamara 
Tested-by: Jenkins CollaboraOffice 

diff --git a/sw/CppunitTest_sw_core_layout.mk b/sw/CppunitTest_sw_core_layout.mk
index 5eb874400d53..d64a43f7d3fb 100644
--- a/sw/CppunitTest_sw_core_layout.mk
+++ b/sw/CppunitTest_sw_core_layout.mk
@@ -14,6 +14,7 @@ $(eval $(call gb_CppunitTest_CppunitTest,sw_core_layout))
 $(eval $(call gb_CppunitTest_use_common_precompiled_header,sw_core_layout))
 
 $(eval $(call gb_CppunitTest_add_exception_objects,sw_core_layout, \
+sw/qa/core/layout/calcmove \
 sw/qa/core/layout/fly \
 sw/qa/core/layout/flycnt \
 sw/qa/core/layout/frmtool \
diff --git a/sw/qa/core/layout/calcmove.cxx b/sw/qa/core/layout/calcmove.cxx
new file mode 100644
index ..3e4deec52ae8
--- /dev/null
+++ b/sw/qa/core/layout/calcmove.cxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-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/.
+ */
+
+#include 
+
+#include 
+
+namespace
+{
+/// Covers sw/source/core/layout/calcmove.cxx fixes.
+class Test : public SwModelTestBase
+{
+public:
+Test()
+: SwModelTestBase("/sw/qa/core/layout/data/")
+{
+}
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testIgnoreTopMargin)
+{
+// Given a DOCX (>= Word 2013) file, with 2 pages:
+// When loading that document:
+createSwDoc("ignore-top-margin.docx");
+
+// Then make sure that the paragraph on the 2nd page has no top margin:
+xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+sal_Int32 nParaTopMargin
+= getXPath(pXmlDoc, "/root/page[2]/body/txt/infos/prtBounds"_ostr, 
"top"_ostr).toInt32();
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected: 0
+// - Actual  : 2400
+// 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);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/core/layout/data/ignore-top-margin.docx 
b/sw/qa/core/layout/data/ignore-top-margin.docx
new file mode 100644
index ..d05a1358db1e
Binary files /dev/null and b/sw/qa/core/layout/data/ignore-top-margin.docx 
differ
diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx
index 604488a18c9f..a86358508182 100644
--- a/sw/source/core/inc/frame.hxx
+++ b/sw/source/core/inc/frame.hxx
@@ -948,6 +948,9 @@ public:
 virtual void dumpAsXmlAttributes(xmlTextWriterPtr writer) const;
 void 

core.git: sw/inc sw/source

2024-05-08 Thread Miklos Vajna (via logerrit)
 sw/inc/ftninfo.hxx|5 +
 sw/source/core/doc/docftn.cxx |   19 +++
 sw/source/core/doc/docnew.cxx |1 +
 3 files changed, 25 insertions(+)

New commits:
commit 90f19126fa405a0632eae4ee8525b66bbce12625
Author: Miklos Vajna 
AuthorDate: Wed May 8 08:59:47 2024 +0200
Commit: Miklos Vajna 
CommitDate: Wed May 8 12:49:04 2024 +0200

tdf#160984 sw continuous endnotes: introduce an endnote section

Word lays out endnotes at the end of the document inline after body
text, Writer puts them on one or more separate endnote pages.

There was already an attempt in the past to resolve this difference, see
commit 4814e8caa5f06c4fe438dfd7d7315e4a2410ea18 (tdf#124601 sw: add
ContinuousEndnotes layout compat option, 2019-09-30). The approach back
then was to map such endnotes to footnotes, so the extra, unwanted page
doesn't appear. This turned out to be not working too well, the compat
option is only enabled for DOC, and even there commit
dc11f5b151e1a2ea2623fc8cf806a400763955d9 (tdf#143445 DOC import: limit
the usage of the CONTINUOUS_ENDNOTES compat flag, 2023-05-23) limited
the usage of the compat flag to 1 or 2 endnotes only.

Coming back to this, try a new approach: create a section that more or
less exists only at a layout level and put endnotes into that section.
This allows reusing all the complex logic on how to lay out endnotes
inline, on one or more pages. The plan is that this new approach is more
robust, can replace the old continuous endnotes layout code and then can
be enabled for DOCX as well.

This commit just introduces the backing section format and SwSection for
that special "endnotes section" (it's special because SwSection is
usually owned by an SwSectionNode, but here there is no doc model node
for the SwSection), SwFootnoteBossFrame::AppendFootnote() doesn't try to
use the new SwEndNoteInfo::GetSwSection() yet.

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

diff --git a/sw/inc/ftninfo.hxx b/sw/inc/ftninfo.hxx
index 17742687c944..c5490ed885d0 100644
--- a/sw/inc/ftninfo.hxx
+++ b/sw/inc/ftninfo.hxx
@@ -28,12 +28,14 @@ class SwTextFormatColl;
 class SwPageDesc;
 class SwCharFormat;
 class SwDoc;
+class SwSection;
 
 class SW_DLLPUBLIC SwEndNoteInfo : public SwClient
 {
 mutable sw::WriterMultiListener m_aDepends;
 mutable SwTextFormatColl* m_pTextFormatColl;
 mutable SwPageDesc* m_pPageDesc;
+mutable std::unique_ptr m_pSwSection;
 mutable SwCharFormat* m_pCharFormat;
 mutable SwCharFormat* m_pAnchorFormat;
 OUString m_sPrefix;
@@ -51,6 +53,9 @@ public:
 bool KnowsPageDesc() const;
 bool DependsOn(const SwPageDesc*) const;
 
+SwSection* GetSwSection(SwDoc& rDoc) const;
+void ResetSwSection();
+
 void SetFootnoteTextColl(SwTextFormatColl& rColl);
 SwTextFormatColl* GetFootnoteTextColl() const { return m_pTextFormatColl; 
} // can be 0.
 
diff --git a/sw/source/core/doc/docftn.cxx b/sw/source/core/doc/docftn.cxx
index 16f6694c94c5..f211dcdcc9f4 100644
--- a/sw/source/core/doc/docftn.cxx
+++ b/sw/source/core/doc/docftn.cxx
@@ -35,6 +35,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 SwEndNoteInfo& SwEndNoteInfo::operator=(const SwEndNoteInfo& rInfo)
 {
@@ -130,6 +132,23 @@ void SwEndNoteInfo::ChgPageDesc(SwPageDesc* pDesc)
 m_aDepends.StartListening(m_pPageDesc);
 }
 
+SwSection* SwEndNoteInfo::GetSwSection(SwDoc& rDoc) const
+{
+if (!m_pSwSection)
+{
+SwSectionFormat* pFormat = rDoc.MakeSectionFormat();
+pFormat->SetFormatName(UNO_NAME_ENDNOTE);
+pFormat->SetFormatAttr(SwFormatEndAtTextEnd(FTNEND_ATTXTEND));
+m_pSwSection.reset(new SwSection(SectionType::Content, 
pFormat->GetName(), *pFormat));
+}
+return m_pSwSection.get();
+}
+
+void SwEndNoteInfo::ResetSwSection()
+{
+m_pSwSection.reset();
+}
+
 void SwEndNoteInfo::SetFootnoteTextColl(SwTextFormatColl& rFormat)
 {
 m_aDepends.EndListening(m_pTextFormatColl);
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index a56e7343e8f1..daef5f64be75 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -505,6 +505,7 @@ SwDoc::~SwDoc()
 // do not have any dependencies anymore.
 m_pNodes->DelNodes( SwNodeIndex(*m_pNodes), m_pNodes->Count() );
 rUndoNodes.DelNodes( SwNodeIndex( rUndoNodes ), rUndoNodes.Count() );
+mpEndNoteInfo->ResetSwSection();
 
 // clear TOX after nodes - TOXMarks are gone now so SwTOXType has no 
clients
 for (const auto& pType : *mpTOXTypes)


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' - cui/source sw/source

2024-05-08 Thread Miklos Vajna (via logerrit)
 cui/source/inc/swpossizetabpage.hxx  |1 +
 cui/source/tabpages/swpossizetabpage.cxx |   27 +--
 sw/source/uibase/shells/drwbassh.cxx |   10 ++
 3 files changed, 32 insertions(+), 6 deletions(-)

New commits:
commit e74f2f3f259125434f7fb9f8d7c338123a0137ed
Author: Miklos Vajna 
AuthorDate: Fri May 3 08:08:29 2024 +0200
Commit: Xisco Fauli 
CommitDate: Wed May 8 09:33:44 2024 +0200

tdf#160833 sw DoNotMirrorRtlDrawObjs: add UI in cui/

The UI code at lcl_ChangeResIdToVerticalOrRTL() was aware that
SwAnchoredObjectPosition::CalcRelPosX() mirrors the position when the
anchor paragraph is RTL, so swapped the "from left" label to a "from
right" label.

Don't do this when the compat option is enabled, so not only we render
correctly but the UI now correctly explains why we came up with the
correct position.

Change-Id: I479ed1f085b249d10be47b66d7a656dc1bd4f936
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167031
Reviewed-by: Miklos Vajna 
Tested-by: Jenkins
(cherry picked from commit 0f410680461d7ba5f70dd65b2a8263dec15ac357)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167083
Reviewed-by: Xisco Fauli 

diff --git a/cui/source/inc/swpossizetabpage.hxx 
b/cui/source/inc/swpossizetabpage.hxx
index eb73196986bf..ede7fd4231ae 100644
--- a/cui/source/inc/swpossizetabpage.hxx
+++ b/cui/source/inc/swpossizetabpage.hxx
@@ -52,6 +52,7 @@ class SvxSwPosSizeTabPage : public SfxTabPage
 boolm_bPositioningDisabled;
 boolm_bIsMultiSelection;
 boolm_bIsInRightToLeft;
+bool m_bDoNotMirrorRtlDrawObjs = false;
 TriStatem_nProtectSizeState;
 
 SwFrameExample m_aExampleWN;
diff --git a/cui/source/tabpages/swpossizetabpage.cxx 
b/cui/source/tabpages/swpossizetabpage.cxx
index 060f7b44ce9f..8de586a74df5 100644
--- a/cui/source/tabpages/swpossizetabpage.cxx
+++ b/cui/source/tabpages/swpossizetabpage.cxx
@@ -37,6 +37,7 @@
 #include 
 #include 
 #include 
+#include 
 
 using namespace ::com::sun::star::text;
 
@@ -431,14 +432,16 @@ static std::size_t lcl_GetFrmMapCount(const FrmMap* pMap)
 }
 
 static SvxSwFramePosString::StringId lcl_ChangeResIdToVerticalOrRTL(
-SvxSwFramePosString::StringId eStringId, bool bVertical, bool bRTL)
+SvxSwFramePosString::StringId eStringId, bool bVertical, bool 
bRTL, bool bDontMirrorRTL)
 {
 //special handling of STR_FROMLEFT
 if(SvxSwFramePosString::FROMLEFT == eStringId)
 {
+bool bMirrorRtlDrawObjs = !bDontMirrorRTL;
+bool bSwapLR = bRTL && bMirrorRtlDrawObjs;
 eStringId = bVertical ?
 bRTL ? SvxSwFramePosString::FROMBOTTOM : 
SvxSwFramePosString::FROMTOP :
-bRTL ? SvxSwFramePosString::FROMRIGHT : 
SvxSwFramePosString::FROMLEFT;
+bSwapLR ? SvxSwFramePosString::FROMRIGHT : 
SvxSwFramePosString::FROMLEFT;
 return eStringId;
 }
 if(bVertical)
@@ -728,7 +731,8 @@ WhichRangesContainer SvxSwPosSizeTabPage::GetRanges()
 SID_ATTR_TRANSFORM_AUTOWIDTH, SID_ATTR_TRANSFORM_VERT_ORIENT,
 SID_HTML_MODE, SID_HTML_MODE,
 SID_SW_FOLLOW_TEXT_FLOW, SID_SW_FOLLOW_TEXT_FLOW,
-SID_ATTR_TRANSFORM_HORI_POSITION, SID_ATTR_TRANSFORM_VERT_POSITION
+SID_ATTR_TRANSFORM_HORI_POSITION, SID_ATTR_TRANSFORM_VERT_POSITION,
+SID_ATTR_CHAR_GRABBAG, SID_ATTR_CHAR_GRABBAG
 >);
 return ranges;
 }
@@ -967,6 +971,17 @@ void SvxSwPosSizeTabPage::Reset( const SfxItemSet* rSet)
 }
 m_xFollowCB->save_state();
 
+const SfxGrabBagItem* pGrabBag = GetItem(*rSet, SID_ATTR_CHAR_GRABBAG);
+if (pGrabBag)
+{
+const std::map& rMap = pGrabBag->GetGrabBag();
+auto it = rMap.find("DoNotMirrorRtlDrawObjs");
+if (it != rMap.end())
+{
+it->second >>= m_bDoNotMirrorRtlDrawObjs;
+}
+}
+
 if(m_bHtmlMode)
 {
 m_xHoriMirrorCB->hide();
@@ -1651,7 +1666,7 @@ void SvxSwPosSizeTabPage::FillRelLB(FrmMap const *pMap, 
sal_uInt16 nMapPos, sal_
 {
 SvxSwFramePosString::StringId sStrId1 = 
aAsCharRelationMap[nRelPos].eStrId;
 
-sStrId1 = lcl_ChangeResIdToVerticalOrRTL(sStrId1, 
m_bIsVerticalFrame, m_bIsInRightToLeft);
+sStrId1 = lcl_ChangeResIdToVerticalOrRTL(sStrId1, 
m_bIsVerticalFrame, m_bIsInRightToLeft, m_bDoNotMirrorRtlDrawObjs);
 OUString sEntry = 
SvxSwFramePosString::GetString(sStrId1);
 
rLB.append(weld::toId([nRelPos]), sEntry);
 if (pMap[_nMapPos].nAlign == nAlign)
@@ -1706,7 +1721,7 @@ void SvxSwPosSizeTabPage::FillRelLB(FrmMap const *pMap, 
sal_uInt16 nMapPos, sal_
 if (aRelationMap[nRelPos].nLBRelation == 
static_cast(nBit))
 {
 SvxSwFramePosString::StringId sStrId1 = 

core.git: sw/qa

2024-05-08 Thread Miklos Vajna (via logerrit)
 sw/qa/extras/rtfexport/rtfexport6.cxx | 1115 ++
 1 file changed, 722 insertions(+), 393 deletions(-)

New commits:
commit af3d52e444595a4a3b50528c0f02fa798e7a2b08
Author: Miklos Vajna 
AuthorDate: Wed May 8 08:11:07 2024 +0200
Commit: Miklos Vajna 
CommitDate: Wed May 8 09:07:54 2024 +0200

CppunitTest_sw_rtfexport6: avoid DECLARE_RTFEXPORT_TEST

No need to go via Writer-specific macros here.

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

diff --git a/sw/qa/extras/rtfexport/rtfexport6.cxx 
b/sw/qa/extras/rtfexport/rtfexport6.cxx
index e943de10622b..f206c1ddadfb 100644
--- a/sw/qa/extras/rtfexport/rtfexport6.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport6.cxx
@@ -47,25 +47,43 @@ public:
 }
 };
 
-DECLARE_RTFEXPORT_TEST(testFdo85889pc, "fdo85889-pc.rtf")
+CPPUNIT_TEST_FIXTURE(Test, testFdo85889pc)
 {
-uno::Reference xTextRange = getRun(getParagraph(1), 1);
+auto verify = [this]() {
+uno::Reference xTextRange = getRun(getParagraph(1), 
1);
 
-CPPUNIT_ASSERT_EQUAL(u"\u00B1\u2265\u2264"_ustr, xTextRange->getString());
+CPPUNIT_ASSERT_EQUAL(u"\u00B1\u2265\u2264"_ustr, 
xTextRange->getString());
+};
+createSwDoc("fdo85889-pc.rtf");
+verify();
+saveAndReload(mpFilter);
+verify();
 }
 
-DECLARE_RTFEXPORT_TEST(testFdo85889pca, "fdo85889-pca.rtf")
+CPPUNIT_TEST_FIXTURE(Test, testFdo85889pca)
 {
-uno::Reference xTextRange = getRun(getParagraph(1), 1);
+auto verify = [this]() {
+uno::Reference xTextRange = getRun(getParagraph(1), 
1);
 
-CPPUNIT_ASSERT_EQUAL(u"\u00B1\u2017\u00BE"_ustr, xTextRange->getString());
+CPPUNIT_ASSERT_EQUAL(u"\u00B1\u2017\u00BE"_ustr, 
xTextRange->getString());
+};
+createSwDoc("fdo85889-pca.rtf");
+verify();
+saveAndReload(mpFilter);
+verify();
 }
 
-DECLARE_RTFEXPORT_TEST(testFdo85889mac, "fdo85889-mac.rtf")
+CPPUNIT_TEST_FIXTURE(Test, testFdo85889mac)
 {
-uno::Reference xTextRange = getRun(getParagraph(1), 1);
+auto verify = [this]() {
+uno::Reference xTextRange = getRun(getParagraph(1), 
1);
 
-CPPUNIT_ASSERT_EQUAL(u"\u00D2\u00DA\u00DB"_ustr, xTextRange->getString());
+CPPUNIT_ASSERT_EQUAL(u"\u00D2\u00DA\u00DB"_ustr, 
xTextRange->getString());
+};
+createSwDoc("fdo85889-mac.rtf");
+verify();
+saveAndReload(mpFilter);
+verify();
 }
 
 CPPUNIT_TEST_FIXTURE(Test, testFdo72031)
@@ -86,63 +104,111 @@ CPPUNIT_TEST_FIXTURE(Test, testFdo72031)
 verify();
 }
 
-DECLARE_RTFEXPORT_TEST(testFdo86750, "fdo86750.rtf")
+CPPUNIT_TEST_FIXTURE(Test, testFdo86750)
 {
-// This was 'HYPERLINK#anchor', the URL of the hyperlink had the field 
type as a prefix, leading to broken links.
-CPPUNIT_ASSERT_EQUAL(OUString("#anchor"),
- getProperty(getRun(getParagraph(1), 1), 
"HyperLinkURL"));
+auto verify = [this]() {
+// This was 'HYPERLINK#anchor', the URL of the hyperlink had the field 
type as a prefix, leading to broken links.
+CPPUNIT_ASSERT_EQUAL(OUString("#anchor"),
+ getProperty(getRun(getParagraph(1), 1), 
"HyperLinkURL"));
+};
+createSwDoc("fdo86750.rtf");
+verify();
+saveAndReload(mpFilter);
+verify();
 }
 
-DECLARE_RTFEXPORT_TEST(testTdf88811, "tdf88811.rtf")
+CPPUNIT_TEST_FIXTURE(Test, testTdf88811)
 {
-// The problem was that shapes anchored to the paragraph that is moved 
into a textframe were lost, so this was 2.
-CPPUNIT_ASSERT_EQUAL(4, getShapes());
+auto verify = [this]() {
+// The problem was that shapes anchored to the paragraph that is moved 
into a textframe were lost, so this was 2.
+CPPUNIT_ASSERT_EQUAL(4, getShapes());
+};
+createSwDoc("tdf88811.rtf");
+verify();
+saveAndReload(mpFilter);
+verify();
 }
 
-DECLARE_RTFEXPORT_TEST(testFdo49893_2, "fdo49893-2.rtf")
+CPPUNIT_TEST_FIXTURE(Test, testFdo49893_2)
 {
-// Ensure that header text exists on each page (especially on second page)
-CPPUNIT_ASSERT_EQUAL(OUString("HEADER"), 
parseDump("/root/page[1]/header/txt/text()"_ostr));
-CPPUNIT_ASSERT_EQUAL(OUString("HEADER"), 
parseDump("/root/page[2]/header/txt/text()"_ostr));
-CPPUNIT_ASSERT_EQUAL(OUString("HEADER"), 
parseDump("/root/page[3]/header/txt/text()"_ostr));
-CPPUNIT_ASSERT_EQUAL(OUString("HEADER"), 
parseDump("/root/page[4]/header/txt/text()"_ostr));
-CPPUNIT_ASSERT_EQUAL(OUString("HEADER"), 
parseDump("/root/page[5]/header/txt/text()"_ostr));
-CPPUNIT_ASSERT_EQUAL(5, getPages()); // Word has 5
+auto verify = [this]() {
+// Ensure that header text exists on each page (especially on second 
page)
+CPPUNIT_ASSERT_EQUAL(OUString("HEADER"), 
parseDump("/root/page[1]/header/txt/text()"_ostr));
+CPPUNIT_ASSERT_EQUAL(OUString("HEADER"), 

core.git: sw/CppunitTest_sw_core_layout.mk sw/qa sw/source

2024-05-07 Thread Miklos Vajna (via logerrit)
 sw/CppunitTest_sw_core_layout.mk  |1 
 sw/qa/core/layout/calcmove.cxx|   44 ++
 sw/qa/core/layout/data/ignore-top-margin.docx |binary
 sw/source/core/inc/frame.hxx  |3 +
 sw/source/core/layout/calcmove.cxx|   32 ++
 sw/source/core/layout/flowfrm.cxx |5 ++
 6 files changed, 85 insertions(+)

New commits:
commit 6200d89b905d51776ff4f3c8a84f338655ffaa7f
Author: Miklos Vajna 
AuthorDate: Tue May 7 08:13:37 2024 +0200
Commit: Miklos Vajna 
CommitDate: Tue May 7 09:18:06 2024 +0200

tdf#160952 sw: ignore top margin of para on non-first pages with newer DOCX

The 2nd page of the bugdoc has a single paragraph, with a non-zero top
margin. This is ignored in Word, but wasn't ignored in Writer.

Experimenting with the document, it looks like old Word files also don't
ignore this top margin: it started when the compat mode is upgraded
(from binary DOC or Word 2010) to Word 2023 or newer. Also the top
margin is only ignored for the first paragraph on the page, and only in
case it's not on the first page.

Fix the problem by introducing a new SwFrame::IsCollapseUpper() function
to decide if the upper margin should be collapsed or not, and then by
using it in SwFlowFrame::CalcUpperSpace() at one place where we read the
top margin from the doc model. Take advantage of the fact that we have
related, existing compat flags that tell us if we're in "Word >= 2013"
compat mode: see e.g. GetFlyAnchorBottom(), which explains
DocumentSettingId::TAB_OVER_MARGIN is a good indicator that this is a
"Word <= 2010" document. Also, DocumentSettingId::TAB_OVER_SPACING is an
indicator that this is a Word document, so we want the "TabOverSpacing
&& !TabOverMargin" case.

This doesn't change all reads of the upper spacing of a text node, but
is enough to avoid the unwanted top spacing, as demonstrated by the
bugdoc.

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

diff --git a/sw/CppunitTest_sw_core_layout.mk b/sw/CppunitTest_sw_core_layout.mk
index 5eb874400d53..d64a43f7d3fb 100644
--- a/sw/CppunitTest_sw_core_layout.mk
+++ b/sw/CppunitTest_sw_core_layout.mk
@@ -14,6 +14,7 @@ $(eval $(call gb_CppunitTest_CppunitTest,sw_core_layout))
 $(eval $(call gb_CppunitTest_use_common_precompiled_header,sw_core_layout))
 
 $(eval $(call gb_CppunitTest_add_exception_objects,sw_core_layout, \
+sw/qa/core/layout/calcmove \
 sw/qa/core/layout/fly \
 sw/qa/core/layout/flycnt \
 sw/qa/core/layout/frmtool \
diff --git a/sw/qa/core/layout/calcmove.cxx b/sw/qa/core/layout/calcmove.cxx
new file mode 100644
index ..3e4deec52ae8
--- /dev/null
+++ b/sw/qa/core/layout/calcmove.cxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-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/.
+ */
+
+#include 
+
+#include 
+
+namespace
+{
+/// Covers sw/source/core/layout/calcmove.cxx fixes.
+class Test : public SwModelTestBase
+{
+public:
+Test()
+: SwModelTestBase("/sw/qa/core/layout/data/")
+{
+}
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testIgnoreTopMargin)
+{
+// Given a DOCX (>= Word 2013) file, with 2 pages:
+// When loading that document:
+createSwDoc("ignore-top-margin.docx");
+
+// Then make sure that the paragraph on the 2nd page has no top margin:
+xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+sal_Int32 nParaTopMargin
+= getXPath(pXmlDoc, "/root/page[2]/body/txt/infos/prtBounds"_ostr, 
"top"_ostr).toInt32();
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected: 0
+// - Actual  : 2400
+// 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);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/core/layout/data/ignore-top-margin.docx 
b/sw/qa/core/layout/data/ignore-top-margin.docx
new file mode 100644
index ..d05a1358db1e
Binary files /dev/null and b/sw/qa/core/layout/data/ignore-top-margin.docx 
differ
diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx
index eac4adff7ce6..f0b7439bd283 100644
--- a/sw/source/core/inc/frame.hxx
+++ b/sw/source/core/inc/frame.hxx
@@ -951,6 +951,9 @@ public:
 virtual void dumpAsXmlAttributes(xmlTextWriterPtr writer) const;
 void dumpChildrenAsXml(xmlTextWriterPtr writer) const;
 bool IsCollapse() const;
+
+/// Determines if the upper 

core.git: Branch 'distro/collabora/co-23.05' - sc/source

2024-05-06 Thread Miklos Vajna (via logerrit)
 sc/source/ui/docshell/docsh6.cxx |6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

New commits:
commit 6360a8e721555bf9deb6ee38829a22abe39863ab
Author: Miklos Vajna 
AuthorDate: Fri Mar 1 08:34:00 2024 +0100
Commit: Szymon Kłos 
CommitDate: Tue May 7 07:55:05 2024 +0200

sc lok: make the formula separator warning dialog async

I'm not sure what exactly changed here, but recently online.git
unit-wopi-languages started to fail for me. First it was an assertion
failure:

/home/vmiklos/git/libreoffice/core/vcl/source/window/window.cxx:3186: void 
vcl::Window::SetLOKNotifier(const vcl::ILibreOfficeKitNotifier*, bool): 
Assertion `pNotifier' failed.

Once ScDocShell::CheckConfigOptions() is changed to pass in the view
shell explicitly, the next error is:

kit-26201-26149 2024-02-28 10:41:31.659255 +0100 [ kitbroker_002 ] ERR  
non-async dialog triggered

So convert it to async, similar to the chart2/ hunk of commit
4b33e878a446b0bcdb1d5f882a05a256967eea54 (Make format condition, chart
delete and pivot table error async, 2024-01-10).

Change-Id: I159278b24db0acd5fddb6f4d29dae9a35321e614
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164178
Tested-by: Jenkins
Reviewed-by: Miklos Vajna 
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167235
Tested-by: Jenkins CollaboraOffice 
Tested-by: Szymon Kłos 
Reviewed-by: Szymon Kłos 

diff --git a/sc/source/ui/docshell/docsh6.cxx b/sc/source/ui/docshell/docsh6.cxx
index caefdfc0fed3..344b52953faf 100644
--- a/sc/source/ui/docshell/docsh6.cxx
+++ b/sc/source/ui/docshell/docsh6.cxx
@@ -499,10 +499,10 @@ void ScDocShell::CheckConfigOptions()
 ScTabViewShell* pViewShell = GetBestViewShell();
 if (pViewShell)
 {
-std::unique_ptr 
xInfoBox(Application::CreateMessageDialog(pViewShell->GetFrameWeld(),
+std::shared_ptr 
xInfoBox(Application::CreateMessageDialog(pViewShell->GetFrameWeld(),
   
VclMessageType::Info, VclButtonsType::Ok,
-  
ScResId(STR_OPTIONS_WARN_SEPARATORS)));
-xInfoBox->run();
+  
ScResId(STR_OPTIONS_WARN_SEPARATORS), pViewShell));
+xInfoBox->runAsync(xInfoBox, [] (int) {});
 }
 
 // For now, this is the only option setting that could launch info


core.git: Branch 'distro/collabora/co-24.04' - cui/source sw/source

2024-05-06 Thread Miklos Vajna (via logerrit)
 cui/source/inc/swpossizetabpage.hxx  |1 +
 cui/source/tabpages/swpossizetabpage.cxx |   27 +--
 sw/source/uibase/shells/drwbassh.cxx |   10 ++
 3 files changed, 32 insertions(+), 6 deletions(-)

New commits:
commit 2b1a9d721f0664d31dfe06bad30d4a74d44262ce
Author: Miklos Vajna 
AuthorDate: Fri May 3 08:08:29 2024 +0200
Commit: Caolán McNamara 
CommitDate: Mon May 6 20:01:34 2024 +0200

tdf#160833 sw DoNotMirrorRtlDrawObjs: add UI in cui/

The UI code at lcl_ChangeResIdToVerticalOrRTL() was aware that
SwAnchoredObjectPosition::CalcRelPosX() mirrors the position when the
anchor paragraph is RTL, so swapped the "from left" label to a "from
right" label.

Don't do this when the compat option is enabled, so not only we render
correctly but the UI now correctly explains why we came up with the
correct position.

(cherry picked from commit 0f410680461d7ba5f70dd65b2a8263dec15ac357)

Change-Id: I479ed1f085b249d10be47b66d7a656dc1bd4f936
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167183
Reviewed-by: Caolán McNamara 
Tested-by: Jenkins CollaboraOffice 

diff --git a/cui/source/inc/swpossizetabpage.hxx 
b/cui/source/inc/swpossizetabpage.hxx
index eb73196986bf..ede7fd4231ae 100644
--- a/cui/source/inc/swpossizetabpage.hxx
+++ b/cui/source/inc/swpossizetabpage.hxx
@@ -52,6 +52,7 @@ class SvxSwPosSizeTabPage : public SfxTabPage
 boolm_bPositioningDisabled;
 boolm_bIsMultiSelection;
 boolm_bIsInRightToLeft;
+bool m_bDoNotMirrorRtlDrawObjs = false;
 TriStatem_nProtectSizeState;
 
 SwFrameExample m_aExampleWN;
diff --git a/cui/source/tabpages/swpossizetabpage.cxx 
b/cui/source/tabpages/swpossizetabpage.cxx
index 060f7b44ce9f..8de586a74df5 100644
--- a/cui/source/tabpages/swpossizetabpage.cxx
+++ b/cui/source/tabpages/swpossizetabpage.cxx
@@ -37,6 +37,7 @@
 #include 
 #include 
 #include 
+#include 
 
 using namespace ::com::sun::star::text;
 
@@ -431,14 +432,16 @@ static std::size_t lcl_GetFrmMapCount(const FrmMap* pMap)
 }
 
 static SvxSwFramePosString::StringId lcl_ChangeResIdToVerticalOrRTL(
-SvxSwFramePosString::StringId eStringId, bool bVertical, bool bRTL)
+SvxSwFramePosString::StringId eStringId, bool bVertical, bool 
bRTL, bool bDontMirrorRTL)
 {
 //special handling of STR_FROMLEFT
 if(SvxSwFramePosString::FROMLEFT == eStringId)
 {
+bool bMirrorRtlDrawObjs = !bDontMirrorRTL;
+bool bSwapLR = bRTL && bMirrorRtlDrawObjs;
 eStringId = bVertical ?
 bRTL ? SvxSwFramePosString::FROMBOTTOM : 
SvxSwFramePosString::FROMTOP :
-bRTL ? SvxSwFramePosString::FROMRIGHT : 
SvxSwFramePosString::FROMLEFT;
+bSwapLR ? SvxSwFramePosString::FROMRIGHT : 
SvxSwFramePosString::FROMLEFT;
 return eStringId;
 }
 if(bVertical)
@@ -728,7 +731,8 @@ WhichRangesContainer SvxSwPosSizeTabPage::GetRanges()
 SID_ATTR_TRANSFORM_AUTOWIDTH, SID_ATTR_TRANSFORM_VERT_ORIENT,
 SID_HTML_MODE, SID_HTML_MODE,
 SID_SW_FOLLOW_TEXT_FLOW, SID_SW_FOLLOW_TEXT_FLOW,
-SID_ATTR_TRANSFORM_HORI_POSITION, SID_ATTR_TRANSFORM_VERT_POSITION
+SID_ATTR_TRANSFORM_HORI_POSITION, SID_ATTR_TRANSFORM_VERT_POSITION,
+SID_ATTR_CHAR_GRABBAG, SID_ATTR_CHAR_GRABBAG
 >);
 return ranges;
 }
@@ -967,6 +971,17 @@ void SvxSwPosSizeTabPage::Reset( const SfxItemSet* rSet)
 }
 m_xFollowCB->save_state();
 
+const SfxGrabBagItem* pGrabBag = GetItem(*rSet, SID_ATTR_CHAR_GRABBAG);
+if (pGrabBag)
+{
+const std::map& rMap = pGrabBag->GetGrabBag();
+auto it = rMap.find("DoNotMirrorRtlDrawObjs");
+if (it != rMap.end())
+{
+it->second >>= m_bDoNotMirrorRtlDrawObjs;
+}
+}
+
 if(m_bHtmlMode)
 {
 m_xHoriMirrorCB->hide();
@@ -1651,7 +1666,7 @@ void SvxSwPosSizeTabPage::FillRelLB(FrmMap const *pMap, 
sal_uInt16 nMapPos, sal_
 {
 SvxSwFramePosString::StringId sStrId1 = 
aAsCharRelationMap[nRelPos].eStrId;
 
-sStrId1 = lcl_ChangeResIdToVerticalOrRTL(sStrId1, 
m_bIsVerticalFrame, m_bIsInRightToLeft);
+sStrId1 = lcl_ChangeResIdToVerticalOrRTL(sStrId1, 
m_bIsVerticalFrame, m_bIsInRightToLeft, m_bDoNotMirrorRtlDrawObjs);
 OUString sEntry = 
SvxSwFramePosString::GetString(sStrId1);
 
rLB.append(weld::toId([nRelPos]), sEntry);
 if (pMap[_nMapPos].nAlign == nAlign)
@@ -1706,7 +1721,7 @@ void SvxSwPosSizeTabPage::FillRelLB(FrmMap const *pMap, 
sal_uInt16 nMapPos, sal_
 if (aRelationMap[nRelPos].nLBRelation == 
static_cast(nBit))
 {
 SvxSwFramePosString::StringId sStrId1 = 
m_xHoriMirrorCB->get_active() ? 

core.git: officecfg/registry sw/inc sw/source

2024-05-06 Thread Miklos Vajna (via logerrit)
 officecfg/registry/schema/org/openoffice/Office/Compatibility.xcs |6 +
 sw/inc/strings.hrc|1 
 sw/inc/viewsh.hxx |2 +
 sw/source/core/doc/DocumentSettingManager.cxx |1 
 sw/source/core/view/viewsh.cxx|   11 
++
 sw/source/ui/config/optcomp.cxx   |6 +
 6 files changed, 27 insertions(+)

New commits:
commit 2f79dc2bc2ddf4006646f235f228b61e3f9ffde0
Author: Miklos Vajna 
AuthorDate: Mon May 6 08:36:18 2024 +0200
Commit: Miklos Vajna 
CommitDate: Mon May 6 10:36:33 2024 +0200

Related: tdf#160833 sw DoNotMirrorRtlDrawObjs: add enable/disable option UI

Doing this via a macro was possible already, but that didn't invalidate
the object positions on the layout, so required a document reload, which
was ugly.

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

diff --git a/officecfg/registry/schema/org/openoffice/Office/Compatibility.xcs 
b/officecfg/registry/schema/org/openoffice/Office/Compatibility.xcs
index 085a380cbd41..9bc722106070 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Compatibility.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Compatibility.xcs
@@ -152,6 +152,12 @@
 
 false
   
+  
+
+  Do not mirror drawing objects anchored in paragraphs with an 
RTL writing direction
+
+false
+  
 
   
   
diff --git a/sw/inc/strings.hrc b/sw/inc/strings.hrc
index a0d04e35ba29..6a36f4740926 100644
--- a/sw/inc/strings.hrc
+++ b/sw/inc/strings.hrc
@@ -1492,6 +1492,7 @@
 #define STR_COMPAT_OPT_NOGAPAFTERNOTENUMBER 
NC_("STR_COMPAT_OPT_NOGAPAFTERNOTENUMBER", "Do not add an extra space after 
number in footnotes / endnotes with hanging first line")
 #define STR_COMPAT_OPT_TABSRELATIVETOINDENT 
NC_("STR_COMPAT_OPT_TABSRELATIVETOINDENT", "Set tabstops relative to indent of 
paragraph")
 #define STR_COMPAT_OPT_TABOVERMARGIN
NC_("STR_COMPAT_OPT_TABOVERMARGIN", "Allow tabs to extend beyond the right 
margin")
+#define STR_COMPAT_OPT_DO_NOT_MIRROR_RTL_DRAW_OBJS 
NC_("DO_NOT_MIRROR_RTL_DRAW_OBJS", "Do not mirror drawing objects anchored in 
paragraphs with an RTL writing direction")
 
 #define STR_TABLE_PANEL_ALIGN_AUTO  
NC_("sidebartableedit|alignautolabel", "Automatic")
 #define STR_TABLE_PANEL_ALIGN_LEFT  
NC_("sidebartableedit|alignleftlabel", "Left")
diff --git a/sw/inc/viewsh.hxx b/sw/inc/viewsh.hxx
index 9417702f5b86..18d33266b627 100644
--- a/sw/inc/viewsh.hxx
+++ b/sw/inc/viewsh.hxx
@@ -451,6 +451,8 @@ public:
 
 SW_DLLPUBLIC void SetTabOverMargin(bool bNew);
 
+SW_DLLPUBLIC void SetDoNotMirrorRtlDrawObjs(bool bDoNotMirrorRtlDrawObjs);
+
 // DOCUMENT COMPATIBILITY FLAGS END
 
 // Calls Idle-formatter of Layout.
diff --git a/sw/source/core/doc/DocumentSettingManager.cxx 
b/sw/source/core/doc/DocumentSettingManager.cxx
index 55b625932efb..501344ca8108 100644
--- a/sw/source/core/doc/DocumentSettingManager.cxx
+++ b/sw/source/core/doc/DocumentSettingManager.cxx
@@ -139,6 +139,7 @@ sw::DocumentSettingManager::DocumentSettingManager(SwDoc 
)
 mbNoGapAfterNoteNumber  = 
aOptions.get(u"NoGapAfterNoteNumber"_ustr);
 mbTabRelativeToIndent   = 
aOptions.get(u"TabsRelativeToIndent"_ustr);
 mbTabOverMargin = 
aOptions.get(u"TabOverMargin"_ustr);
+mbDoNotMirrorRtlDrawObjs= 
aOptions.get(u"DoNotMirrorRtlDrawObjs"_ustr);
 }
 else
 {
diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx
index 5ec658a9cd14..f20eb694e8f4 100644
--- a/sw/source/core/view/viewsh.cxx
+++ b/sw/source/core/view/viewsh.cxx
@@ -1083,6 +1083,17 @@ void SwViewShell::SetTabOverMargin(bool bNew)
 }
 }
 
+void SwViewShell::SetDoNotMirrorRtlDrawObjs(bool bDoNotMirrorRtlDrawObjs)
+{
+IDocumentSettingAccess& rIDSA = getIDocumentSettingAccess();
+if (rIDSA.get(DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS) != 
bDoNotMirrorRtlDrawObjs)
+{
+SwWait aWait(*GetDoc()->GetDocShell(), true);
+rIDSA.set(DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS, 
bDoNotMirrorRtlDrawObjs);
+lcl_InvalidateAllObjPos(*this);
+}
+}
+
 void SwViewShell::Reformat()
 {
 SwWait aWait( *GetDoc()->GetDocShell(), true );
diff --git a/sw/source/ui/config/optcomp.cxx b/sw/source/ui/config/optcomp.cxx
index 9ed4c850bd4d..9d60a786ce8b 100644
--- a/sw/source/ui/config/optcomp.cxx
+++ b/sw/source/ui/config/optcomp.cxx
@@ -62,6 +62,7 @@ constexpr std::pair options_list[]{
 { u"NoGapAfterNoteNumber"_ustr, STR_COMPAT_OPT_NOGAPAFTERNOTENUMBER },
 { u"TabsRelativeToIndent"_ustr, STR_COMPAT_OPT_TABSRELATIVETOINDENT 

core.git: Branch 'libreoffice-24-2' - 2 commits - sw/CppunitTest_sw_writerfilter_filter.mk sw/Module_sw.mk sw/qa sw/source writerfilter/source

2024-05-06 Thread Miklos Vajna (via logerrit)
 sw/CppunitTest_sw_writerfilter_filter.mk|   59 
++
 sw/Module_sw.mk |1 
 sw/qa/core/objectpositioning/objectpositioning.cxx  |   48 

 sw/qa/writerfilter/cppunittests/filter/WriterFilter.cxx |   57 
+
 sw/qa/writerfilter/cppunittests/filter/data/draw-obj-rtl-no-mirror.docx |binary
 sw/source/core/objectpositioning/anchoredobjectposition.cxx |5 
 writerfilter/source/filter/WriterFilter.cxx |1 
 7 files changed, 170 insertions(+), 1 deletion(-)

New commits:
commit 7d75210808f8d8be7ee226031ae27b724cfcfbcc
Author: Miklos Vajna 
AuthorDate: Thu May 2 08:42:25 2024 +0200
Commit: Xisco Fauli 
CommitDate: Mon May 6 10:24:00 2024 +0200

tdf#160833 DOCX import: use the DoNotMirrorRtlDrawObjs compat flag

The bugdoc has a shape which should be on the right page margin, but it
was on the left page margin.

Use the new compat flag to have a layout that matches Word.

This way we don't need to unmap the tweaked position at export time (a
limitation that the DOC filter has).

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

diff --git a/sw/CppunitTest_sw_writerfilter_filter.mk 
b/sw/CppunitTest_sw_writerfilter_filter.mk
new file mode 100644
index ..ad61c66f1ed4
--- /dev/null
+++ b/sw/CppunitTest_sw_writerfilter_filter.mk
@@ -0,0 +1,59 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#*
+#
+# 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/.
+#
+#*
+
+$(eval $(call gb_CppunitTest_CppunitTest,sw_writerfilter_filter))
+
+$(eval $(call gb_CppunitTest_use_externals,sw_writerfilter_filter,\
+   boost_headers \
+   libxml2 \
+))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,sw_writerfilter_filter, \
+sw/qa/writerfilter/cppunittests/filter/WriterFilter \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,sw_writerfilter_filter, \
+basegfx \
+comphelper \
+cppu \
+cppuhelper \
+oox \
+sal \
+subsequenttest \
+test \
+unotest \
+utl \
+tl \
+vcl \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,sw_writerfilter_filter))
+
+$(eval $(call gb_CppunitTest_use_ure,sw_writerfilter_filter))
+$(eval $(call gb_CppunitTest_use_vcl,sw_writerfilter_filter))
+
+$(eval $(call gb_CppunitTest_use_rdb,sw_writerfilter_filter,services))
+
+$(eval $(call gb_CppunitTest_use_custom_headers,sw_writerfilter_filter,\
+   officecfg/registry \
+))
+
+$(eval $(call gb_CppunitTest_use_configuration,sw_writerfilter_filter))
+
+# we need to explicitly depend on library sw_writerfilter because it is not 
implied
+# by a link relation
+$(call gb_CppunitTest_get_target,sw_writerfilter_filter) : $(call 
gb_Library_get_target,sw_writerfilter)
+
+ifneq ($(filter MORE_FONTS,$(BUILD_TYPE)),)
+$(eval $(call 
gb_CppunitTest_set_non_application_font_use,sw_writerfilter_filter,abort))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/sw/Module_sw.mk b/sw/Module_sw.mk
index 7d5679e52f3c..7556ecf33778 100644
--- a/sw/Module_sw.mk
+++ b/sw/Module_sw.mk
@@ -168,6 +168,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,sw,\
 CppunitTest_sw_a11y \
 CppunitTest_sw_core_theme \
 CppunitTest_sw_pdf_test \
+CppunitTest_sw_writerfilter_filter \
 ))
 
 ifneq ($(DISABLE_GUI),TRUE)
diff --git a/sw/qa/writerfilter/cppunittests/filter/WriterFilter.cxx 
b/sw/qa/writerfilter/cppunittests/filter/WriterFilter.cxx
new file mode 100644
index ..10b8cab57a45
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/filter/WriterFilter.cxx
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-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/.
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+using namespace ::com::sun::star;
+
+namespace
+{
+/// Tests for sw/source/writerfilter/filter/WriterFilter.cxx.
+class Test : public UnoApiXmlTest
+{
+public:
+Test()
+: UnoApiXmlTest("/sw/qa/writerfilter/cppunittests/filter/data/")
+{
+}
+};
+
+CPPUNIT_TEST_FIXTURE(Test, 

core.git: include/svx reportdesign/source svx/source

2024-05-06 Thread Miklos Vajna (via logerrit)
 include/svx/svdundo.hxx  |2 +-
 reportdesign/source/core/sdr/UndoActions.cxx |   12 ++--
 reportdesign/source/ui/misc/RptUndo.cxx  |2 +-
 svx/source/form/fmundo.cxx   |8 
 svx/source/svdraw/svdundo.cxx|   24 
 5 files changed, 24 insertions(+), 24 deletions(-)

New commits:
commit 9683305264568d77a1d912f4b0d2e063455feeae
Author: Miklos Vajna 
AuthorDate: Mon May 6 08:19:53 2024 +0200
Commit: Miklos Vajna 
CommitDate: Mon May 6 10:00:58 2024 +0200

svx: prefix members of SdrUndoAction

See tdf#94879 for motivation.

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

diff --git a/include/svx/svdundo.hxx b/include/svx/svdundo.hxx
index 80c7ae4560b3..824f36f06efc 100644
--- a/include/svx/svdundo.hxx
+++ b/include/svx/svdundo.hxx
@@ -60,7 +60,7 @@ namespace svx { namespace diagram {
 class SVXCORE_DLLPUBLIC SdrUndoAction : public SfxUndoAction
 {
 protected:
-SdrModel& rMod;
+SdrModel& m_rMod;
 ViewShellId m_nViewShellId;
 
 protected:
diff --git a/reportdesign/source/core/sdr/UndoActions.cxx 
b/reportdesign/source/core/sdr/UndoActions.cxx
index 5aaa412cf1ff..e078ffa2c931 100644
--- a/reportdesign/source/core/sdr/UndoActions.cxx
+++ b/reportdesign/source/core/sdr/UndoActions.cxx
@@ -113,7 +113,7 @@ OUndoContainerAction::~OUndoContainerAction()
 if ( !xChild.is() || xChild->getParent().is() )
 return;
 
-OXUndoEnvironment& rEnv = static_cast< OReportModel& >( rMod 
).GetUndoEnv();
+OXUndoEnvironment& rEnv = static_cast< OReportModel& >( m_rMod 
).GetUndoEnv();
 rEnv.RemoveElement( m_xOwnElement );
 
 // -> dispose it
@@ -141,7 +141,7 @@ void OUndoContainerAction::implReInsert( )
 
 void OUndoContainerAction::implReRemove( )
 {
-OXUndoEnvironment& rEnv = static_cast< OReportModel& >( rMod 
).GetUndoEnv();
+OXUndoEnvironment& rEnv = static_cast< OReportModel& >( m_rMod 
).GetUndoEnv();
 try
 {
 OXUndoEnvironment::OUndoEnvLock aLock(rEnv);
@@ -234,7 +234,7 @@ OUndoGroupSectionAction::OUndoGroupSectionAction(
 
 void OUndoGroupSectionAction::implReInsert( )
 {
-OXUndoEnvironment& rEnv = static_cast< OReportModel& >( rMod 
).GetUndoEnv();
+OXUndoEnvironment& rEnv = static_cast< OReportModel& >( m_rMod 
).GetUndoEnv();
 try
 {
 OXUndoEnvironment::OUndoEnvLock aLock(rEnv);
@@ -251,7 +251,7 @@ void OUndoGroupSectionAction::implReInsert( )
 
 void OUndoGroupSectionAction::implReRemove( )
 {
-OXUndoEnvironment& rEnv = static_cast< OReportModel& >( rMod 
).GetUndoEnv();
+OXUndoEnvironment& rEnv = static_cast< OReportModel& >( m_rMod 
).GetUndoEnv();
 try
 {
 OXUndoEnvironment::OUndoEnvLock aLock(rEnv);
@@ -278,7 +278,7 @@ OUndoReportSectionAction::OUndoReportSectionAction(
 
 void OUndoReportSectionAction::implReInsert( )
 {
-OXUndoEnvironment& rEnv = static_cast< OReportModel& >( rMod 
).GetUndoEnv();
+OXUndoEnvironment& rEnv = static_cast< OReportModel& >( m_rMod 
).GetUndoEnv();
 try
 {
 OXUndoEnvironment::OUndoEnvLock aLock(rEnv);
@@ -301,7 +301,7 @@ void OUndoReportSectionAction::implReInsert( )
 
 void OUndoReportSectionAction::implReRemove( )
 {
-OXUndoEnvironment& rEnv = static_cast< OReportModel& >( rMod 
).GetUndoEnv();
+OXUndoEnvironment& rEnv = static_cast< OReportModel& >( m_rMod 
).GetUndoEnv();
 try
 {
 OXUndoEnvironment::OUndoEnvLock aLock(rEnv);
diff --git a/reportdesign/source/ui/misc/RptUndo.cxx 
b/reportdesign/source/ui/misc/RptUndo.cxx
index 7a835237722a..bff3c4518b1a 100644
--- a/reportdesign/source/ui/misc/RptUndo.cxx
+++ b/reportdesign/source/ui/misc/RptUndo.cxx
@@ -125,7 +125,7 @@ OSectionUndo::~OSectionUndo()
 if ( m_bInserted )
 return;
 
-OXUndoEnvironment& rEnv = static_cast< OReportModel& >( rMod 
).GetUndoEnv();
+OXUndoEnvironment& rEnv = static_cast< OReportModel& >( m_rMod 
).GetUndoEnv();
 for (uno::Reference& xShape : m_aControls)
 {
 rEnv.RemoveElement(xShape);
diff --git a/svx/source/form/fmundo.cxx b/svx/source/form/fmundo.cxx
index 9bbe99a81d6e..956d4a06e43e 100644
--- a/svx/source/form/fmundo.cxx
+++ b/svx/source/form/fmundo.cxx
@@ -964,7 +964,7 @@ FmUndoPropertyAction::FmUndoPropertyAction(FmFormModel& 
rNewMod, const PropertyC
 
 void FmUndoPropertyAction::Undo()
 {
-FmXUndoEnvironment& rEnv = static_cast(rMod).GetUndoEnv();
+FmXUndoEnvironment& rEnv = static_cast(m_rMod).GetUndoEnv();
 
 if (!xObj.is() || rEnv.IsLocked())
 return;
@@ -984,7 +984,7 @@ void FmUndoPropertyAction::Undo()
 
 void FmUndoPropertyAction::Redo()
 {
-FmXUndoEnvironment& rEnv = static_cast(rMod).GetUndoEnv();
+FmXUndoEnvironment& rEnv = static_cast(m_rMod).GetUndoEnv();
 
 if (!xObj.is() || rEnv.IsLocked())
 return;
@@ 

core.git: sw/qa sw/source

2024-05-03 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 9d95eb980ef12678f6fb978badcbe1cacbe0c4dc
Author: Miklos Vajna 
AuthorDate: Fri May 3 13:54:02 2024 +0200
Commit: Miklos Vajna 
CommitDate: Fri May 3 16:28:04 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

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 d3bc9c4071d9..6caffceffa00 100644
--- a/sw/qa/extras/ww8export/ww8export4.cxx
+++ b/sw/qa/extras/ww8export/ww8export4.cxx
@@ -267,6 +267,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 c13d06106286..21afd78cce1d 100644
--- a/sw/source/filter/ww8/wrtw8esh.cxx
+++ b/sw/source/filter/ww8/wrtw8esh.cxx
@@ -576,6 +576,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 'distro/collabora/co-24.04' - writerfilter/CppunitTest_writerfilter_filter.mk writerfilter/Module_writerfilter.mk writerfilter/qa writerfilter/source

2024-05-03 Thread Miklos Vajna (via logerrit)
 writerfilter/CppunitTest_writerfilter_filter.mk  |   55 
+
 writerfilter/Module_writerfilter.mk  |1 
 writerfilter/qa/cppunittests/filter/WriterFilter.cxx |   57 
++
 writerfilter/qa/cppunittests/filter/data/draw-obj-rtl-no-mirror.docx |binary
 writerfilter/source/filter/WriterFilter.cxx  |1 
 5 files changed, 114 insertions(+)

New commits:
commit ffcd1d52574e19ce45b47758d3ed445d2a9da943
Author: Miklos Vajna 
AuthorDate: Thu May 2 08:42:25 2024 +0200
Commit: Caolán McNamara 
CommitDate: Fri May 3 15:17:14 2024 +0200

tdf#160833 DOCX import: use the DoNotMirrorRtlDrawObjs compat flag

The bugdoc has a shape which should be on the right page margin, but it
was on the left page margin.

Use the new compat flag to have a layout that matches Word.

This way we don't need to unmap the tweaked position at export time (a
limitation that the DOC filter has).

(cherry picked from commit 01dcc9a652ecfc65fb674b492afa6f58b0a846db)

Conflicts:
sw/Module_sw.mk

Change-Id: I38dfae370f275d9f0897198e7b0569f2d91dd352
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167033
Tested-by: Jenkins CollaboraOffice 
Reviewed-by: Caolán McNamara 

diff --git a/writerfilter/CppunitTest_writerfilter_filter.mk 
b/writerfilter/CppunitTest_writerfilter_filter.mk
new file mode 100644
index ..8b719bba5713
--- /dev/null
+++ b/writerfilter/CppunitTest_writerfilter_filter.mk
@@ -0,0 +1,55 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#*
+#
+# 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/.
+#
+#*
+
+$(eval $(call gb_CppunitTest_CppunitTest,writerfilter_filter))
+
+$(eval $(call gb_CppunitTest_use_externals,writerfilter_filter,\
+   boost_headers \
+   libxml2 \
+))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,writerfilter_filter, \
+writerfilter/qa/cppunittests/filter/WriterFilter \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,writerfilter_filter, \
+basegfx \
+comphelper \
+cppu \
+cppuhelper \
+oox \
+sal \
+subsequenttest \
+test \
+unotest \
+utl \
+tl \
+vcl \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,writerfilter_filter))
+
+$(eval $(call gb_CppunitTest_use_ure,writerfilter_filter))
+$(eval $(call gb_CppunitTest_use_vcl,writerfilter_filter))
+
+$(eval $(call gb_CppunitTest_use_rdb,writerfilter_filter,services))
+
+$(eval $(call gb_CppunitTest_use_custom_headers,writerfilter_filter,\
+   officecfg/registry \
+))
+
+$(eval $(call gb_CppunitTest_use_configuration,writerfilter_filter))
+
+# we need to explicitly depend on library writerfilter because it is not 
implied
+# by a link relation
+$(call gb_CppunitTest_get_target,writerfilter_filter) : $(call 
gb_Library_get_target,writerfilter)
+
+# vim: set noet sw=4 ts=4:
diff --git a/writerfilter/Module_writerfilter.mk 
b/writerfilter/Module_writerfilter.mk
index 587bf4fa4dfc..08710edb23e6 100644
--- a/writerfilter/Module_writerfilter.mk
+++ b/writerfilter/Module_writerfilter.mk
@@ -20,6 +20,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,writerfilter,\
 CppunitTest_writerfilter_dmapper \
 CppunitTest_writerfilter_ooxml \
 CppunitTest_writerfilter_rtftok \
+CppunitTest_writerfilter_filter \
 ))
 
 # vim: set noet sw=4 ts=4:
diff --git a/writerfilter/qa/cppunittests/filter/WriterFilter.cxx 
b/writerfilter/qa/cppunittests/filter/WriterFilter.cxx
new file mode 100644
index ..ae741085277c
--- /dev/null
+++ b/writerfilter/qa/cppunittests/filter/WriterFilter.cxx
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-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/.
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+using namespace ::com::sun::star;
+
+namespace
+{
+/// Tests for writerfilter/source/filter/WriterFilter.cxx.
+class Test : public UnoApiXmlTest
+{
+public:
+Test()
+: UnoApiXmlTest("/writerfilter/qa/cppunittests/filter/data/")
+{
+}
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testDoNotMirrorRtlDrawObjs)
+{
+// Given a document with a shape, anchored in an RTL paragraph:
+// When loading that document:
+loadFromFile(u"draw-obj-rtl-no-mirror.docx");
+
+// Then make sure the shape is on 

core.git: Branch 'distro/collabora/co-24.04' - sw/qa sw/source

2024-05-03 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 3e9ff13bb78c56b5ddc6316b0b73c8a21ea7c0b0
Author: Miklos Vajna 
AuthorDate: Fri May 3 12:00:59 2024 +0200
Commit: Caolán McNamara 
CommitDate: Fri May 3 15:16:56 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/+/167048
Tested-by: Jenkins CollaboraOffice 
Tested-by: Caolán McNamara 
Reviewed-by: Caolán McNamara 

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 e297ac949afe..b25d3b4a7701 100644
--- a/sw/qa/extras/ww8export/ww8export4.cxx
+++ b/sw/qa/extras/ww8export/ww8export4.cxx
@@ -262,6 +262,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 f9e1082f9276..3e7087221db0 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: cui/source sw/source

2024-05-03 Thread Miklos Vajna (via logerrit)
 cui/source/inc/swpossizetabpage.hxx  |1 +
 cui/source/tabpages/swpossizetabpage.cxx |   27 +--
 sw/source/uibase/shells/drwbassh.cxx |   10 ++
 3 files changed, 32 insertions(+), 6 deletions(-)

New commits:
commit 0f410680461d7ba5f70dd65b2a8263dec15ac357
Author: Miklos Vajna 
AuthorDate: Fri May 3 08:08:29 2024 +0200
Commit: Miklos Vajna 
CommitDate: Fri May 3 13:51:08 2024 +0200

tdf#160833 sw DoNotMirrorRtlDrawObjs: add UI in cui/

The UI code at lcl_ChangeResIdToVerticalOrRTL() was aware that
SwAnchoredObjectPosition::CalcRelPosX() mirrors the position when the
anchor paragraph is RTL, so swapped the "from left" label to a "from
right" label.

Don't do this when the compat option is enabled, so not only we render
correctly but the UI now correctly explains why we came up with the
correct position.

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

diff --git a/cui/source/inc/swpossizetabpage.hxx 
b/cui/source/inc/swpossizetabpage.hxx
index 2e5a15fbebbb..037cede29326 100644
--- a/cui/source/inc/swpossizetabpage.hxx
+++ b/cui/source/inc/swpossizetabpage.hxx
@@ -53,6 +53,7 @@ class SvxSwPosSizeTabPage : public SfxTabPage
 boolm_bPositioningDisabled;
 boolm_bIsMultiSelection;
 boolm_bIsInRightToLeft;
+bool m_bDoNotMirrorRtlDrawObjs = false;
 TriStatem_nProtectSizeState;
 
 SwFrameExample m_aExampleWN;
diff --git a/cui/source/tabpages/swpossizetabpage.cxx 
b/cui/source/tabpages/swpossizetabpage.cxx
index 1a0d14759eac..752af91a1a62 100644
--- a/cui/source/tabpages/swpossizetabpage.cxx
+++ b/cui/source/tabpages/swpossizetabpage.cxx
@@ -37,6 +37,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -433,14 +434,16 @@ static std::size_t lcl_GetFrmMapCount(const FrmMap* pMap)
 }
 
 static SvxSwFramePosString::StringId lcl_ChangeResIdToVerticalOrRTL(
-SvxSwFramePosString::StringId eStringId, bool bVertical, bool bRTL)
+SvxSwFramePosString::StringId eStringId, bool bVertical, bool 
bRTL, bool bDontMirrorRTL)
 {
 //special handling of STR_FROMLEFT
 if(SvxSwFramePosString::FROMLEFT == eStringId)
 {
+bool bMirrorRtlDrawObjs = !bDontMirrorRTL;
+bool bSwapLR = bRTL && bMirrorRtlDrawObjs;
 eStringId = bVertical ?
 bRTL ? SvxSwFramePosString::FROMBOTTOM : 
SvxSwFramePosString::FROMTOP :
-bRTL ? SvxSwFramePosString::FROMRIGHT : 
SvxSwFramePosString::FROMLEFT;
+bSwapLR ? SvxSwFramePosString::FROMRIGHT : 
SvxSwFramePosString::FROMLEFT;
 return eStringId;
 }
 if(bVertical)
@@ -749,7 +752,8 @@ WhichRangesContainer SvxSwPosSizeTabPage::GetRanges()
 SID_ATTR_TRANSFORM_AUTOWIDTH, SID_ATTR_TRANSFORM_VERT_ORIENT,
 SID_HTML_MODE, SID_HTML_MODE,
 SID_SW_FOLLOW_TEXT_FLOW, SID_SW_FOLLOW_TEXT_FLOW,
-SID_ATTR_TRANSFORM_HORI_POSITION, SID_ATTR_TRANSFORM_VERT_POSITION
+SID_ATTR_TRANSFORM_HORI_POSITION, SID_ATTR_TRANSFORM_VERT_POSITION,
+SID_ATTR_CHAR_GRABBAG, SID_ATTR_CHAR_GRABBAG
 >);
 return ranges;
 }
@@ -988,6 +992,17 @@ void SvxSwPosSizeTabPage::Reset( const SfxItemSet* rSet)
 }
 m_xFollowCB->save_state();
 
+const SfxGrabBagItem* pGrabBag = GetItem(*rSet, SID_ATTR_CHAR_GRABBAG);
+if (pGrabBag)
+{
+const std::map& rMap = pGrabBag->GetGrabBag();
+auto it = rMap.find("DoNotMirrorRtlDrawObjs");
+if (it != rMap.end())
+{
+it->second >>= m_bDoNotMirrorRtlDrawObjs;
+}
+}
+
 if(m_bHtmlMode)
 {
 m_xHoriMirrorCB->hide();
@@ -1677,7 +1692,7 @@ void SvxSwPosSizeTabPage::FillRelLB(FrmMap const *pMap, 
sal_uInt16 nMapPos, sal_
 {
 SvxSwFramePosString::StringId sStrId1 = 
aAsCharRelationMap[nRelPos].eStrId;
 
-sStrId1 = lcl_ChangeResIdToVerticalOrRTL(sStrId1, 
m_bIsVerticalFrame, m_bIsInRightToLeft);
+sStrId1 = lcl_ChangeResIdToVerticalOrRTL(sStrId1, 
m_bIsVerticalFrame, m_bIsInRightToLeft, m_bDoNotMirrorRtlDrawObjs);
 OUString sEntry = 
SvxSwFramePosString::GetString(sStrId1);
 
rLB.append(weld::toId([nRelPos]), sEntry);
 if (pMap[_nMapPos].nAlign == nAlign)
@@ -1732,7 +1747,7 @@ void SvxSwPosSizeTabPage::FillRelLB(FrmMap const *pMap, 
sal_uInt16 nMapPos, sal_
 if (aRelationMap[nRelPos].nLBRelation == 
static_cast(nBit))
 {
 SvxSwFramePosString::StringId sStrId1 = 
m_xHoriMirrorCB->get_active() ? aRelationMap[nRelPos].eMirrorStrId : 
aRelationMap[nRelPos].eStrId;
-sStrId1 = lcl_ChangeResIdToVerticalOrRTL(sStrId1, 

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

2024-05-03 Thread Miklos Vajna (via logerrit)
 sw/inc/IDocumentSettingAccess.hxx |1 +
 sw/qa/uibase/uno/uno.cxx  |   24 
 sw/source/core/doc/DocumentSettingManager.cxx |   10 ++
 sw/source/core/inc/DocumentSettingManager.hxx |1 +
 sw/source/filter/xml/xmlexp.cxx   |1 +
 sw/source/filter/xml/xmlimp.cxx   |   10 ++
 sw/source/uibase/uno/SwXDocumentSettings.cxx  |   18 ++
 7 files changed, 65 insertions(+)

New commits:
commit 799767d5670efc7f996892de5dd7d1afdb4a6cce
Author: Miklos Vajna 
AuthorDate: Mon Apr 29 10:39:43 2024 +0200
Commit: Xisco Fauli 
CommitDate: Fri May 3 11:55:12 2024 +0200

tdf#160833 sw: add a DoNotMirrorRtlDrawObjs compat flag

The DOCX bugdoc has a circle shape anchored inside an RTL paragraph:
this shows up on the right hand side in Word, but on the left hand side
in Writer.

What happens is that Writer implicitly mirrors draw objects anchored in
RTL paragraphs, while Word doesn't do this.

Start fixing the problem by adding a new layout compatibility flag that
can be used by the DOCX import in the future, to leave the behavior
unchanged for new & existing ODT documents.

An alternative would be to do something similar to the DOC import's
SwWW8ImplReader::MiserableRTLGraphicsHack(), but 1) we don't have the
page margins by the time we import the shape and 2) as its name says, it
doesn't feel like a clean solution, it's better to handle this
difference at a layout level.

Change-Id: I2ec067d86c7fbdbe57e4cd9547015fe25a9a56b9
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166820
Reviewed-by: Miklos Vajna 
Tested-by: Jenkins
(cherry picked from commit c675eaf923cf579670b8ba2f7794b47be7fad39e)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166845
Reviewed-by: Xisco Fauli 

diff --git a/sw/inc/IDocumentSettingAccess.hxx 
b/sw/inc/IDocumentSettingAccess.hxx
index 0dd9467bdf13..264860b854c4 100644
--- a/sw/inc/IDocumentSettingAccess.hxx
+++ b/sw/inc/IDocumentSettingAccess.hxx
@@ -99,6 +99,7 @@ enum class DocumentSettingId
 // tdf#119908 new paragraph justification
 JUSTIFY_LINES_WITH_SHRINKING,
 APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH,
+DO_NOT_MIRROR_RTL_DRAW_OBJS,
 // COMPATIBILITY FLAGS END
 BROWSE_MODE,
 HTML_MODE,
diff --git a/sw/qa/uibase/uno/uno.cxx b/sw/qa/uibase/uno/uno.cxx
index d38d0bbfc967..3e6d9c93d51c 100644
--- a/sw/qa/uibase/uno/uno.cxx
+++ b/sw/qa/uibase/uno/uno.cxx
@@ -560,6 +560,30 @@ CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, 
testAllowTextAfterFloatingTableBreak)
 CPPUNIT_ASSERT(bAllowTextAfterFloatingTableBreak);
 }
 
+CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testDoNotMirrorRtlDrawObjs)
+{
+// Given an empty document:
+createSwDoc();
+
+// When checking the state of the DoNotMirrorRtlDrawObjs compat flag:
+uno::Reference xDocument(mxComponent, 
uno::UNO_QUERY);
+uno::Reference xSettings(
+xDocument->createInstance("com.sun.star.document.Settings"), 
uno::UNO_QUERY);
+bool bDoNotMirrorRtlDrawObjs{};
+// Without the accompanying fix in place, this test would have failed with:
+// An uncaught exception of type 
com.sun.star.beans.UnknownPropertyException
+// i.e. the compat flag was not recognized.
+xSettings->getPropertyValue("DoNotMirrorRtlDrawObjs") >>= 
bDoNotMirrorRtlDrawObjs;
+// Then make sure it's false by default:
+CPPUNIT_ASSERT(!bDoNotMirrorRtlDrawObjs);
+
+// And when setting DoNotMirrorRtlDrawObjs=true:
+xSettings->setPropertyValue("DoNotMirrorRtlDrawObjs", uno::Any(true));
+// Then make sure it gets enabled:
+xSettings->getPropertyValue("DoNotMirrorRtlDrawObjs") >>= 
bDoNotMirrorRtlDrawObjs;
+CPPUNIT_ASSERT(bDoNotMirrorRtlDrawObjs);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/DocumentSettingManager.cxx 
b/sw/source/core/doc/DocumentSettingManager.cxx
index 661c001e98c2..14cfa5fd3c24 100644
--- a/sw/source/core/doc/DocumentSettingManager.cxx
+++ b/sw/source/core/doc/DocumentSettingManager.cxx
@@ -256,6 +256,8 @@ bool sw::DocumentSettingManager::get(/*[in]*/ 
DocumentSettingId id) const
 return mbDoNotBreakWrappedTables;
 case DocumentSettingId::ALLOW_TEXT_AFTER_FLOATING_TABLE_BREAK:
 return mbAllowTextAfterFloatingTableBreak;
+case DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS:
+return mbDoNotMirrorRtlDrawObjs;
 case DocumentSettingId::JUSTIFY_LINES_WITH_SHRINKING:
 return mbJustifyLinesWithShrinking;
 case DocumentSettingId::NO_NUMBERING_SHOW_FOLLOWBY: return 
mbNoNumberingShowFollowBy;
@@ -450,6 +452,10 @@ void sw::DocumentSettingManager::set(/*[in]*/ 
DocumentSettingId id, /*[in]*/ boo
 mbApplyTextAttrToEmptyLineAtEndOfParagraph = value;
 break;
 
+case 

core.git: Branch 'libreoffice-7-6-7' - sc/source

2024-05-03 Thread Miklos Vajna (via logerrit)
 sc/source/core/data/column3.cxx |5 +
 1 file changed, 5 insertions(+)

New commits:
commit 1f49854c0d18000f52d3ad4525bb52b2f35cc064
Author: Miklos Vajna 
AuthorDate: Wed Apr 24 09:37:35 2024 +0200
Commit: Michael Stahl 
CommitDate: Fri May 3 11:42:03 2024 +0200

sc: fix crash in ScColumn::SetEditText()

Crashreport:

> SIG   Fatal signal received: SIGSEGV code: 128 for address: 0x0
> program/libsclo.so
>   ScColumn::SetEditText(int, std::unique_ptr >)
>   sc/source/core/data/column3.cxx:2362
> program/libsclo.so
>   ScTable::SetEditText(short, int, std::unique_ptr >)
>   
/opt/rh/devtoolset-12/root/usr/include/c++/12/bits/unique_ptr.h:395
> program/libsclo.so
>   ScDocument::SetEditText(ScAddress const&, 
std::unique_ptr >)
>   
/opt/rh/devtoolset-12/root/usr/include/c++/12/bits/unique_ptr.h:395
> program/libsclo.so
>   ScDocFunc::SetEditCell(ScAddress const&, EditTextObject const&, 
bool)
>   
/opt/rh/devtoolset-12/root/usr/include/c++/12/bits/unique_ptr.h:395
> program/libsclo.so
>   (anonymous 
namespace)::finalizeFormulaProcessing(std::shared_ptr<(anonymous 
namespace)::FormulaProcessingContext>)
>   sc/source/ui/view/viewfunc.cxx:565

Change-Id: I331ca8784702fdcb0ebad6a0a73390dbe2615ece
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166612
Tested-by: Jenkins
Reviewed-by: Miklos Vajna 
(cherry picked from commit e3ce4aad47c052dcd67107f7c91336f4ecc949be)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166526
Reviewed-by: Xisco Fauli 
(cherry picked from commit 58b85fc5e4ebe6c8a77e2b1935c23bf0ebebad0a)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166848
Tested-by: Michael Stahl 
Reviewed-by: Michael Stahl 
Reviewed-by: Eike Rathke 

diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index f0f4cc83263b..5a1582e560d7 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -2358,6 +2358,11 @@ bool ScColumn::SetString( SCROW nRow, SCTAB nTabP, const 
OUString& rString,
 
 void ScColumn::SetEditText( SCROW nRow, std::unique_ptr 
pEditText )
 {
+if (!pEditText)
+{
+return;
+}
+
 pEditText->NormalizeString(GetDoc().GetSharedStringPool());
 std::vector aNewSharedRows;
 sc::CellStoreType::iterator it = GetPositionToInsert(nRow, aNewSharedRows, 
false);


core.git: Branch 'distro/collabora/co-24.04' - sw/qa sw/source

2024-05-02 Thread Miklos Vajna (via logerrit)
 sw/qa/core/objectpositioning/objectpositioning.cxx  |   48 
 sw/source/core/objectpositioning/anchoredobjectposition.cxx |5 +
 2 files changed, 52 insertions(+), 1 deletion(-)

New commits:
commit 7f790600a530f7ca7c1e7de0abc0a5bf2f6b3023
Author: Miklos Vajna 
AuthorDate: Tue Apr 30 08:22:03 2024 +0200
Commit: Caolán McNamara 
CommitDate: Thu May 2 14:26:20 2024 +0200

tdf#160833 sw DoNotMirrorRtlDrawObjs: add layout

In case this flag is active (intended for DOCX files), then don't
automatically mirror the position of drawing objects, just because they
are anchored in an RTL text node.

(cherry picked from commit 016b2f2f9194a4a1997d0e7bb51bbd1b10bc27ec)

Change-Id: Ie743d94ecb511d7de89e8e1e8303896370ce58c8
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167013
Tested-by: Jenkins CollaboraOffice 
Tested-by: Caolán McNamara 
Reviewed-by: Caolán McNamara 

diff --git a/sw/qa/core/objectpositioning/objectpositioning.cxx 
b/sw/qa/core/objectpositioning/objectpositioning.cxx
index bf560cbdaf90..a1805bf4508e 100644
--- a/sw/qa/core/objectpositioning/objectpositioning.cxx
+++ b/sw/qa/core/objectpositioning/objectpositioning.cxx
@@ -24,6 +24,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 
 namespace
 {
@@ -404,6 +408,50 @@ CPPUNIT_TEST_FIXTURE(Test, testFloatingTableOverlapCell)
 CPPUNIT_ASSERT(pPage1);
 CPPUNIT_ASSERT(!pPage1->GetNext());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testDoNotMirrorRtlDrawObjsLayout)
+{
+// Given a document with an RTL paragraph, Word-style compat flag is 
enabled:
+createSwDoc();
+SwDoc* pDoc = getSwDoc();
+auto& rIDSA = pDoc->getIDocumentSettingAccess();
+rIDSA.set(DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS, true);
+SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
+SwView& rView = pWrtShell->GetView();
+SfxItemSetFixed aSet(rView.GetPool());
+SvxFrameDirectionItem aDirection(SvxFrameDirection::Horizontal_RL_TB, 
RES_FRAMEDIR);
+aSet.Put(aDirection);
+pWrtShell->SetAttrSet(aSet, SetAttrMode::DEFAULT, nullptr, 
/*bParagraphSetting=*/true);
+SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+auto pPageFrame = pLayout->Lower()->DynCastPageFrame();
+SwFrame* pBodyFrame = pPageFrame->GetLower();
+
+// When inserting a graphic on the middle of the right margin:
+SfxItemSet aFrameSet(pDoc->GetAttrPool(), svl::Items);
+SwFormatAnchor aAnchor(RndStdIds::FLY_AT_CHAR);
+aFrameSet.Put(aAnchor);
+// Default margin is 1440, this is 1440/2.
+SwFormatFrameSize aSize(SwFrameSize::Fixed, 720, 720);
+aFrameSet.Put(aSize);
+// This is 1440/4.
+SwFormatHoriOrient aOrient(pBodyFrame->getFrameArea().Right() + 360);
+aFrameSet.Put(aOrient);
+Graphic aGrf;
+pWrtShell->SwFEShell::Insert(OUString(), OUString(), , );
+
+// Then make sure that the image is on the right margin:
+SwTwips nBodyRight = pBodyFrame->getFrameArea().Right();
+CPPUNIT_ASSERT(pPageFrame->GetSortedObjs());
+const SwSortedObjs& rPageObjs = *pPageFrame->GetSortedObjs();
+CPPUNIT_ASSERT_EQUAL(static_cast(1), rPageObjs.size());
+const SwAnchoredObject* pAnchored = rPageObjs[0];
+Point aAnchoredCenter = 
pAnchored->GetDrawObj()->GetLastBoundRect().Center();
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected greater than: 11389
+// - Actual  : 643
+// i.e. the graphic was on the left margin, not on the right margin.
+CPPUNIT_ASSERT_GREATER(nBodyRight, aAnchoredCenter.getX());
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/objectpositioning/anchoredobjectposition.cxx 
b/sw/source/core/objectpositioning/anchoredobjectposition.cxx
index ab35ae7af738..4af3af542b27 100644
--- a/sw/source/core/objectpositioning/anchoredobjectposition.cxx
+++ b/sw/source/core/objectpositioning/anchoredobjectposition.cxx
@@ -852,7 +852,10 @@ SwTwips SwAnchoredObjectPosition::CalcRelPosX(
 if ( _rHoriOrient.GetHoriOrient() == text::HoriOrientation::NONE )
 {
 // 'manual' horizontal position
-const bool bR2L = rAnchorFrame.IsRightToLeft();
+const IDocumentSettingAccess& rIDSA = 
mpFrameFormat->getIDocumentSettingAccess();
+// If compat flag is active, then disable automatic mirroring for RTL.
+bool bMirrorRtlDrawObjs = 
!rIDSA.get(DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS);
+const bool bR2L = rAnchorFrame.IsRightToLeft() && bMirrorRtlDrawObjs;
 if( IsAnchoredToChar() && text::RelOrientation::CHAR == eRelOrient )
 {
 if( bR2L )


core.git: sw/CppunitTest_sw_writerfilter_filter.mk sw/Module_sw.mk sw/qa sw/source

2024-05-02 Thread Miklos Vajna (via logerrit)
 sw/CppunitTest_sw_writerfilter_filter.mk|   59 
++
 sw/Module_sw.mk |1 
 sw/qa/writerfilter/cppunittests/filter/WriterFilter.cxx |   57 
+
 sw/qa/writerfilter/cppunittests/filter/data/draw-obj-rtl-no-mirror.docx |binary
 sw/source/writerfilter/filter/WriterFilter.cxx  |1 
 5 files changed, 118 insertions(+)

New commits:
commit 01dcc9a652ecfc65fb674b492afa6f58b0a846db
Author: Miklos Vajna 
AuthorDate: Thu May 2 08:42:25 2024 +0200
Commit: Miklos Vajna 
CommitDate: Thu May 2 12:08:31 2024 +0200

tdf#160833 DOCX import: use the DoNotMirrorRtlDrawObjs compat flag

The bugdoc has a shape which should be on the right page margin, but it
was on the left page margin.

Use the new compat flag to have a layout that matches Word.

This way we don't need to unmap the tweaked position at export time (a
limitation that the DOC filter has).

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

diff --git a/sw/CppunitTest_sw_writerfilter_filter.mk 
b/sw/CppunitTest_sw_writerfilter_filter.mk
new file mode 100644
index ..ad61c66f1ed4
--- /dev/null
+++ b/sw/CppunitTest_sw_writerfilter_filter.mk
@@ -0,0 +1,59 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#*
+#
+# 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/.
+#
+#*
+
+$(eval $(call gb_CppunitTest_CppunitTest,sw_writerfilter_filter))
+
+$(eval $(call gb_CppunitTest_use_externals,sw_writerfilter_filter,\
+   boost_headers \
+   libxml2 \
+))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,sw_writerfilter_filter, \
+sw/qa/writerfilter/cppunittests/filter/WriterFilter \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,sw_writerfilter_filter, \
+basegfx \
+comphelper \
+cppu \
+cppuhelper \
+oox \
+sal \
+subsequenttest \
+test \
+unotest \
+utl \
+tl \
+vcl \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,sw_writerfilter_filter))
+
+$(eval $(call gb_CppunitTest_use_ure,sw_writerfilter_filter))
+$(eval $(call gb_CppunitTest_use_vcl,sw_writerfilter_filter))
+
+$(eval $(call gb_CppunitTest_use_rdb,sw_writerfilter_filter,services))
+
+$(eval $(call gb_CppunitTest_use_custom_headers,sw_writerfilter_filter,\
+   officecfg/registry \
+))
+
+$(eval $(call gb_CppunitTest_use_configuration,sw_writerfilter_filter))
+
+# we need to explicitly depend on library sw_writerfilter because it is not 
implied
+# by a link relation
+$(call gb_CppunitTest_get_target,sw_writerfilter_filter) : $(call 
gb_Library_get_target,sw_writerfilter)
+
+ifneq ($(filter MORE_FONTS,$(BUILD_TYPE)),)
+$(eval $(call 
gb_CppunitTest_set_non_application_font_use,sw_writerfilter_filter,abort))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/sw/Module_sw.mk b/sw/Module_sw.mk
index 3fcd0f85ed56..fc2afe9fb7d9 100644
--- a/sw/Module_sw.mk
+++ b/sw/Module_sw.mk
@@ -175,6 +175,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,sw,\
 CppunitTest_sw_writerfilter_dmapper \
 CppunitTest_sw_writerfilter_ooxml \
 CppunitTest_sw_writerfilter_rtftok \
+CppunitTest_sw_writerfilter_filter \
 ))
 
 ifneq ($(DISABLE_GUI),TRUE)
diff --git a/sw/qa/writerfilter/cppunittests/filter/WriterFilter.cxx 
b/sw/qa/writerfilter/cppunittests/filter/WriterFilter.cxx
new file mode 100644
index ..10b8cab57a45
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/filter/WriterFilter.cxx
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-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/.
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+using namespace ::com::sun::star;
+
+namespace
+{
+/// Tests for sw/source/writerfilter/filter/WriterFilter.cxx.
+class Test : public UnoApiXmlTest
+{
+public:
+Test()
+: UnoApiXmlTest("/sw/qa/writerfilter/cppunittests/filter/data/")
+{
+}
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testDoNotMirrorRtlDrawObjs)
+{
+// Given a document with a shape, anchored in an RTL paragraph:
+// When loading that document:
+loadFromFile(u"draw-obj-rtl-no-mirror.docx");
+
+// Then make sure the shape is on the right margin:
+

core.git: sw/qa

2024-05-02 Thread Miklos Vajna (via logerrit)
 sw/qa/extras/rtfexport/rtfexport5.cxx | 1509 +-
 1 file changed, 948 insertions(+), 561 deletions(-)

New commits:
commit ceaba8bf5903b454ff717d788d2298edbf92bac2
Author: Miklos Vajna 
AuthorDate: Thu May 2 08:19:38 2024 +0200
Commit: Miklos Vajna 
CommitDate: Thu May 2 11:43:30 2024 +0200

CppunitTest_sw_rtfexport5: avoid DECLARE_RTFEXPORT_TEST

No need to go via Writer-specific macros here.

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

diff --git a/sw/qa/extras/rtfexport/rtfexport5.cxx 
b/sw/qa/extras/rtfexport/rtfexport5.cxx
index 18ff21848af8..8b897485e92b 100644
--- a/sw/qa/extras/rtfexport/rtfexport5.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport5.cxx
@@ -40,115 +40,188 @@ public:
 }
 };
 
-DECLARE_RTFEXPORT_TEST(testFdo63023, "fdo63023.rtf")
-{
-uno::Reference xHeaderText = 
getProperty>(
-getStyles("PageStyles")->getByName("Standard"), "HeaderText");
-// Back color was black (0) in the header, due to missing color table in 
the substream.
-CPPUNIT_ASSERT_EQUAL(
-Color(0x99),
-getProperty(getRun(getParagraphOfText(1, xHeaderText), 1), 
"CharBackColor"));
+CPPUNIT_TEST_FIXTURE(Test, testFdo63023)
+{
+auto verify = [this]() {
+uno::Reference xHeaderText = 
getProperty>(
+getStyles("PageStyles")->getByName("Standard"), "HeaderText");
+// Back color was black (0) in the header, due to missing color table 
in the substream.
+CPPUNIT_ASSERT_EQUAL(
+Color(0x99),
+getProperty(getRun(getParagraphOfText(1, xHeaderText), 1), 
"CharBackColor"));
+};
+createSwDoc("fdo63023.rtf");
+verify();
+saveAndReload(mpFilter);
+verify();
 }
 
-DECLARE_RTFEXPORT_TEST(testFdo42109, "fdo42109.rtf")
-{
-uno::Reference xTextTablesSupplier(mxComponent, 
uno::UNO_QUERY);
-uno::Reference 
xTables(xTextTablesSupplier->getTextTables(),
-uno::UNO_QUERY);
-uno::Reference xTable(xTables->getByIndex(0), 
uno::UNO_QUERY);
-uno::Reference xCell(xTable->getCellByName("B1"), 
uno::UNO_QUERY);
-// Make sure the page number is imported as a field in the B1 cell.
-CPPUNIT_ASSERT_EQUAL(OUString("TextField"),
- getProperty(getRun(getParagraphOfText(1, 
xCell->getText()), 1),
-   "TextPortionType"));
+CPPUNIT_TEST_FIXTURE(Test, testFdo42109)
+{
+auto verify = [this]() {
+uno::Reference 
xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
+uno::Reference 
xTables(xTextTablesSupplier->getTextTables(),
+uno::UNO_QUERY);
+uno::Reference xTable(xTables->getByIndex(0), 
uno::UNO_QUERY);
+uno::Reference xCell(xTable->getCellByName("B1"), 
uno::UNO_QUERY);
+// Make sure the page number is imported as a field in the B1 cell.
+CPPUNIT_ASSERT_EQUAL(
+OUString("TextField"),
+getProperty(getRun(getParagraphOfText(1, 
xCell->getText()), 1),
+  "TextPortionType"));
+};
+createSwDoc("fdo42109.rtf");
+verify();
+saveAndReload(mpFilter);
+verify();
 }
 
-DECLARE_RTFEXPORT_TEST(testFdo62977, "fdo62977.rtf")
+CPPUNIT_TEST_FIXTURE(Test, testFdo62977)
 {
-// The middle character was imported as '?' instead of the proper unicode 
value.
-getRun(getParagraph(1), 1, u"\u5E74\uFF14\u6708"_ustr);
+auto verify = [this]() {
+// The middle character was imported as '?' instead of the proper 
unicode value.
+getRun(getParagraph(1), 1, u"\u5E74\uFF14\u6708"_ustr);
+};
+createSwDoc("fdo62977.rtf");
+verify();
+saveAndReload(mpFilter);
+verify();
 }
 
-DECLARE_RTFEXPORT_TEST(testN818997, "n818997.rtf")
+CPPUNIT_TEST_FIXTURE(Test, testN818997)
 {
-// \page was ignored between two \shp tokens.
-CPPUNIT_ASSERT_EQUAL(2, getPages());
+auto verify = [this]() {
+// \page was ignored between two \shp tokens.
+CPPUNIT_ASSERT_EQUAL(2, getPages());
+};
+createSwDoc("n818997.rtf");
+verify();
+saveAndReload(mpFilter);
+verify();
 }
 
-DECLARE_RTFEXPORT_TEST(testN818997B, "n818997B.rtf")
+CPPUNIT_TEST_FIXTURE(Test, testN818997B)
 {
-// \page was ignored between two \shp tokens - this time not 
IsFirstParagraphInSection.
-CPPUNIT_ASSERT_EQUAL(2, getPages());
+auto verify = [this]() {
+// \page was ignored between two \shp tokens - this time not 
IsFirstParagraphInSection.
+CPPUNIT_ASSERT_EQUAL(2, getPages());
+};
+createSwDoc("n818997B.rtf");
+verify();
+saveAndReload(mpFilter);
+verify();
 }
 
-DECLARE_RTFEXPORT_TEST(testTdf153613_anchoredAfterPgBreak, 
"tdf153613_anchoredAfterPgBreak.rtf")
+CPPUNIT_TEST_FIXTURE(Test, 

core.git: Branch 'distro/collabora/co-24.04' - sw/inc sw/qa sw/source

2024-04-30 Thread Miklos Vajna (via logerrit)
 sw/inc/IDocumentSettingAccess.hxx |1 +
 sw/qa/uibase/uno/uno.cxx  |   24 
 sw/source/core/doc/DocumentSettingManager.cxx |   10 ++
 sw/source/core/inc/DocumentSettingManager.hxx |1 +
 sw/source/filter/xml/xmlexp.cxx   |1 +
 sw/source/filter/xml/xmlimp.cxx   |   10 ++
 sw/source/uibase/uno/SwXDocumentSettings.cxx  |   18 ++
 7 files changed, 65 insertions(+)

New commits:
commit 99417eb50996e50c99d9557444ad5ce321901ef4
Author: Miklos Vajna 
AuthorDate: Mon Apr 29 10:39:43 2024 +0200
Commit: Caolán McNamara 
CommitDate: Tue Apr 30 11:51:09 2024 +0200

tdf#160833 sw: add a DoNotMirrorRtlDrawObjs compat flag

The DOCX bugdoc has a circle shape anchored inside an RTL paragraph:
this shows up on the right hand side in Word, but on the left hand side
in Writer.

What happens is that Writer implicitly mirrors draw objects anchored in
RTL paragraphs, while Word doesn't do this.

Start fixing the problem by adding a new layout compatibility flag that
can be used by the DOCX import in the future, to leave the behavior
unchanged for new & existing ODT documents.

An alternative would be to do something similar to the DOC import's
SwWW8ImplReader::MiserableRTLGraphicsHack(), but 1) we don't have the
page margins by the time we import the shape and 2) as its name says, it
doesn't feel like a clean solution, it's better to handle this
difference at a layout level.

(cherry picked from commit c675eaf923cf579670b8ba2f7794b47be7fad39e)

Change-Id: I2ec067d86c7fbdbe57e4cd9547015fe25a9a56b9
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166917
Tested-by: Caolán McNamara 
Reviewed-by: Caolán McNamara 
Tested-by: Jenkins CollaboraOffice 

diff --git a/sw/inc/IDocumentSettingAccess.hxx 
b/sw/inc/IDocumentSettingAccess.hxx
index 0dd9467bdf13..264860b854c4 100644
--- a/sw/inc/IDocumentSettingAccess.hxx
+++ b/sw/inc/IDocumentSettingAccess.hxx
@@ -99,6 +99,7 @@ enum class DocumentSettingId
 // tdf#119908 new paragraph justification
 JUSTIFY_LINES_WITH_SHRINKING,
 APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH,
+DO_NOT_MIRROR_RTL_DRAW_OBJS,
 // COMPATIBILITY FLAGS END
 BROWSE_MODE,
 HTML_MODE,
diff --git a/sw/qa/uibase/uno/uno.cxx b/sw/qa/uibase/uno/uno.cxx
index d38d0bbfc967..3e6d9c93d51c 100644
--- a/sw/qa/uibase/uno/uno.cxx
+++ b/sw/qa/uibase/uno/uno.cxx
@@ -560,6 +560,30 @@ CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, 
testAllowTextAfterFloatingTableBreak)
 CPPUNIT_ASSERT(bAllowTextAfterFloatingTableBreak);
 }
 
+CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testDoNotMirrorRtlDrawObjs)
+{
+// Given an empty document:
+createSwDoc();
+
+// When checking the state of the DoNotMirrorRtlDrawObjs compat flag:
+uno::Reference xDocument(mxComponent, 
uno::UNO_QUERY);
+uno::Reference xSettings(
+xDocument->createInstance("com.sun.star.document.Settings"), 
uno::UNO_QUERY);
+bool bDoNotMirrorRtlDrawObjs{};
+// Without the accompanying fix in place, this test would have failed with:
+// An uncaught exception of type 
com.sun.star.beans.UnknownPropertyException
+// i.e. the compat flag was not recognized.
+xSettings->getPropertyValue("DoNotMirrorRtlDrawObjs") >>= 
bDoNotMirrorRtlDrawObjs;
+// Then make sure it's false by default:
+CPPUNIT_ASSERT(!bDoNotMirrorRtlDrawObjs);
+
+// And when setting DoNotMirrorRtlDrawObjs=true:
+xSettings->setPropertyValue("DoNotMirrorRtlDrawObjs", uno::Any(true));
+// Then make sure it gets enabled:
+xSettings->getPropertyValue("DoNotMirrorRtlDrawObjs") >>= 
bDoNotMirrorRtlDrawObjs;
+CPPUNIT_ASSERT(bDoNotMirrorRtlDrawObjs);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/DocumentSettingManager.cxx 
b/sw/source/core/doc/DocumentSettingManager.cxx
index 661c001e98c2..14cfa5fd3c24 100644
--- a/sw/source/core/doc/DocumentSettingManager.cxx
+++ b/sw/source/core/doc/DocumentSettingManager.cxx
@@ -256,6 +256,8 @@ bool sw::DocumentSettingManager::get(/*[in]*/ 
DocumentSettingId id) const
 return mbDoNotBreakWrappedTables;
 case DocumentSettingId::ALLOW_TEXT_AFTER_FLOATING_TABLE_BREAK:
 return mbAllowTextAfterFloatingTableBreak;
+case DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS:
+return mbDoNotMirrorRtlDrawObjs;
 case DocumentSettingId::JUSTIFY_LINES_WITH_SHRINKING:
 return mbJustifyLinesWithShrinking;
 case DocumentSettingId::NO_NUMBERING_SHOW_FOLLOWBY: return 
mbNoNumberingShowFollowBy;
@@ -450,6 +452,10 @@ void sw::DocumentSettingManager::set(/*[in]*/ 
DocumentSettingId id, /*[in]*/ boo
 mbApplyTextAttrToEmptyLineAtEndOfParagraph = value;
 break;
 
+case 

core.git: sw/qa sw/source

2024-04-30 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 06aeb9c61d50bba7edafe17f9d3513af26b0782f
Author: Miklos Vajna 
AuthorDate: Tue Apr 30 08:44:59 2024 +0200
Commit: Miklos Vajna 
CommitDate: Tue Apr 30 10:12:13 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

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 dec97c2ab910..b2bc0cec8b22 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 60161c3b8f89..c684b005504f 100644
--- a/sw/source/core/txtnode/thints.cxx
+++ b/sw/source/core/txtnode/thints.cxx
@@ -1698,7 +1698,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: sw/qa sw/source

2024-04-30 Thread Miklos Vajna (via logerrit)
 sw/qa/core/objectpositioning/objectpositioning.cxx  |   48 
 sw/source/core/objectpositioning/anchoredobjectposition.cxx |5 +
 2 files changed, 52 insertions(+), 1 deletion(-)

New commits:
commit 016b2f2f9194a4a1997d0e7bb51bbd1b10bc27ec
Author: Miklos Vajna 
AuthorDate: Tue Apr 30 08:22:03 2024 +0200
Commit: Miklos Vajna 
CommitDate: Tue Apr 30 09:45:40 2024 +0200

tdf#160833 sw DoNotMirrorRtlDrawObjs: add layout

In case this flag is active (intended for DOCX files), then don't
automatically mirror the position of drawing objects, just because they
are anchored in an RTL text node.

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

diff --git a/sw/qa/core/objectpositioning/objectpositioning.cxx 
b/sw/qa/core/objectpositioning/objectpositioning.cxx
index 717d63ded052..60a14c90547a 100644
--- a/sw/qa/core/objectpositioning/objectpositioning.cxx
+++ b/sw/qa/core/objectpositioning/objectpositioning.cxx
@@ -24,6 +24,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 
 #include 
 
@@ -418,6 +422,50 @@ CPPUNIT_TEST_FIXTURE(Test, testFloatingTableOverlapCell)
 CPPUNIT_ASSERT(pPage1);
 CPPUNIT_ASSERT(!pPage1->GetNext());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testDoNotMirrorRtlDrawObjsLayout)
+{
+// Given a document with an RTL paragraph, Word-style compat flag is 
enabled:
+createSwDoc();
+SwDoc* pDoc = getSwDoc();
+auto& rIDSA = pDoc->getIDocumentSettingAccess();
+rIDSA.set(DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS, true);
+SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
+SwView& rView = pWrtShell->GetView();
+SfxItemSetFixed aSet(rView.GetPool());
+SvxFrameDirectionItem aDirection(SvxFrameDirection::Horizontal_RL_TB, 
RES_FRAMEDIR);
+aSet.Put(aDirection);
+pWrtShell->SetAttrSet(aSet, SetAttrMode::DEFAULT, nullptr, 
/*bParagraphSetting=*/true);
+SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+auto pPageFrame = pLayout->Lower()->DynCastPageFrame();
+SwFrame* pBodyFrame = pPageFrame->GetLower();
+
+// When inserting a graphic on the middle of the right margin:
+SfxItemSet aFrameSet(pDoc->GetAttrPool(), svl::Items);
+SwFormatAnchor aAnchor(RndStdIds::FLY_AT_CHAR);
+aFrameSet.Put(aAnchor);
+// Default margin is 1440, this is 1440/2.
+SwFormatFrameSize aSize(SwFrameSize::Fixed, 720, 720);
+aFrameSet.Put(aSize);
+// This is 1440/4.
+SwFormatHoriOrient aOrient(pBodyFrame->getFrameArea().Right() + 360);
+aFrameSet.Put(aOrient);
+Graphic aGrf;
+pWrtShell->SwFEShell::Insert(OUString(), OUString(), , );
+
+// Then make sure that the image is on the right margin:
+SwTwips nBodyRight = pBodyFrame->getFrameArea().Right();
+CPPUNIT_ASSERT(pPageFrame->GetSortedObjs());
+const SwSortedObjs& rPageObjs = *pPageFrame->GetSortedObjs();
+CPPUNIT_ASSERT_EQUAL(static_cast(1), rPageObjs.size());
+const SwAnchoredObject* pAnchored = rPageObjs[0];
+Point aAnchoredCenter = 
pAnchored->GetDrawObj()->GetLastBoundRect().Center();
+// Without the accompanying fix in place, this test would have failed with:
+// - Expected greater than: 11389
+// - Actual  : 643
+// i.e. the graphic was on the left margin, not on the right margin.
+CPPUNIT_ASSERT_GREATER(nBodyRight, aAnchoredCenter.getX());
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/objectpositioning/anchoredobjectposition.cxx 
b/sw/source/core/objectpositioning/anchoredobjectposition.cxx
index ab35ae7af738..4af3af542b27 100644
--- a/sw/source/core/objectpositioning/anchoredobjectposition.cxx
+++ b/sw/source/core/objectpositioning/anchoredobjectposition.cxx
@@ -852,7 +852,10 @@ SwTwips SwAnchoredObjectPosition::CalcRelPosX(
 if ( _rHoriOrient.GetHoriOrient() == text::HoriOrientation::NONE )
 {
 // 'manual' horizontal position
-const bool bR2L = rAnchorFrame.IsRightToLeft();
+const IDocumentSettingAccess& rIDSA = 
mpFrameFormat->getIDocumentSettingAccess();
+// If compat flag is active, then disable automatic mirroring for RTL.
+bool bMirrorRtlDrawObjs = 
!rIDSA.get(DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS);
+const bool bR2L = rAnchorFrame.IsRightToLeft() && bMirrorRtlDrawObjs;
 if( IsAnchoredToChar() && text::RelOrientation::CHAR == eRelOrient )
 {
 if( bR2L )


core.git: Branch 'distro/collabora/co-24.04' - sw/qa sw/source

2024-04-30 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 d7f6f7bd0dd5428bd1fd483dd13102174a19cd8e
Author: Miklos Vajna 
AuthorDate: Tue Apr 23 08:29:07 2024 +0200
Commit: Miklos Vajna 
CommitDate: Tue Apr 30 09:17:24 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 
(cherry picked from commit 008b1c3a8652b33b9b42ca0794a21ce9754e96f2)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166884
Tested-by: Jenkins CollaboraOffice 

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 = 

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;
+

  1   2   3   4   5   6   7   8   9   10   >