core.git: sw/qa sw/source

2024-05-31 Thread László Németh (via logerrit)
 sw/qa/extras/uiwriter/uiwriter6.cxx |   62 
 sw/source/core/frmedt/feshview.cxx  |   24 +
 2 files changed, 86 insertions(+)

New commits:
commit 014e5f559a9acf319af24c721dbe6b0bc3bc5882
Author: László Németh 
AuthorDate: Fri May 31 12:38:12 2024 +0200
Commit: László Németh 
CommitDate: Fri May 31 20:46:16 2024 +0200

tdf#161360 sw: fix cursor position deselecting image in table

In tables, when the selected image was anchored as character
at beginning of the table row, pressing Escape resulted completely
lost text cursor (after a short blinking, not visible, missing
typing etc.) or – in the case of floating tables – cursor in
a bad position (after the table instead of before the image).

Change-Id: Ib49211ec3531110fc8f5f65fb700318884519666
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168289
Reviewed-by: László Németh 
Tested-by: Jenkins

diff --git a/sw/qa/extras/uiwriter/uiwriter6.cxx 
b/sw/qa/extras/uiwriter/uiwriter6.cxx
index aedec9304791..a27f506095b3 100644
--- a/sw/qa/extras/uiwriter/uiwriter6.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter6.cxx
@@ -1683,6 +1683,68 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf161332)
 CPPUNIT_ASSERT_EQUAL(SelectionType::Frame, eType2);
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf161360)
+{
+createSwDoc("tdf160842.fodt");
+SwDoc* pDoc = getSwDoc();
+CPPUNIT_ASSERT(pDoc);
+SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+CPPUNIT_ASSERT(pWrtShell);
+// the cursor is not in the table
+CPPUNIT_ASSERT(!pWrtShell->IsCursorInTable());
+
+SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+auto pPage = dynamic_cast(pLayout->Lower());
+CPPUNIT_ASSERT(pPage);
+const SwSortedObjs& rPageObjs = *pPage->GetSortedObjs();
+CPPUNIT_ASSERT_EQUAL(static_cast(1), rPageObjs.size());
+auto pPageFly = dynamic_cast(rPageObjs[0]);
+CPPUNIT_ASSERT(pPageFly);
+auto pTable = dynamic_cast(pPageFly->GetLower());
+CPPUNIT_ASSERT(pTable);
+auto pRow1 = pTable->GetLower();
+CPPUNIT_ASSERT(pRow1->IsRowFrame());
+auto pCellA1 = pRow1->GetLower();
+CPPUNIT_ASSERT(pCellA1);
+const SwRect& rCellA1Rect = pCellA1->getFrameArea();
+auto nRowHeight = rCellA1Rect.Height();
+
+// select image by clicking on it at the center of the upper cell
+Point ptFrom(rCellA1Rect.Left() + rCellA1Rect.Width() / 2, 
rCellA1Rect.Top() + nRowHeight / 2);
+vcl::Window& rEditWin = pDoc->GetDocShell()->GetView()->GetEditWin();
+Point aFrom = rEditWin.LogicToPixel(ptFrom);
+MouseEvent aClickEvent(aFrom, 1, MouseEventModifiers::SIMPLECLICK, 
MOUSE_LEFT);
+rEditWin.MouseButtonDown(aClickEvent);
+rEditWin.MouseButtonUp(aClickEvent);
+
+// Then make sure that the image is selected:
+SelectionType eType = pWrtShell->GetSelectionType();
+CPPUNIT_ASSERT_EQUAL(SelectionType::Graphic, eType);
+
+// select the text frame instead of the image
+// by pressing Escape
+dispatchCommand(mxComponent, ".uno:Escape", {});
+
+// Then make sure that the cursor in the table:
+SelectionType eType2 = pWrtShell->GetSelectionType();
+// This was false (only SelectionType::Text)
+bool bCursorInTable = eType2 == (SelectionType::Text | 
SelectionType::Table);
+CPPUNIT_ASSERT(bCursorInTable);
+
+// select the text frame by pressing Escape again
+dispatchCommand(mxComponent, ".uno:Escape", {});
+
+eType2 = pWrtShell->GetSelectionType();
+CPPUNIT_ASSERT_EQUAL(SelectionType::Frame, eType2);
+
+// deselect the text frame by pressing Escape again
+dispatchCommand(mxComponent, ".uno:Escape", {});
+
+eType2 = pWrtShell->GetSelectionType();
+// The text cursor is after the floating table
+CPPUNIT_ASSERT_EQUAL(SelectionType::Text, eType2);
+}
+
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf115132)
 {
 createSwDoc();
diff --git a/sw/source/core/frmedt/feshview.cxx 
b/sw/source/core/frmedt/feshview.cxx
index c10a87110d8e..9a8d7304b4cc 100644
--- a/sw/source/core/frmedt/feshview.cxx
+++ b/sw/source/core/frmedt/feshview.cxx
@@ -191,6 +191,7 @@ bool SwFEShell::SelectObj( const Point& rPt, sal_uInt8 
nFlag, SdrObject *pObj )
 ( 
pOldSelFly->GetFormat()->GetProtect().IsContentProtected()
  && !IsReadOnlyAvailable() ))
 {
+SdrObject *pOldObj = 
rMrkList.GetMark(0)->GetMarkedSdrObj();
 // If a fly is deselected, which contains graphic, OLE or
 // otherwise, the cursor should be removed from it.
 // Similar if a fly with protected content is deselected.
@@ -201,6 +202,29 @@ bool SwFEShell::SelectObj( const Point& rPt, sal_uInt8 
nFlag, SdrObject *pObj )
 bool bUnLockView = !IsViewLocked();
 LockView( true );
 SetCursor( aPt, true );
+

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 Justin Luth (via logerrit)
 sw/qa/extras/ooxmlexport/ooxmlexport21.cxx |   11 +++
 sw/source/core/doc/number.cxx  |5 -
 sw/source/filter/ww8/wrtw8num.cxx  |   11 ++-
 3 files changed, 25 insertions(+), 2 deletions(-)

New commits:
commit 71c49057deb1a696e4b0ce9d2091aaa28572b57a
Author: Justin Luth 
AuthorDate: Mon May 20 14:28:59 2024 -0400
Commit: Justin Luth 
CommitDate: Fri May 31 15:27:14 2024 +0200

tdf#149258 sw ms export: no separator for NONE numbering level

This is to benefit ODT->DOCX.

LO does not show the separators specified after a numbering level
that has no numbering type (since LO 7.2.5).
However, MSO does show any specified separators.
So export this the way that LO sees it.

Note that in the very odd case where an MSO user actually wanted
these separators to be visible, LO fails to show them,
and thus this will end up exporting as "data loss". How sad.

make CppunitTest_sw_ooxmlexport21 \
CPPUNIT_TEST_NAME=testTdf156105_percentSuffix

Change-Id: I2c084de319ef4b1e77b6f377708c71a62dcc5910
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167898
Tested-by: Jenkins
Reviewed-by: Justin Luth 

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
index baeba733afcc..e487bbf00015 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
@@ -298,6 +298,17 @@ DECLARE_OOXMLEXPORT_TEST(testTdf156105_percentSuffix, 
"tdf156105_percentSuffix.o
 // given a numbered list with a non-escaping percent symbol in the prefix 
and suffix
 CPPUNIT_ASSERT_EQUAL(OUString("(%)[%]"),
  getProperty(getParagraph(3), 
"ListLabelString"));
+
+// tdf#149258 - NONE number should not export separator since LO doesn't 
currently show it
+CPPUNIT_ASSERT_EQUAL_MESSAGE("showing levels 1, 2, and 4", 
OUString("(%)1.1.1[%]"),
+ getProperty(getParagraph(4), 
"ListLabelString"));
+if (isExported())
+{
+xmlDocUniquePtr pXmlNum = parseExport("word/numbering.xml");
+// The 3rd level is NONE. If we include the separator, MS Word will 
display it.
+assertXPath(pXmlNum, 
"/w:numbering/w:abstractNum[1]/w:lvl[4]/w:lvlText"_ostr, "val"_ostr,
+"(%)%1.%2.%3%4[%]");
+}
 }
 
 DECLARE_OOXMLEXPORT_TEST(testTdf160049_anchorMarginVML, 
"tdf160049_anchorMarginVML.docx")
diff --git a/sw/source/core/doc/number.cxx b/sw/source/core/doc/number.cxx
index f43ab140b60d..e811f7b83540 100644
--- a/sw/source/core/doc/number.cxx
+++ b/sw/source/core/doc/number.cxx
@@ -763,8 +763,11 @@ OUString SwNumRule::MakeNumString( const 
SwNumberTree::tNumberVector & rNumVecto
 // Numbering disabled - replacement is empty
 // And we should skip all level string content until next 
level marker:
 // so %1%.%2%.%3% with second level as NONE will result 1.1, 
not 1..1
+
+// NOTE: if changed, fix MSWordExportBase::NumberingLevel to 
match new behaviour.
+
 sal_Int32 nPositionNext = sLevelFormat.indexOf('%', nPosition 
+ sFind.getLength());
-if (nPosition >= 0 && nPositionNext >= nPosition)
+if (nPosition >= 0 && nPositionNext > nPosition)
 {
 sLevelFormat = sLevelFormat.replaceAt(nPosition, 
nPositionNext - nPosition, u"");
 }
diff --git a/sw/source/filter/ww8/wrtw8num.cxx 
b/sw/source/filter/ww8/wrtw8num.cxx
index 4c56472bb6b3..e8f7b197ed59 100644
--- a/sw/source/filter/ww8/wrtw8num.cxx
+++ b/sw/source/filter/ww8/wrtw8num.cxx
@@ -489,9 +489,18 @@ void MSWordExportBase::NumberingLevel(
 sal_Int32 nFnd = sNumStr.indexOf(sSrch);
 if (-1 != nFnd)
 {
+sal_Int32 nLen = sSrch.getLength();
+if (i < nLvl && rRule.Get(i).GetNumberingType() == 
SVX_NUM_NUMBER_NONE)
+{
+// LO doesn't show this level, so don't export its 
separator
+const OUString sSrch2("%" + OUString::number(i + 2) + 
"%");
+const sal_Int32 nFnd2 = sNumStr.indexOf(sSrch2, nFnd);
+if (-1 != nFnd2)
+nLen = nFnd2 - nFnd;
+}
 *pLvlPos = static_cast(nFnd + 1);
 ++pLvlPos;
-sNumStr = sNumStr.replaceAt(nFnd, sSrch.getLength(), 
rtl::OUStringChar(static_cast(i)));
+sNumStr = sNumStr.replaceAt(nFnd, nLen, 
OUStringChar(static_cast(i)));
 }
 }
 }


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

2024-05-29 Thread Justin Luth (via logerrit)
 sw/qa/extras/ooxmlexport/ooxmlexport21.cxx   |3 ---
 sw/source/filter/ww8/docxattributeoutput.cxx |4 
 2 files changed, 4 insertions(+), 3 deletions(-)

New commits:
commit a2b00082114b443962715a671b8bbb17733d6453
Author: Justin Luth 
AuthorDate: Mon May 27 20:31:54 2024 -0400
Commit: Justin Luth 
CommitDate: Thu May 30 01:21:48 2024 +0200

tdf#131098 docx export: write fill property of graphic

All these are round-tripping (at least at a basic level):
- bitmap
- hatch
- solid color
- transparency (unit test)

make CppunitTest_sw_ooxmlexport21 \
CPPUNIT_TEST_NAME=testTdf131098_imageFill

No existing unit tests had an image with a fill.

Change-Id: I745fa064db83bdb3bb7ec67eef1ae803f3930a23
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168134
Reviewed-by: Justin Luth 
Tested-by: Jenkins

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
index 901a0b161d6a..baeba733afcc 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
@@ -534,9 +534,6 @@ DECLARE_OOXMLEXPORT_TEST(testTdf126533_pageBitmap, 
"tdf126533_pageBitmap.docx")
 
 DECLARE_OOXMLEXPORT_TEST(testTdf131098_imageFill, "tdf131098_imageFill.docx")
 {
-if (isExported())
-return;
-
 // given a document with an image background transparency (blue-white)
 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT,
  getProperty(getShape(1), 
"FillStyle"));
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index 971f27df0314..827d037b274c 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -5411,6 +5411,10 @@ void DocxAttributeOutput::FlyFrameGraphic( const 
SwGrfNode* pGrfNode, const Size
 m_pSerializer->singleElementNS(XML_a, XML_avLst);
 m_pSerializer->endElementNS( XML_a, XML_prstGeom );
 
+m_rDrawingML.SetFS(m_pSerializer); // to be sure that we write to the 
right stream
+if (xShapePropSet)
+m_rDrawingML.WriteFill(xShapePropSet, awt::Size(aSize.Width(), 
aSize.Height()));
+
 const SvxBoxItem& rBoxItem = pFrameFormat->GetBox();
 const SvxBorderLine* pLeft = rBoxItem.GetLine(SvxBoxItemLine::LEFT);
 const SvxBorderLine* pRight = rBoxItem.GetLine(SvxBoxItemLine::RIGHT);


core.git: sw/qa sw/source

2024-05-29 Thread Justin Luth (via logerrit)
 sw/qa/extras/ooxmlexport/data/tdf131098_imageFill.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlexport21.cxx |   11 +++
 sw/source/writerfilter/dmapper/GraphicImport.cxx   |   52 -
 3 files changed, 61 insertions(+), 2 deletions(-)

New commits:
commit 2862f1989591f4666ed0f7b994c80a0d0fd8ae52
Author: Justin Luth 
AuthorDate: Mon May 27 16:48:04 2024 -0400
Commit: Justin Luth 
CommitDate: Thu May 30 01:20:18 2024 +0200

tdf#131098 oox import: apply fill properties to graphic

The fill properties picked up by oox import
were not being transferred to the final graphic.

For some reason, the shape didn't import at all
if I copied over the Fill*Name properties.

All these are importing (at least at a basic level):
- bitmap
- hatch
- solid color
- transparency (unit test)

make CppunitTest_sw_ooxmlexport21 \
CPPUNIT_TEST_NAME=testTdf131098_imageFill

Change-Id: Ia891db8059c33132a75bef2c4922205315b7ecaf
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168127
Reviewed-by: Justin Luth 
Tested-by: Jenkins

diff --git a/sw/qa/extras/ooxmlexport/data/tdf131098_imageFill.docx 
b/sw/qa/extras/ooxmlexport/data/tdf131098_imageFill.docx
new file mode 100644
index ..b663bdf72ac4
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf131098_imageFill.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
index 1c55be3df2cf..901a0b161d6a 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
@@ -532,6 +532,17 @@ DECLARE_OOXMLEXPORT_TEST(testTdf126533_pageBitmap, 
"tdf126533_pageBitmap.docx")
 
"/rels:Relationships/rels:Relationship[@Target='media/image1.jpeg']"_ostr, 1);
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf131098_imageFill, "tdf131098_imageFill.docx")
+{
+if (isExported())
+return;
+
+// given a document with an image background transparency (blue-white)
+CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT,
+ getProperty(getShape(1), 
"FillStyle"));
+CPPUNIT_ASSERT_EQUAL(Color(0x729fcf), getProperty(getShape(1), 
"FillColor"));
+}
+
 DECLARE_OOXMLEXPORT_TEST(testTdf154369, "tdf154369.docx")
 {
 //Unit test for bug fix in tdf#154369
diff --git a/sw/source/writerfilter/dmapper/GraphicImport.cxx 
b/sw/source/writerfilter/dmapper/GraphicImport.cxx
index b7621f776f4e..bab91d2b7fe0 100644
--- a/sw/source/writerfilter/dmapper/GraphicImport.cxx
+++ b/sw/source/writerfilter/dmapper/GraphicImport.cxx
@@ -1953,8 +1953,56 @@ rtl::Reference 
GraphicImport::createGraphicObject(uno::Ref
 uno::Any(m_pImpl->m_eColorMode));
 }
 
-xGraphicObject->setPropertyValue(getPropertyName( PROP_BACK_COLOR 
),
-uno::Any( GraphicImport_Impl::nFillColor ));
+// copy the image fill area properties
+xGraphicObject->setPropertyValue("FillBackground",
+ 
xShapeProps->getPropertyValue("FillBackground"));
+xGraphicObject->setPropertyValue("FillBitmap",
+ 
xShapeProps->getPropertyValue("FillBitmap"));
+xGraphicObject->setPropertyValue(
+"FillBitmapLogicalSize", 
xShapeProps->getPropertyValue("FillBitmapLogicalSize"));
+xGraphicObject->setPropertyValue("FillBitmapMode",
+ 
xShapeProps->getPropertyValue("FillBitmapMode"));
+xGraphicObject->setPropertyValue("FillBitmapOffsetX",
+ 
xShapeProps->getPropertyValue("FillBitmapOffsetX"));
+xGraphicObject->setPropertyValue(
+"FillBitmapPositionOffsetX",
+xShapeProps->getPropertyValue("FillBitmapPositionOffsetX"));
+xGraphicObject->setPropertyValue(
+"FillBitmapPositionOffsetY",
+xShapeProps->getPropertyValue("FillBitmapPositionOffsetY"));
+xGraphicObject->setPropertyValue(
+"FillBitmapRectanglePoint",
+xShapeProps->getPropertyValue("FillBitmapRectanglePoint"));
+xGraphicObject->setPropertyValue("FillBitmapSizeX",
+ 
xShapeProps->getPropertyValue("FillBitmapSizeX"));
+xGraphicObject->setPropertyValue("FillBitmapSizeY",
+ 
xShapeProps->getPropertyValue("FillBitmapSizeY"));
+xGraphicObject->setPropertyValue("FillBitmapStretch",
+ 
xShapeProps->getPropertyValue("FillBitmapStretch"));
+xGraphicObject->setPropertyValue("FillBitmapTile",
+ 
xShapeProps->getPropertyValue("FillBitmapTile"));
+

core.git: sw/qa sw/source

2024-05-29 Thread László Németh (via logerrit)
 sw/qa/extras/uiwriter/uiwriter6.cxx |   63 
 sw/source/core/layout/flylay.cxx|   38 ++---
 2 files changed, 96 insertions(+), 5 deletions(-)

New commits:
commit dece7d80c31c3c489859200bc93d9c948a535cbf
Author: László Németh 
AuthorDate: Tue May 21 13:20:24 2024 +0200
Commit: László Németh 
CommitDate: Wed May 29 23:43:47 2024 +0200

tdf#161261 sw: fix lost size of image resized in fixed-height cell

A fixed-height cell can contain a bigger image, which is cropped by
cell boundaries. It was not possible to resize this image with a simple 
drag & drop, because its size changed to the cell size immediately.
Now it's possible, like MSO does.

Follow-up to commit 30de13743f144aced83bc43d310592f82788c910
"tdf#160836 sw: resize rows at images cropped by row height".

Change-Id: I6b4e911432e784a96d393ee225ce69a1f2986d56
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168186
Tested-by: Jenkins
Reviewed-by: László Németh 
Tested-by: László Németh 

diff --git a/sw/qa/extras/uiwriter/uiwriter6.cxx 
b/sw/qa/extras/uiwriter/uiwriter6.cxx
index fb3ecb357bcd..6322120748da 100644
--- a/sw/qa/extras/uiwriter/uiwriter6.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter6.cxx
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -1559,6 +1560,68 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf160836)
 CPPUNIT_ASSERT_EQUAL(tools::Long(1980), pCellA1->getFrameArea().Height());
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf161261)
+{
+createSwDoc("tdf160842.fodt");
+SwDoc* pDoc = getSwDoc();
+CPPUNIT_ASSERT(pDoc);
+SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+CPPUNIT_ASSERT(pWrtShell);
+// the cursor is not in the table
+CPPUNIT_ASSERT(!pWrtShell->IsCursorInTable());
+
+SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+auto pPage = dynamic_cast(pLayout->Lower());
+CPPUNIT_ASSERT(pPage);
+const SwSortedObjs& rPageObjs = *pPage->GetSortedObjs();
+CPPUNIT_ASSERT_EQUAL(static_cast(1), rPageObjs.size());
+auto pPageFly = dynamic_cast(rPageObjs[0]);
+CPPUNIT_ASSERT(pPageFly);
+auto pTable = dynamic_cast(pPageFly->GetLower());
+CPPUNIT_ASSERT(pTable);
+auto pRow1 = pTable->GetLower();
+CPPUNIT_ASSERT(pRow1->IsRowFrame());
+auto pCellA1 = pRow1->GetLower();
+CPPUNIT_ASSERT(pCellA1);
+const SwRect& rCellA1Rect = pCellA1->getFrameArea();
+auto nRowHeight = rCellA1Rect.Height();
+
+// select image by clicking on it at the center of the upper cell
+Point ptFrom(rCellA1Rect.Left() + rCellA1Rect.Width() / 2, 
rCellA1Rect.Top() + nRowHeight / 2);
+vcl::Window& rEditWin = pDoc->GetDocShell()->GetView()->GetEditWin();
+Point aFrom = rEditWin.LogicToPixel(ptFrom);
+MouseEvent aClickEvent(aFrom, 1, MouseEventModifiers::SIMPLECLICK, 
MOUSE_LEFT);
+rEditWin.MouseButtonDown(aClickEvent);
+rEditWin.MouseButtonUp(aClickEvent);
+
+// Then make sure that the image is selected:
+SelectionType eType = pWrtShell->GetSelectionType();
+CPPUNIT_ASSERT_EQUAL(SelectionType::Graphic, eType);
+
+uno::Reference xShape = getShape(2);
+CPPUNIT_ASSERT(xShape.is());
+
+// zoom image by drag & drop using right bottom handle of the image
+const SwRect& rSelRect = pWrtShell->GetAnyCurRect(CurRectType::Frame);
+Point ptFromHandle(rSelRect.Right(), rSelRect.Bottom());
+Point aFromHandle = rEditWin.LogicToPixel(ptFromHandle);
+Point ptTo(rSelRect.Left() + rSelRect.Width() * 1.5, rSelRect.Top() + 
rSelRect.Height() * 1.5);
+Point aTo = rEditWin.LogicToPixel(ptTo);
+MouseEvent aClickEvent2(aFromHandle, 1, MouseEventModifiers::SIMPLECLICK, 
MOUSE_LEFT);
+rEditWin.MouseButtonDown(aClickEvent2);
+MouseEvent aClickEvent3(aTo, 0, MouseEventModifiers::SIMPLEMOVE, 
MOUSE_LEFT);
+rEditWin.MouseMove(aClickEvent3);
+rEditWin.MouseMove(aClickEvent3);
+MouseEvent aClickEvent4(aTo, 1, MouseEventModifiers::SIMPLECLICK, 
MOUSE_LEFT);
+rEditWin.MouseButtonUp(aClickEvent4);
+Scheduler::ProcessEventsToIdle();
+
+// Make sure image is greater than before, instead of minimizing it to the 
cell size
+// This was 8707 and 6509
+CPPUNIT_ASSERT_GREATER(sal_Int32(1), xShape->getSize().Width);
+CPPUNIT_ASSERT_GREATER(sal_Int32(8000), xShape->getSize().Height);
+}
+
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf115132)
 {
 createSwDoc();
diff --git a/sw/source/core/layout/flylay.cxx b/sw/source/core/layout/flylay.cxx
index 1a39b735d2d8..42ea0332f6eb 100644
--- a/sw/source/core/layout/flylay.cxx
+++ b/sw/source/core/layout/flylay.cxx
@@ -1409,17 +1409,45 @@ bool CalcClipRect( const SdrObject *pSdrObj, SwRect 
, bool bMove )
 {
 const SwFrame *pUp = pFly->GetAnchorFrame()->GetUpper();
 SwRectFnSet aRectFnSet(pFly->GetAnchorFrame());
+bool 

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

2024-05-29 Thread Mike Kaganski (via logerrit)
 sw/qa/extras/layout/layout2.cxx   |5 ++---
 sw/qa/extras/ooxmlexport/ooxmlexport5.cxx |6 ++
 sw/source/core/inc/frame.hxx  |1 +
 sw/source/core/layout/calcmove.cxx|6 ++
 sw/source/core/layout/flowfrm.cxx |9 +
 sw/source/core/layout/sectfrm.cxx |2 +-
 sw/source/core/layout/tabfrm.cxx  |   13 +
 sw/source/core/layout/trvlfrm.cxx |   16 
 8 files changed, 54 insertions(+), 4 deletions(-)

New commits:
commit fc1e6a64bd0517a7e67f08860c29b44d030220eb
Author: Mike Kaganski 
AuthorDate: Tue May 28 09:04:51 2024 +0500
Commit: Mike Kaganski 
CommitDate: Wed May 29 13:17:30 2024 +0200

tdf#161202: lowers shouldn't move forward because of lack of space

... in hidden section. So make sure to set heights of lowers to zero, too.
testOldComplexMergeTableInTable turned out to be a nice test for this.

Change-Id: I334aaaf2becf0ac1ff61faed2e5f697f344c78d4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168151
Tested-by: Jenkins
Reviewed-by: Mike Kaganski 

diff --git a/sw/qa/extras/layout/layout2.cxx b/sw/qa/extras/layout/layout2.cxx
index 56c6991fce5e..dc81b5e2296e 100644
--- a/sw/qa/extras/layout/layout2.cxx
+++ b/sw/qa/extras/layout/layout2.cxx
@@ -858,7 +858,7 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf152872)
 assertXPath(pXmlDoc, "/root/page[1]/body/txt"_ostr, 2);
 assertXPath(pXmlDoc, 
"/root/page/body/txt[1]/SwParaPortion/SwLineLayout"_ostr, "portion"_ostr,
 "C DE");
-assertXPath(pXmlDoc, "/root/page/body/txt[2]/SwParaPortion"_ostr, 0); // 5 
is empty and hidden
+// 5 is empty and hidden
 assertXPath(pXmlDoc, "/root/page/body/txt[2]/infos/bounds"_ostr, 
"height"_ostr, "0");
 
 dispatchCommand(mxComponent, ".uno:ControlCodes", {});
@@ -880,7 +880,6 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf152872)
 // 5 is an empty paragraph with RES_CHRATR_HIDDEN which results in 0-height
 // frame; ideally it should only be hidden when control codes are hidden
 // and be a full-height frame now, but that needs more work...
-assertXPath(pXmlDoc, "/root/page/body/txt[5]/SwParaPortion"_ostr, 0); // 5 
is empty
 assertXPath(pXmlDoc, "/root/page/body/txt[5]/infos/bounds"_ostr, 
"height"_ostr, "0");
 
 dispatchCommand(mxComponent, ".uno:ControlCodes", {});
@@ -891,7 +890,7 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf152872)
 assertXPath(pXmlDoc, "/root/page[1]/body/txt"_ostr, 2);
 assertXPath(pXmlDoc, 
"/root/page/body/txt[1]/SwParaPortion/SwLineLayout"_ostr, "portion"_ostr,
 "C DE");
-assertXPath(pXmlDoc, "/root/page/body/txt[2]/SwParaPortion"_ostr, 0); // 5 
is empty and hidden
+// 5 is empty and hidden
 assertXPath(pXmlDoc, "/root/page/body/txt[2]/infos/bounds"_ostr, 
"height"_ostr, "0");
 }
 
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
index db504be317c1..4a2ac4bbbfd2 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
@@ -319,6 +319,12 @@ CPPUNIT_TEST_FIXTURE(Test, testOldComplexMergeTableInTable)
 {
 loadAndSave("ooo96040-2.odt");
 parseExport("word/document.xml");
+
+// Check tdf#161202 - this document has all kinds of tables inside hidden 
sections.
+// The page count must be 13, but for unclear reason, it is 12 in some 
tests on Linux
+// (maybe the layout hasn't finished?).
+// Without the fix, it was 52.
+CPPUNIT_ASSERT_LESSEQUAL(13, getPages());
 }
 
 CPPUNIT_TEST_FIXTURE(Test, testHyperlinkContainingPlaceholderField)
diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx
index 4f0df45e2d30..9972248e9744 100644
--- a/sw/source/core/inc/frame.hxx
+++ b/sw/source/core/inc/frame.hxx
@@ -903,6 +903,7 @@ public:
 bool IsProtected() const;
 
 virtual bool IsHiddenNow() const;
+void MakeValidZeroHeight();
 
 bool IsColLocked()  const { return mbColLocked; }
 virtual bool IsDeleteForbidden() const { return mnForbidDelete > 0; }
diff --git a/sw/source/core/layout/calcmove.cxx 
b/sw/source/core/layout/calcmove.cxx
index 6e8112308002..dbd6ffe88b91 100644
--- a/sw/source/core/layout/calcmove.cxx
+++ b/sw/source/core/layout/calcmove.cxx
@@ -965,6 +965,9 @@ void SwLayoutFrame::MakeAll(vcl::RenderContext* 
/*pRenderContext*/)
 const SwLayNotify aNotify( this );
 bool bVert = IsVertical();
 
+if (IsHiddenNow())
+MakeValidZeroHeight();
+
 SwRectFn fnRect = ( IsNeighbourFrame() == bVert )? fnRectHori : ( 
IsVertLR() ? (IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert );
 
 std::optional oAccess;
@@ -1281,6 +1284,9 @@ void SwContentFrame::MakeAll(vcl::RenderContext* 
/*pRenderContext*/)
 return;
 }
 
+if (IsHiddenNow())
+MakeValidZeroHeight();
+
 std::optional oDeleteGuard(std::in_place, this);
 LockJoin();
 

core.git: sw/qa sw/source

2024-05-29 Thread Stephan Bergmann (via logerrit)
 sw/qa/extras/uiwriter/uiwriter6.cxx |   63 
 sw/source/core/layout/flylay.cxx|   38 ++---
 2 files changed, 5 insertions(+), 96 deletions(-)

New commits:
commit db94d1079a83eae9ac0c8d92f4547698d016daf8
Author: Stephan Bergmann 
AuthorDate: Mon May 27 10:57:41 2024 +0200
Commit: Stephan Bergmann 
CommitDate: Wed May 29 10:38:41 2024 +0200

Revert "tdf#161261 sw: fix lost size of image resized in fixed-height cell"

This reverts commit 4da6f52f5fd164082fd42fc58fc7d31da567c924 plus follow-up
24f65bf5940adb0aa3590443752110119e2bea5e "Fix typo".  It caused
CppunitTest_sw_uiwriter6 to fail with

> /sw/source/core/layout/flylay.cxx:1426:51: runtime error: downcast of 
address 0x606000c4b620 which does not point to an object of type 'const 
SwDrawContact'
> 0x606000c4b620: note: object is of type 'SwFlyDrawContact'
>  00 00 00 00  50 3d 2f b8 99 7f 00 00  c0 3d 2f b8 99 7f 00 00  00 00 00 
00 00 00 00 00  d0 64 50 00
>   ^~~
>   vptr for 'SwFlyDrawContact'
> #0 0x7f99ae257936 in CalcClipRect(SdrObject const*, SwRect&, bool) 
/sw/source/core/layout/flylay.cxx:1426:51
> #1 0x7f99ad5b2607 in SwDrawView::TakeDragLimit(SdrDragMode, 
tools::Rectangle&) const /sw/source/core/draw/dview.cxx:694:13
> #2 0x7f99c317c1a0 in SdrDragView::BegDragObj(Point const&, 
OutputDevice*, SdrHdl*, short, SdrDragMethod*) 
/svx/source/svdraw/svddrgv.cxx:199:21
> #3 0x7f99c18eef25 in E3dView::BegDragObj(Point const&, OutputDevice*, 
SdrHdl*, short, SdrDragMethod*) /svx/source/engine3d/view3d.cxx:1243:21
> #4 0x7f99adcfa821 in SwFEShell::BeginDrag(Point const*, bool) 
/sw/source/core/frmedt/feshview.cxx:741:20
> #5 0x7f99b3ea5ffd in SwWrtShell::BeginFrameDrag(Point const*, bool) 
/sw/source/uibase/wrtsh/select.cxx:761:20
> #6 0x7f99b27a8238 in SwWrtShell::Drag(Point const*, bool) 
/sw/source/uibase/inc/wrtsh.hxx:124:56
> #7 0x7f99b2742135 in SwEditWin::MouseMove(MouseEvent const&) 
/sw/source/uibase/docvw/edtwin.cxx:4489:25
> #8 0x7f99dcdc6f64 in testTdf161261::TestBody() 
/sw/qa/extras/uiwriter/uiwriter6.cxx:1613:14

()

Change-Id: Idf0c0c75d39a28671c852fc526549439892d0902
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168177
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann 

diff --git a/sw/qa/extras/uiwriter/uiwriter6.cxx 
b/sw/qa/extras/uiwriter/uiwriter6.cxx
index 6322120748da..fb3ecb357bcd 100644
--- a/sw/qa/extras/uiwriter/uiwriter6.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter6.cxx
@@ -36,7 +36,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 
 #include 
@@ -1560,68 +1559,6 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf160836)
 CPPUNIT_ASSERT_EQUAL(tools::Long(1980), pCellA1->getFrameArea().Height());
 }
 
-CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf161261)
-{
-createSwDoc("tdf160842.fodt");
-SwDoc* pDoc = getSwDoc();
-CPPUNIT_ASSERT(pDoc);
-SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
-CPPUNIT_ASSERT(pWrtShell);
-// the cursor is not in the table
-CPPUNIT_ASSERT(!pWrtShell->IsCursorInTable());
-
-SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
-auto pPage = dynamic_cast(pLayout->Lower());
-CPPUNIT_ASSERT(pPage);
-const SwSortedObjs& rPageObjs = *pPage->GetSortedObjs();
-CPPUNIT_ASSERT_EQUAL(static_cast(1), rPageObjs.size());
-auto pPageFly = dynamic_cast(rPageObjs[0]);
-CPPUNIT_ASSERT(pPageFly);
-auto pTable = dynamic_cast(pPageFly->GetLower());
-CPPUNIT_ASSERT(pTable);
-auto pRow1 = pTable->GetLower();
-CPPUNIT_ASSERT(pRow1->IsRowFrame());
-auto pCellA1 = pRow1->GetLower();
-CPPUNIT_ASSERT(pCellA1);
-const SwRect& rCellA1Rect = pCellA1->getFrameArea();
-auto nRowHeight = rCellA1Rect.Height();
-
-// select image by clicking on it at the center of the upper cell
-Point ptFrom(rCellA1Rect.Left() + rCellA1Rect.Width() / 2, 
rCellA1Rect.Top() + nRowHeight / 2);
-vcl::Window& rEditWin = pDoc->GetDocShell()->GetView()->GetEditWin();
-Point aFrom = rEditWin.LogicToPixel(ptFrom);
-MouseEvent aClickEvent(aFrom, 1, MouseEventModifiers::SIMPLECLICK, 
MOUSE_LEFT);
-rEditWin.MouseButtonDown(aClickEvent);
-rEditWin.MouseButtonUp(aClickEvent);
-
-// Then make sure that the image is selected:
-SelectionType eType = pWrtShell->GetSelectionType();
-CPPUNIT_ASSERT_EQUAL(SelectionType::Graphic, eType);
-
-uno::Reference xShape = getShape(2);
-CPPUNIT_ASSERT(xShape.is());
-
-// zoom image by drag & drop using right bottom handle of the image
-const SwRect& rSelRect = pWrtShell->GetAnyCurRect(CurRectType::Frame);
-Point ptFromHandle(rSelRect.Right(), rSelRect.Bottom());
-Point aFromHandle = rEditWin.LogicToPixel(ptFromHandle);
-Point 

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

2024-05-24 Thread László Németh (via logerrit)
 sw/qa/extras/uiwriter/uiwriter6.cxx |   63 
 sw/source/core/layout/flylay.cxx|   38 ++---
 2 files changed, 96 insertions(+), 5 deletions(-)

New commits:
commit 4da6f52f5fd164082fd42fc58fc7d31da567c924
Author: László Németh 
AuthorDate: Tue May 21 13:20:24 2024 +0200
Commit: László Németh 
CommitDate: Fri May 24 19:46:46 2024 +0200

tdf#161261 sw: fix lost size of image resized in fixed-height cell

A fixed-height cell can contain a bigger image, which is cropped by
cell boundaries. It was not possible to resize this image with a simple 
drag & drop, because its size changed to the cell size immediately.
Now it's possible, like MSO does.

Follow-up to commit 30de13743f144aced83bc43d310592f82788c910
"tdf#160836 sw: resize rows at images cropped by row height".

Change-Id: I9d63e6e526135b6d8541f904c363b9186bb3cfc4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168023
Tested-by: Jenkins
Reviewed-by: László Németh 

diff --git a/sw/qa/extras/uiwriter/uiwriter6.cxx 
b/sw/qa/extras/uiwriter/uiwriter6.cxx
index fb3ecb357bcd..6322120748da 100644
--- a/sw/qa/extras/uiwriter/uiwriter6.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter6.cxx
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -1559,6 +1560,68 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf160836)
 CPPUNIT_ASSERT_EQUAL(tools::Long(1980), pCellA1->getFrameArea().Height());
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf161261)
+{
+createSwDoc("tdf160842.fodt");
+SwDoc* pDoc = getSwDoc();
+CPPUNIT_ASSERT(pDoc);
+SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+CPPUNIT_ASSERT(pWrtShell);
+// the cursor is not in the table
+CPPUNIT_ASSERT(!pWrtShell->IsCursorInTable());
+
+SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+auto pPage = dynamic_cast(pLayout->Lower());
+CPPUNIT_ASSERT(pPage);
+const SwSortedObjs& rPageObjs = *pPage->GetSortedObjs();
+CPPUNIT_ASSERT_EQUAL(static_cast(1), rPageObjs.size());
+auto pPageFly = dynamic_cast(rPageObjs[0]);
+CPPUNIT_ASSERT(pPageFly);
+auto pTable = dynamic_cast(pPageFly->GetLower());
+CPPUNIT_ASSERT(pTable);
+auto pRow1 = pTable->GetLower();
+CPPUNIT_ASSERT(pRow1->IsRowFrame());
+auto pCellA1 = pRow1->GetLower();
+CPPUNIT_ASSERT(pCellA1);
+const SwRect& rCellA1Rect = pCellA1->getFrameArea();
+auto nRowHeight = rCellA1Rect.Height();
+
+// select image by clicking on it at the center of the upper cell
+Point ptFrom(rCellA1Rect.Left() + rCellA1Rect.Width() / 2, 
rCellA1Rect.Top() + nRowHeight / 2);
+vcl::Window& rEditWin = pDoc->GetDocShell()->GetView()->GetEditWin();
+Point aFrom = rEditWin.LogicToPixel(ptFrom);
+MouseEvent aClickEvent(aFrom, 1, MouseEventModifiers::SIMPLECLICK, 
MOUSE_LEFT);
+rEditWin.MouseButtonDown(aClickEvent);
+rEditWin.MouseButtonUp(aClickEvent);
+
+// Then make sure that the image is selected:
+SelectionType eType = pWrtShell->GetSelectionType();
+CPPUNIT_ASSERT_EQUAL(SelectionType::Graphic, eType);
+
+uno::Reference xShape = getShape(2);
+CPPUNIT_ASSERT(xShape.is());
+
+// zoom image by drag & drop using right bottom handle of the image
+const SwRect& rSelRect = pWrtShell->GetAnyCurRect(CurRectType::Frame);
+Point ptFromHandle(rSelRect.Right(), rSelRect.Bottom());
+Point aFromHandle = rEditWin.LogicToPixel(ptFromHandle);
+Point ptTo(rSelRect.Left() + rSelRect.Width() * 1.5, rSelRect.Top() + 
rSelRect.Height() * 1.5);
+Point aTo = rEditWin.LogicToPixel(ptTo);
+MouseEvent aClickEvent2(aFromHandle, 1, MouseEventModifiers::SIMPLECLICK, 
MOUSE_LEFT);
+rEditWin.MouseButtonDown(aClickEvent2);
+MouseEvent aClickEvent3(aTo, 0, MouseEventModifiers::SIMPLEMOVE, 
MOUSE_LEFT);
+rEditWin.MouseMove(aClickEvent3);
+rEditWin.MouseMove(aClickEvent3);
+MouseEvent aClickEvent4(aTo, 1, MouseEventModifiers::SIMPLECLICK, 
MOUSE_LEFT);
+rEditWin.MouseButtonUp(aClickEvent4);
+Scheduler::ProcessEventsToIdle();
+
+// Make sure image is greater than before, instead of minimizing it to the 
cell size
+// This was 8707 and 6509
+CPPUNIT_ASSERT_GREATER(sal_Int32(1), xShape->getSize().Width);
+CPPUNIT_ASSERT_GREATER(sal_Int32(8000), xShape->getSize().Height);
+}
+
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf115132)
 {
 createSwDoc();
diff --git a/sw/source/core/layout/flylay.cxx b/sw/source/core/layout/flylay.cxx
index 1a39b735d2d8..92ad07ba4481 100644
--- a/sw/source/core/layout/flylay.cxx
+++ b/sw/source/core/layout/flylay.cxx
@@ -1409,17 +1409,45 @@ bool CalcClipRect( const SdrObject *pSdrObj, SwRect 
, bool bMove )
 {
 const SwFrame *pUp = pFly->GetAnchorFrame()->GetUpper();
 SwRectFnSet aRectFnSet(pFly->GetAnchorFrame());
+bool bOnlyCellFrame = pUp->IsCellFrame();

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

2024-05-21 Thread Tibor Nagy (via logerrit)
 sw/qa/uitest/writer_tests2/formatBulletsNumbering.py |7 +++
 sw/source/core/doc/docnum.cxx|5 -
 2 files changed, 11 insertions(+), 1 deletion(-)

New commits:
commit 708d619e32f251f06af8e8a057bf802627b81fbd
Author: Tibor Nagy 
AuthorDate: Sat May 18 23:31:56 2024 +0200
Commit: Nagy Tibor 
CommitDate: Tue May 21 11:00:04 2024 +0200

fix crash when push the Bullets button on the toolbar and then press the

dropdown part of the button

caused by commit I40cfc39501006146f7c6c04a1f3c7cf877c6f1c4
(tdf#161056 Show bullets used in document in bullets dropdown)

Change-Id: I215d7cb677825821917a4fd8c498deaaab9fc9b8
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167838
Tested-by: Jenkins
Reviewed-by: Nagy Tibor 

diff --git a/sw/qa/uitest/writer_tests2/formatBulletsNumbering.py 
b/sw/qa/uitest/writer_tests2/formatBulletsNumbering.py
index b3c5484964d4..abf090f7d16e 100644
--- a/sw/qa/uitest/writer_tests2/formatBulletsNumbering.py
+++ b/sw/qa/uitest/writer_tests2/formatBulletsNumbering.py
@@ -259,4 +259,11 @@ class formatBulletsNumbering(UITestCase):
 
self.assertEqual(get_state_as_dict(xselector)["SelectedItemId"], "73")
 
 
+   def test_bullets_and_numbering_document_bullet_list(self):
+with self.ui_test.create_doc_in_start_center("writer"):
+self.xUITest.executeCommand(".uno:DefaultBullet")
+# Without the fix in place, this test would have crashed here
+self.xUITest.executeCommand(".uno:DocumentBulletList")
+
+
 # vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/sw/source/core/doc/docnum.cxx b/sw/source/core/doc/docnum.cxx
index adf0f5b9f699..c4afeac7c50f 100644
--- a/sw/source/core/doc/docnum.cxx
+++ b/sw/source/core/doc/docnum.cxx
@@ -2534,8 +2534,11 @@ std::vector SwDoc::GetUsedBullets()
 for (int nLevel=0; nLevel<10; ++nLevel)
 {
 const SwNumFormat& rFormat = (*mpNumRuleTable)[nRule]->Get(nLevel);
-if (SVX_NUM_CHAR_SPECIAL != rFormat.GetNumberingType())
+if (SVX_NUM_CHAR_SPECIAL != rFormat.GetNumberingType()
+|| !rFormat.GetBulletFont().has_value())
+{
 continue;
+}
 vcl::Font aFont(*rFormat.GetBulletFont());
 sal_UCS4 cBullet = rFormat.GetBulletChar();
 OUString sBullet(, 1);


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

2024-05-21 Thread Jaume Pujantell (via logerrit)
 sw/qa/writerfilter/cppunittests/ooxml/data/recursive_header_rels.docx |binary
 sw/qa/writerfilter/cppunittests/ooxml/ooxml.cxx   |7 
+++
 sw/source/writerfilter/ooxml/OOXMLDocumentImpl.cxx|3 
++-
 sw/source/writerfilter/ooxml/OOXMLDocumentImpl.hxx|2 ++
 4 files changed, 11 insertions(+), 1 deletion(-)

New commits:
commit e39c57022afbe84601f58ef5bae0f12e69d33fc5
Author: Jaume Pujantell 
AuthorDate: Fri May 17 16:44:12 2024 +0200
Commit: Miklos Vajna 
CommitDate: Tue May 21 08:33:10 2024 +0200

writerfilter: avoid infinit loop when resolving embeddings on docx

If a docx file contains a loop on the .rels files for headers and/or footers
the code would enter an infinite recursion while looking for embeddings.

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

diff --git 
a/sw/qa/writerfilter/cppunittests/ooxml/data/recursive_header_rels.docx 
b/sw/qa/writerfilter/cppunittests/ooxml/data/recursive_header_rels.docx
new file mode 100644
index ..8000760017ed
Binary files /dev/null and 
b/sw/qa/writerfilter/cppunittests/ooxml/data/recursive_header_rels.docx differ
diff --git a/sw/qa/writerfilter/cppunittests/ooxml/ooxml.cxx 
b/sw/qa/writerfilter/cppunittests/ooxml/ooxml.cxx
index c146560ed352..5cbd9e219449 100644
--- a/sw/qa/writerfilter/cppunittests/ooxml/ooxml.cxx
+++ b/sw/qa/writerfilter/cppunittests/ooxml/ooxml.cxx
@@ -62,6 +62,13 @@ CPPUNIT_TEST_FIXTURE(Test, testFloatingTableLeak)
 CPPUNIT_ASSERT(xParagraph->supportsService("com.sun.star.text.Paragraph"));
 CPPUNIT_ASSERT(!xParaEnum->hasMoreElements());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testRecursiveHeaderRels)
+{
+// Given a document with self-referencing rels in a header/footer:
+loadFromFile(u"recursive_header_rels.docx");
+// It should not crash/hang on load
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/writerfilter/ooxml/OOXMLDocumentImpl.cxx 
b/sw/source/writerfilter/ooxml/OOXMLDocumentImpl.cxx
index 0530969fbccc..0fdf1b927956 100644
--- a/sw/source/writerfilter/ooxml/OOXMLDocumentImpl.cxx
+++ b/sw/source/writerfilter/ooxml/OOXMLDocumentImpl.cxx
@@ -762,8 +762,9 @@ void OOXMLDocumentImpl::resolveEmbeddingsStream(const 
OOXMLStream::Pointer_t& pS
 {
 importSubStreamRelations(pStream, OOXMLStream::CHARTS);
 }
-if(bHeaderFooterFound)
+if (bHeaderFooterFound && 
!maSeenStreams.contains(customTarget))
 {
+maSeenStreams.insert(customTarget);
 try
 {
 OOXMLStream::Pointer_t Stream = 
OOXMLDocumentFactory::createStream(pStream, streamType);
diff --git a/sw/source/writerfilter/ooxml/OOXMLDocumentImpl.hxx 
b/sw/source/writerfilter/ooxml/OOXMLDocumentImpl.hxx
index 87aae13ab94f..ee8a01972f93 100644
--- a/sw/source/writerfilter/ooxml/OOXMLDocumentImpl.hxx
+++ b/sw/source/writerfilter/ooxml/OOXMLDocumentImpl.hxx
@@ -30,6 +30,7 @@
 
 #include 
 #include 
+#include 
 
 namespace writerfilter::ooxml
 {
@@ -55,6 +56,7 @@ class OOXMLDocumentImpl : public OOXMLDocument
 css::uno::Reference mxEmbeddings;
 css::uno::Sequence < css::beans::PropertyValue > mxEmbeddingsList;
 std::vector m_aEmbeddings;
+std::set maSeenStreams;
 bool mbIsSubstream;
 bool mbSkipImages;
 /// How many paragraphs equal to 1 percent?


core.git: sw/qa sw/source

2024-05-20 Thread Justin Luth (via logerrit)
 sw/qa/extras/ooxmlexport/data/tdf156105_percentSuffix.odt |binary
 sw/qa/extras/ooxmlexport/ooxmlexport21.cxx|7 ++
 sw/source/core/doc/number.cxx |   33 +++---
 3 files changed, 15 insertions(+), 25 deletions(-)

New commits:
commit 65e226aff6a946ae4884b9f5afdccaa1c745bcd4
Author: Justin Luth 
AuthorDate: Fri May 17 12:17:26 2024 -0400
Commit: Justin Luth 
CommitDate: Mon May 20 15:40:38 2024 +0200

tdf#156105 sw: trust SvxNumberFormat GetPrefix/GetSuffix

After LO 7.4 (backported to 7.2.5) created this
function that manually identifies the Prefix/Suffix,
there was some work done to ensure
GetPrefix and GetSuffix were trustworthy in
LO 7.5's commit 835cda561217bd8c53af2de927158dd5712b06c0
Author: Justin Luth on Tue Aug 2 13:30:31 2022 -0400
related tdf#150197: use SetListFormat or SetPrefix/Suffix
GetListFormat DEPENDS on having managed prefix/suffix itself...

So, lets make sure we use and fix these functions in only one place.

make CppunitTest_sw_ooxmlexport21 \
CPPUNIT_TEST_NAME=testTdf156105_percentSuffix

Change-Id: I44c021a200ba45960e39983087c6af268751fbc1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167792
Reviewed-by: Justin Luth 
Reviewed-by: Vasily Melenchuk 
Tested-by: Jenkins

diff --git a/sw/qa/extras/ooxmlexport/data/tdf156105_percentSuffix.odt 
b/sw/qa/extras/ooxmlexport/data/tdf156105_percentSuffix.odt
new file mode 100644
index ..a5319f7a9522
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf156105_percentSuffix.odt differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
index 01c42d0ea34d..6cfbe8d783fc 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
@@ -293,6 +293,13 @@ DECLARE_OOXMLEXPORT_TEST(testTdf158597, "tdf158597.docx")
 }
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf156105_percentSuffix, 
"tdf156105_percentSuffix.odt")
+{
+// given a numbered list with a non-escaping percent symbol in the prefix 
and suffix
+CPPUNIT_ASSERT_EQUAL(OUString("(%)[%]"),
+ getProperty(getParagraph(3), 
"ListLabelString"));
+}
+
 DECLARE_OOXMLEXPORT_TEST(testTdf160049_anchorMarginVML, 
"tdf160049_anchorMarginVML.docx")
 {
 // given a VML (Word 2003) document with a LEFT "column/text" anchored 
image
diff --git a/sw/source/core/doc/number.cxx b/sw/source/core/doc/number.cxx
index c92d2af29a7d..f43ab140b60d 100644
--- a/sw/source/core/doc/number.cxx
+++ b/sw/source/core/doc/number.cxx
@@ -721,32 +721,15 @@ OUString SwNumRule::MakeNumString( const 
SwNumberTree::tNumberVector & rNumVecto
 
 if (rMyNFormat.GetNumberingType() == SVX_NUM_NUMBER_NONE)
 {
-if (!rMyNFormat.HasListFormat()) {
-OUString sRet = bInclStrings ? rMyNFormat.GetPrefix() + 
rMyNFormat.GetSuffix() : OUString();
-StripNonDelimiter(sRet);
-return sRet;
-}
-
-// If numbering is disabled for this level we should emit just 
prefix/suffix
-// Remove everything between first %1% and last %n% (including markers)
-OUString sLevelFormat = rMyNFormat.GetListFormat(bInclStrings && 
!bHideNonNumerical);
-
-if (bInclStrings && bHideNonNumerical) {
-// If hiding non numerical text, we need to strip the prefix and 
suffix properly, so let's add them manually
-OUString sPrefix = rMyNFormat.GetPrefix();
-OUString sSuffix = rMyNFormat.GetSuffix();
+// since numbering is disabled for this level,
+// only emit prefix/suffix (unless they are not wanted either)
+if (!bInclStrings)
+return OUString();
 
-StripNonDelimiter(sPrefix);
-StripNonDelimiter(sSuffix);
-
-sLevelFormat = sPrefix + sLevelFormat + sSuffix;
-}
-
-sal_Int32 nFirstPosition = sLevelFormat.indexOf("%");
-sal_Int32 nLastPosition = sLevelFormat.lastIndexOf("%");
-if (nFirstPosition >= 0 && nLastPosition >= nFirstPosition)
-sLevelFormat = sLevelFormat.replaceAt(nFirstPosition, 
nLastPosition - nFirstPosition + 1, u"");
-return sLevelFormat;
+OUString sRet = rMyNFormat.GetPrefix() + rMyNFormat.GetSuffix();
+if (bHideNonNumerical)
+StripNonDelimiter(sRet);
+return sRet;
 }
 
 css::lang::Locale aLocale( LanguageTag::convertToLocale(nLang));


core.git: sw/qa sw/source

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

New commits:
commit bb5740bb4c79c6c9507d4dc127e9f4bac78afc2f
Author: Mike Kaganski 
AuthorDate: Sun May 19 13:40:49 2024 +0500
Commit: Mike Kaganski 
CommitDate: Sun May 19 12:36:09 2024 +0200

tdf#161172: Also record history for !bChangeOfListStyleAtParagraph

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

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


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

2024-05-16 Thread László Németh (via logerrit)
 sw/qa/extras/odfexport/data/tdf160518_auto_in_default_paragraph_style.fodt   | 
  42 
 sw/qa/extras/odfexport/data/tdf160518_auto_in_text_body_style.fodt   | 
  42 
 sw/qa/extras/odfexport/data/tdf160518_page_in_default_paragraph_style.fodt   | 
  42 
 sw/qa/extras/odfexport/data/tdf160518_page_in_text_body_style.fodt   | 
  42 
 sw/qa/extras/odfexport/odfexport2.cxx| 
  48 +-
 sw/qa/extras/ooxmlexport/data/tdf160518_auto_in_default_paragraph_style.fodt | 
  42 
 sw/qa/extras/ooxmlexport/data/tdf160518_auto_in_text_body_style.fodt | 
  42 
 sw/qa/extras/ooxmlexport/data/tdf160518_page_in_default_paragraph_style.fodt | 
  42 
 sw/qa/extras/ooxmlexport/data/tdf160518_page_in_text_body_style.fodt | 
  42 
 sw/qa/extras/ooxmlexport/ooxmlexport14.cxx   | 
  48 +++---
 sw/source/filter/ww8/docxexport.cxx  | 
  26 +
 sw/source/writerfilter/dmapper/DomainMapper.cxx  | 
  10 ++
 sw/source/writerfilter/dmapper/SettingsTable.cxx | 
  31 +-
 sw/source/writerfilter/dmapper/SettingsTable.hxx | 
   1 
 14 files changed, 479 insertions(+), 21 deletions(-)

New commits:
commit b538729c90af470c33aeb3002750321ac8ac88be
Author: László Németh 
AuthorDate: Thu May 16 14:45:43 2024 +0200
Commit: László Németh 
CommitDate: Fri May 17 01:49:36 2024 +0200

tdf#160518 sw: fix DOCX import/export of hyphenation-keep

– export hyphenation-page="page" setting of native ODF documents,
  if hyphenation is enabled in the default paragraph or in
  the text body style with this setting. It's lossless for
  hyphenation-keep-type="column", while the other values are
  converted to hyphenation-keep-type="column", which is
  the default layout of MSO 2013 and later.

– fix LO roundtrip of DOCX documents which were created in MSO
  originally: while the roundtrip kept useWord2013TrackBottomHyphenation
  and allowHyphenationAtTrackBottom, the exported redundant
  suppressAutoHyphen = "false" settings of the paragraph
  resulted broken layout in Writer, because the repeated import
  overwrote every paragraphs with bad hyphenation setting
  (hyphenation-keep = "auto" instead of hyphenation-keep = "page").

– export also "Hyphenate CAPS" and "Hyphenation zone" settings,
  if hyphenation is enabled in text body style with these settings,
  and not in the default paragraph style. Setting hyphenation only
  in "Text Body" is more common in documents created in LibreOffice.

Follow-up to commit c8ee0e8f581b8a6e41b1a6b8aa4d40b442c1d463
"tdf160518 DOCX: import hyphenation-keep to fix layout".

Change-Id: I9dbaf1e37416758388e3b2b19db3317f3f5652b5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167749
Tested-by: Jenkins
Reviewed-by: László Németh 

diff --git 
a/sw/qa/extras/odfexport/data/tdf160518_auto_in_default_paragraph_style.fodt 
b/sw/qa/extras/odfexport/data/tdf160518_auto_in_default_paragraph_style.fodt
new file mode 100644
index ..6250cc0af3d5
--- /dev/null
+++ b/sw/qa/extras/odfexport/data/tdf160518_auto_in_default_paragraph_style.fodt
@@ -0,0 +1,42 @@
+
+
+http://www.w3.org/TR/css3-text/; 
xmlns:grddl="http://www.w3.org/2003/g/data-view#; 
xmlns:xhtml="http://www.w3.org/1999/xhtml; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance; 
xmlns:xsd="http://www.w3.org/2001/XMLSchema; 
xmlns:dom="http://www.w3.org/2001/xml-events; 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:ooo="http://openoffice.org/2004/office; 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" 
xmlns:ooow="http://openoffice.org/2004/writer; 
xmlns:xlink="http://www.w3.org/1999/xlink; 
xmlns:drawooo="http://openoffice.org/2010/draw; 
xmlns:oooc="http://openoffice.org/2004/calc; 
xmlns:dc="http://purl.org/dc/elements/1.1/; 
xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0"
 xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:of="urn:oas
 is:names:tc:opendocument:xmlns:of:1.2" 
xmlns:tableooo="http://openoffice.org/2009/table; 
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" 
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" 
xmlns:rpt="http://openoffice.org/2005/report; 
xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0"
 xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" 
xmlns:officeooo="http://openoffice.org/2009/office; office:version="1.3" 

core.git: sw/qa sw/source

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

New commits:
commit 9d3c6b31158aedc33bd616981f0f80af8a0ed1b0
Author: Mike Kaganski 
AuthorDate: Thu May 16 11:07:26 2024 +0500
Commit: Mike Kaganski 
CommitDate: Thu May 16 16:38:56 2024 +0200

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

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

Change-Id: Ib725ffb320ec5a81b39ce77f06392a82bd6d8ee0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167720
Reviewed-by: Mike Kaganski 
Tested-by: Jenkins
Reviewed-by: Patrick Luby 

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


core.git: sw/qa sw/source

2024-05-16 Thread Justin Luth (via logerrit)
 sw/qa/extras/ww8export/data/tdf72511_editengLRSpace.doc |binary
 sw/qa/extras/ww8export/ww8export4.cxx   |   23 ++
 sw/source/filter/ww8/ww8graf.cxx|   61 +++-
 sw/source/filter/ww8/ww8par.hxx |2 
 4 files changed, 82 insertions(+), 4 deletions(-)

New commits:
commit 7fcd5ac42086f1374c3bd5eb2be9a59e6f38f2e3
Author: Justin Luth 
AuthorDate: Tue May 14 18:12:59 2024 -0400
Commit: Michael Stahl 
CommitDate: Thu May 16 09:54:33 2024 +0200

tdf#72511 tdf#78510 ww8import: recombine into SvxLRSpaceItem for EE

This fixes Michael's 7.6 regression,
commit db115bec9254417ef7a3faf687478fe5424ab378
which split RES_LR_SPACE into (mainly) three pieces.

The regression caused paragraphs in textboxes
(and anything else that ends up in EditEng)
to lose left and right paragraph indents.

Accidentally, that regression fixed indents for comments,
since MSO ignores them for DOC format,
so I made sure that these properties were not passed to commments.

make CppunitTest_sw_ww8export4 \
CPPUNIT_TEST_NAME=testTdf72511_editengLRSpace

Change-Id: I95121e4b32193701af3e1d77ba92c36aca7f16cd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167651
Tested-by: Jenkins
Reviewed-by: Michael Stahl 
Reviewed-by: Justin Luth 

diff --git a/sw/qa/extras/ww8export/data/tdf72511_editengLRSpace.doc 
b/sw/qa/extras/ww8export/data/tdf72511_editengLRSpace.doc
new file mode 100644
index ..adf12e9f6b58
Binary files /dev/null and 
b/sw/qa/extras/ww8export/data/tdf72511_editengLRSpace.doc differ
diff --git a/sw/qa/extras/ww8export/ww8export4.cxx 
b/sw/qa/extras/ww8export/ww8export4.cxx
index 6caffceffa00..b52e2b8f77f1 100644
--- a/sw/qa/extras/ww8export/ww8export4.cxx
+++ b/sw/qa/extras/ww8export/ww8export4.cxx
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -54,6 +55,28 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf77964)
 CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AS_CHARACTER, 
getProperty(getShapeByName(u"Image2"), 
"AnchorType"));
 }
 
+DECLARE_WW8EXPORT_TEST(testTdf72511_editengLRSpace, 
"tdf72511_editengLRSpace.doc")
+{
+// given a default paragraph style with a left indent of 2 inches,
+// the comment should ignore the indent, but the textbox must not.
+uno::Reference xRun(
+
getProperty>(getRun(getParagraph(1), 3), 
"TextField"));
+uno::Reference 
xComment(getProperty>(xRun, "TextRange"));
+uno::Reference xParagraph(getParagraphOfText(1, 
xComment), uno::UNO_QUERY);
+// The comment was indented by 4001 (2 inches) instead of nothing
+CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty(xParagraph, 
"ParaLeftMargin"));
+
+uno::Reference xGroupShape(getShape(1), 
uno::UNO_QUERY_THROW);
+uno::Reference xShape2(xGroupShape->getByIndex(1), 
uno::UNO_QUERY_THROW);
+CPPUNIT_ASSERT_EQUAL(OUString("com.sun.star.drawing.TextShape"), 
xShape2->getShapeType());
+uno::Reference xTextbox(xShape2, uno::UNO_QUERY_THROW);
+uno::Reference xTBPara(xTextbox, uno::UNO_QUERY);
+// Textbox paragraphs had no indent instead of 5080 (2 inches - the same 
as normal paragraphs).
+CPPUNIT_ASSERT_EQUAL(sal_Int32(5080), getProperty(xTBPara, 
"ParaLeftMargin"));
+CPPUNIT_ASSERT_EQUAL_MESSAGE("sanity check: normal paragraph's indent", 
sal_Int32(5080),
+ getProperty(getParagraph(1), 
"ParaLeftMargin"));
+}
+
 DECLARE_WW8EXPORT_TEST(testTdf160049_anchorMargin, 
"tdf160049_anchorMargin.doc")
 {
 // given a document with a LEFT "column/text" anchored image
diff --git a/sw/source/filter/ww8/ww8graf.cxx b/sw/source/filter/ww8/ww8graf.cxx
index 28b1211683d1..a0209e002d8e 100644
--- a/sw/source/filter/ww8/ww8graf.cxx
+++ b/sw/source/filter/ww8/ww8graf.cxx
@@ -68,6 +68,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -495,7 +496,7 @@ static ESelection GetESelection(EditEngine const 
, tools::Long n
 // Which-IDs are changed according to the aDstTab table so that the
 // EditEngine will not ignore them.
 // Both Paragraph and character attributes are stuffed into the ItemSet.
-void SwWW8ImplReader::InsertTxbxStyAttrs( SfxItemSet& rS, sal_uInt16 nColl )
+void SwWW8ImplReader::InsertTxbxStyAttrs(SfxItemSet& rS, sal_uInt16 nColl, 
ManTypes eType)
 {
 SwWW8StyInf * pStyInf = GetStyle(nColl);
 if( !(pStyInf != nullptr && pStyInf->m_pFormat && pStyInf->m_bColl) )
@@ -512,7 +513,30 @@ void SwWW8ImplReader::InsertTxbxStyAttrs( SfxItemSet& rS, 
sal_uInt16 nColl )
 SfxItemPool *pEditPool = rS.GetPool();
 sal_uInt16 nWhich = i;
 sal_uInt16 nSlotId = m_rDoc.GetAttrPool().GetSlotId(nWhich);
-if (
+
+if (nWhich == RES_MARGIN_FIRSTLINE || nWhich == RES_MARGIN_TEXTLEFT
+|| nWhich == RES_MARGIN_RIGHT)
+{
+// MSO ignores 

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

2024-05-10 Thread László Németh (via logerrit)
 sw/qa/extras/odfexport/data/tdf132599_page_in_table.fodt |  225 +++
 sw/qa/extras/odfexport/odfexport2.cxx|   16 +
 sw/source/core/text/widorp.cxx   |6 
 3 files changed, 246 insertions(+), 1 deletion(-)

New commits:
commit a4970f4eeb94b8c405c5e3ec094d47061253efac
Author: László Németh 
AuthorDate: Fri May 10 12:23:30 2024 +0200
Commit: László Németh 
CommitDate: Fri May 10 15:25:12 2024 +0200

tdf#132599 sw: fix hyphenation-keep for tables and no widow

Now hyphenation-keep works without widow settings, too, e.g.
in tables (where despite the existing widow settings,
widow handling is always disabled).

Follow-up to commit 6e8819f29b6051a0e551d77512830539913ec277
"tdf#132599 cui offapi sw xmloff: add hyphenation-keep-type",
commit c8a99cb8dce54de506ba66d1cc0818b9b5f7858b
"tdf#132599 sw schema xmloff: add hyphenation-keep-type='always'
commit d4304cd0a4fedd0117fea3625dff1fca2945a0e6
"tdf132599 sw: fix hyphenation-keep for linked frames, also for spreads".

Change-Id: Id3db9631bb75d220e6fee7ebc9a5e7adad735273
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167447
Tested-by: Jenkins
Reviewed-by: László Németh 

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

core.git: sw/qa sw/source

2024-05-10 Thread László Németh (via logerrit)
 sw/qa/extras/layout/data/tdf132599_frames_on_right_pages_no_hyphenation.fodt | 
 224 +
 sw/qa/extras/layout/data/tdf132599_frames_on_same_page_hyphenation.fodt  | 
 210 +
 sw/qa/extras/layout/data/tdf132599_frames_on_same_page_no_hyphenation.fodt   | 
 210 +
 sw/qa/extras/layout/data/tdf132599_frames_on_spread_hyphenation.fodt | 
 231 ++
 sw/qa/extras/layout/layout3.cxx  | 
  99 
 sw/source/core/text/widorp.cxx   | 
  25 -
 6 files changed, 983 insertions(+), 16 deletions(-)

New commits:
commit d4304cd0a4fedd0117fea3625dff1fca2945a0e6
Author: László Németh 
AuthorDate: Wed May 8 13:20:26 2024 +0200
Commit: László Németh 
CommitDate: Fri May 10 09:58:43 2024 +0200

tdf132599 sw: fix hyphenation-keep for linked frames, also for spreads

Linked text frames are hyphenated as columns on the same page,
i.e. do not shift the hyphenated line, if hyphenation-keep-type="page"
or "spread".

For "spread", check also that the hyphenated line is on the previous
left page, because checking only right page wasn't enough for linked
text frames and blank left pages.

Follow-up to commit 6e8819f29b6051a0e551d77512830539913ec277
"tdf#132599 cui offapi sw xmloff: add hyphenation-keep-type" and
commit c8a99cb8dce54de506ba66d1cc0818b9b5f7858b
"tdf#132599 sw schema xmloff: add hyphenation-keep-type='always'".

Change-Id: I8965b42aa26c3c2571e07ad1b45dce6a9f61c633
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167390
Tested-by: Jenkins
Reviewed-by: László Németh 

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

core.git: sw/qa sw/source

2024-05-07 Thread Michael Stahl (via logerrit)
 sw/qa/extras/ooxmlexport/ooxmlexport9.cxx  |4 
 sw/source/writerfilter/dmapper/StyleSheetTable.cxx |  417 ++---
 2 files changed, 367 insertions(+), 54 deletions(-)

New commits:
commit 72ea1005b987159a6a59f9379e63321e0b0dd44f
Author: Michael Stahl 
AuthorDate: Mon May 6 15:58:36 2024 +0200
Commit: Michael Stahl 
CommitDate: Tue May 7 09:33:58 2024 +0200

tdf#160402 writerfilter: extend StyleMap with all Word styles

There doesn't appear to be an accurate and complete documentation of all
the Word built-in style names, but fortunately Word writes them all into
styles.xml in a w:latentStyles element anyway.

It turned out that a lot of the Writer built-in style names here were
obsoleted by renaming and did not match any more.

Change-Id: Ic69785a34524f667b83a06a267715b2c8b0165d0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167242
Tested-by: Jenkins
Reviewed-by: Michael Stahl 

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
index 0a914500b526..fefabe5c3df3 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
@@ -563,7 +563,7 @@ 
DECLARE_OOXMLEXPORT_TEST(testTdf104061_tableSectionColumns,"tdf104061_tableSecti
 
 //tdf#95114 - follow style is Text Body - DOCX test
 uno::Reference< beans::XPropertySet > 
properties(getStyles("ParagraphStyles")->getByName("annotation subject"), 
uno::UNO_QUERY);
-CPPUNIT_ASSERT_EQUAL(OUString("annotation text"), 
getProperty(properties, "FollowStyle"));
+CPPUNIT_ASSERT_EQUAL(OUString("Marginalia"), 
getProperty(properties, "FollowStyle"));
 }
 
 DECLARE_OOXMLEXPORT_TEST(testTdf46940_dontEquallyDistributeColumns, 
"tdf46940_dontEquallyDistributeColumns.docx")
@@ -690,7 +690,7 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf109310_endnoteStyleForMSO)
 xmlDocUniquePtr pXmlDoc = parseExport("word/endnotes.xml");
 // Check w:rStyle element has w:val attribute - note that w: is not 
specified for attribute
 assertXPath(pXmlDoc, 
"/w:endnotes/w:endnote[@w:id='2']/w:p/w:r[1]/w:rPr/w:rStyle"_ostr, "val"_ostr,
-"EndnoteCharacters");
+"EndnoteCharacters1");
 }
 
 CPPUNIT_TEST_FIXTURE(Test, testTdf103389)
diff --git a/sw/source/writerfilter/dmapper/StyleSheetTable.cxx 
b/sw/source/writerfilter/dmapper/StyleSheetTable.cxx
index eac2585bb6ca..6ee04ee59fa6 100644
--- a/sw/source/writerfilter/dmapper/StyleSheetTable.cxx
+++ b/sw/source/writerfilter/dmapper/StyleSheetTable.cxx
@@ -1562,10 +1562,18 @@ StyleSheetTable::ConvertStyleName(const OUString& 
rWWName)
 // will point to a style with specific RES_POOL* in its m_nPoolFormatId. 
Then on export, the
 // pool format id will map to a ww::sti enum value, and finally to a Word 
style name. Keep this
 // part in sync with the export functions mentioned above!
-// In addition to "standard" names, some case variations are handled here; 
and also there are
-// a number of strange mappings like "BodyTextIndentItalic" -> "Text body 
indent italic", which
-// map something unused in Word to something unused in Writer :-/
+// In addition to "standard" names, some case variations are handled here.
+// It's required to know all the Word paragraph/character styles for
+// STYLEREF/TOC fields; the ones that don't have a Writer equivalent have
+// an empty string in the map, and the code should return the original 
name.
+// Also very unclear: at least in DOCX, style names appear to be case
+// sensitive; if Word imports 2 styles that have the same case-insensitive
+// name as a built-in style, it renames one of them by appending a number.
+// These are from the w:latentStyles in the styles.xml of a Word 15.0 DOCX,
+// plus some pre-existing additions and variants.
 static const std::map< OUString, OUString> StyleNameMap {
+//FIXME: testFdo77716, testTdf129575_docDefault etc. fail with correct 
mapping
+//{ "Normal", "Default Paragraph Style" }, // RES_POOLCOLL_STANDARD
 { "Normal", "Standard" }, // RES_POOLCOLL_STANDARD
 { "heading 1", "Heading 1" }, // RES_POOLCOLL_HEADLINE1
 { "heading 2", "Heading 2" }, // RES_POOLCOLL_HEADLINE2
@@ -1588,12 +1596,21 @@ StyleSheetTable::ConvertStyleName(const OUString& 
rWWName)
 { "Index 1", "Index 1" }, // RES_POOLCOLL_TOX_IDX1
 { "Index 2", "Index 2" }, // RES_POOLCOLL_TOX_IDX2
 { "Index 3", "Index 3" }, // RES_POOLCOLL_TOX_IDX3
-//{ "Index 4", "" },
-//{ "Index 5", "" },
-//{ "Index 6", "" },
-//{ "Index 7", "" },
-//{ "Index 8", "" },
-//{ "Index 9", "" },
+{ "Index 4", "" },
+{ "Index 5", "" },
+{ "Index 6", "" },
+{ "Index 7", "" },
+{ "Index 8", "" },
+{ "Index 9", "" },
+{ "index 1", "Index 1" }, // RES_POOLCOLL_TOX_IDX1
+{ "index 

core.git: sw/qa sw/source

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

New commits:
commit d4fdafa103bfea94a279d7069ddc50ba92f67d01
Author: Michael Stahl 
AuthorDate: Fri May 3 19:31:20 2024 +0200
Commit: Michael Stahl 
CommitDate: Mon May 6 18:49:58 2024 +0200

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

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

Works for the "Intensive Hervorhebung" field in bugdoc.

Change-Id: Iee126eeb4cc2ff1c570941e3beefd93527c56fee
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167098
Reviewed-by: Michael Stahl 
Tested-by: Jenkins

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

core.git: sw/qa sw/source

2024-05-06 Thread Justin Luth (via logerrit)
 sw/qa/extras/ooxmlexport/data/tdf160814_commentOrder.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlexport21.cxx|   14 ++
 sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx  |   70 ++
 3 files changed, 84 insertions(+)

New commits:
commit 7ae84ed99b133cdb4c197ecb43e2454f90b0439a
Author: Justin Luth 
AuthorDate: Fri Apr 26 14:23:34 2024 -0400
Commit: Miklos Vajna 
CommitDate: Mon May 6 09:09:53 2024 +0200

tdf#160814 writerfilter: insert comment after other comments

If multiple comments all have on the same range
(comment replies typically, but not necessarily)
then make sure that later replies are not inserted
in front of the earlier replies.

MSO can anchor their comments anywhere in the document,
so this is not a perfect, fool-proof solution.
However, it should handle the typical cases.

make CppunitTest_sw_ooxmlexport21 /
CPPUNIT_TEST_NAME=testTdf160814_commentOrder

Change-Id: I8ebdae83e4dec25ee34dffc3e84bbd3068a15f57
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166765
Reviewed-by: Justin Luth 
Reviewed-by: Miklos Vajna 
Tested-by: Jenkins

diff --git a/sw/qa/extras/ooxmlexport/data/tdf160814_commentOrder.docx 
b/sw/qa/extras/ooxmlexport/data/tdf160814_commentOrder.docx
new file mode 100644
index ..f8d93e70b409
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf160814_commentOrder.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
index 15af73057d75..01c42d0ea34d 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
@@ -437,6 +437,20 @@ CPPUNIT_TEST_FIXTURE(Test, 
testTdf159207_footerFramePrBorder)
 // TODO: there SHOULD BE a top border, and even if loaded, it would be 
lost on re-import...
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testTdf160814_commentOrder)
+{
+// given a document with a comment and 5 replies
+loadAndSave("tdf160814_commentOrder.docx");
+
+// make sure the order of the comments is imported and exported correctly
+xmlDocUniquePtr pXmlComments = parseExport("word/comments.xml");
+// This really should be "1. First comment", the 1. being list numbering...
+assertXPathContent(pXmlComments, "//w:comment[1]//w:t"_ostr, "First 
comment");
+assertXPathContent(pXmlComments, "//w:comment[2]//w:t"_ostr, "1.1 first 
reply.");
+assertXPathContent(pXmlComments, "//w:comment[4]//w:t"_ostr, "1.3");
+assertXPathContent(pXmlComments, "//w:comment[6]//w:t"_ostr, "1.5");
+}
+
 CPPUNIT_TEST_FIXTURE(Test, testPersonalMetaData)
 {
 // 1. Remove all personal info
diff --git a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx 
b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
index a0f0af0831f5..a26c517064ec 100644
--- a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
+++ b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
@@ -4545,6 +4545,76 @@ void DomainMapper_Impl::PopAnnotation()
 }
 
 xCursor->gotoRange(aAnnotationPosition.m_xEnd, true);
+
+// MS Word can anchor a comment anywhere in the document, but LO 
always anchors it
+// immediately at the end of the range it spans.
+// If multiple comments have the same end-point, we need to expand 
the range so that
+// this later comment doesn't insert itself before any earlier 
ones.
+const uno::Reference 
xModel(static_cast(m_xTextDocument.get()));
+const uno::Reference xTFS(xModel, 
uno::UNO_QUERY);
+if (xTFS.is())
+{
+// sadly, the enumeration is not correctly sorted, which 
really complicates things.
+const uno::Reference 
xFieldEA(xTFS->getTextFields());
+bool bRetry(false);
+// keep track of the relevant (unsorted) fields that might 
have the same end point
+std::vector> xRetryFields;
+
+uno::Reference xEnum = 
xFieldEA->createEnumeration();
+// Although the primary interest is other comments, the same 
principle
+// probably applies to any kind of field.
+while (xEnum->hasMoreElements())
+{
+try
+{
+// IMPORTANT: nextElement() MUST run before any 
possible exception...
+const uno::Reference 
xField(xEnum->nextElement(),
+  
uno::UNO_QUERY_THROW);
+if 
(xTextRangeCompare->compareRegionStarts(xCursor->getEnd(),
+   
xField->getAnchor()) == 1)
+{
+// Not interesting: our comment-to-insert ends 
before this field begins
+continue;
+  

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

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

New commits:
commit 0d82ddb39e0cdbfde428eb4da7268cac4176f1bd
Author: Mike Kaganski 
AuthorDate: Thu May 2 09:11:25 2024 +0500
Commit: Mike Kaganski 
CommitDate: Thu May 2 08:56:47 2024 +0200

tdf#160898: check for nullptr

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

Change-Id: I9289171647fca8bd1b696399ff7c43a2ac7b8b30
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166990
Reviewed-by: Mike Kaganski 
Tested-by: Jenkins

diff --git a/sw/qa/extras/uiwriter/data/table-in-table.fodt 
b/sw/qa/extras/uiwriter/data/table-in-table.fodt
new file mode 100644
index ..e055d343b847
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/table-in-table.fodt
@@ -0,0 +1,29 @@
+
+
+
+ 
+  
+   
+  
+ 
+ 
+  
+   
+   
+
+
+ 
+  
+   
+   
+
+   
+  
+  
+ 
+
+   
+   
+  
+ 
+
\ No newline at end of file
diff --git a/sw/qa/extras/uiwriter/uiwriter9.cxx 
b/sw/qa/extras/uiwriter/uiwriter9.cxx
index 93d608a69247..d8b10279a827 100644
--- a/sw/qa/extras/uiwriter/uiwriter9.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter9.cxx
@@ -593,6 +593,20 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf146190)
 CPPUNIT_ASSERT_EQUAL(OUString("Shape 1"), 
rMrkList.GetMark(0)->GetMarkedSdrObj()->GetName());
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf160898)
+{
+// Given a document with a 1-cell table in another 1-cell table:
+createSwDoc("table-in-table.fodt");
+SwXTextDocument* pXTextDocument = 
dynamic_cast(mxComponent.get());
+SwDocShell* pDocShell = pXTextDocument->GetDocShell();
+SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
+
+// Move to the normally hidden paragraph inside the outer table cell, 
following the inner table
+pWrtShell->Down(false, 2);
+// Without the fix, this would crash:
+pWrtShell->SelAll();
+}
+
 } // end of anonymous namespace
 CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index 58396b6f2890..d3b39a4ae2c4 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -737,9 +737,15 @@ bool SwCursorShell::MoveStartText()
 SwTableNode const*const pTable(pStartNode->FindTableNode());
 m_pCurrentCursor->GetPoint()->Assign(*pStartNode);
 SwNodes::GoNext(m_pCurrentCursor->GetPoint());
-while (m_pCurrentCursor->GetPoint()->GetNode().FindTableNode() != pTable
-&& (!pTable || pTable->GetIndex() < 
m_pCurrentCursor->GetPoint()->GetNode().FindTableNode()->GetIndex())
-&& MoveOutOfTable());
+while (auto* pFoundTable = 
m_pCurrentCursor->GetPoint()->GetNode().FindTableNode())
+{
+if (pFoundTable == pTable)
+break;
+if (pTable && pTable->GetIndex() >= pFoundTable->GetIndex())
+break;
+if (!MoveOutOfTable())
+break;
+}
 
UpdateCursor(SwCursorShell::SCROLLWIN|SwCursorShell::CHKRANGE|SwCursorShell::READONLY);
 return old != *m_pCurrentCursor->GetPoint();
 }


core.git: sw/qa sw/source

2024-05-01 Thread Mike Kaganski (via logerrit)
 sw/qa/extras/htmlexport/htmlexport.cxx  |   15 +++
 sw/source/filter/html/htmlflywriter.cxx |   31 +++
 2 files changed, 38 insertions(+), 8 deletions(-)

New commits:
commit 96eabc69e9c3c6e9c944a4e83adddea44d48c621
Author: Mike Kaganski 
AuthorDate: Wed May 1 12:10:23 2024 +0500
Commit: Mike Kaganski 
CommitDate: Wed May 1 12:12:59 2024 +0200

tdf#160867: only output first element of the map in ReqIF case

It should be investigated, how the whole image map can be output in
that case - something to be done separately.

Change-Id: I6543c0d238205fabdb0a688e32a2d08423d7a5d3
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166948
Reviewed-by: Mike Kaganski 
Tested-by: Jenkins

diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx 
b/sw/qa/extras/htmlexport/htmlexport.cxx
index 1fc731b8b21d..282ce035b3a6 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -3107,6 +3107,21 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, 
testHTML_160867)
 assertXPath(pDoc, "/html/body/p[2]/img"_ostr, "usemap"_ostr, "#" + 
mapName);
 }
 
+CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testReqIF_160867)
+{
+// Given a document with an image with hyperlink, and text with hyperlink, 
both in a frame:
+createSwDoc("tdf160867_image_with_link.fodt");
+// When exporting to reqif:
+ExportToReqif();
+// For now, we don't (yet) output the whole map in ReqIF case.
+// Make sure that the first hyperlink from the objects in the frame is 
output as an  element
+// around the whole image of the frame.
+xmlDocUniquePtr pXmlDoc = WrapReqifFromTempFile();
+assertXPath(pXmlDoc, 
"//reqif-xhtml:p[2]/reqif-xhtml:a/reqif-xhtml:object"_ostr);
+CPPUNIT_ASSERT(getXPath(pXmlDoc, "//reqif-xhtml:p[2]/reqif-xhtml:a"_ostr, 
"href"_ostr)
+   .endsWith("foo/bar"));
+}
+
 } // end of anonymous namespace
 CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/sw/source/filter/html/htmlflywriter.cxx 
b/sw/source/filter/html/htmlflywriter.cxx
index ea421f3cbc72..80b4abf5eade 100644
--- a/sw/source/filter/html/htmlflywriter.cxx
+++ b/sw/source/filter/html/htmlflywriter.cxx
@@ -1080,17 +1080,17 @@ OUString lclWriteOutImap(SwHTMLWriter& rWrt, const 
SfxItemSet& rItemSet, const S
 OUString aIMapName;
 
 // Only consider the URL attribute if no ImageMap was supplied
-if (!pAltImgMap)
-pURLItem = rItemSet.GetItemIfSet( RES_URL );
 
 // write ImageMap
 const ImageMap* pIMap = pAltImgMap;
-if( !pIMap && pURLItem )
+if( !pIMap  )
 {
-pIMap = pURLItem->GetMap();
+pURLItem = rItemSet.GetItemIfSet(RES_URL);
+if (pURLItem)
+pIMap = pURLItem->GetMap();
 }
 
-if (pIMap)
+if (pIMap && !rWrt.mbReqIF)
 {
 // make the name unique
 aIMapName = pIMap->GetName();
@@ -1098,10 +1098,10 @@ OUString lclWriteOutImap(SwHTMLWriter& rWrt, const 
SfxItemSet& rItemSet, const S
 if (!aIMapName.isEmpty())
 aNameBase = aIMapName;
 else
+{
 aNameBase = OOO_STRING_SVTOOLS_HTML_map;
-
-if (aIMapName.isEmpty())
 aIMapName = aNameBase + OUString::number(rWrt.m_nImgMapCnt);
+}
 
 bool bFound;
 do
@@ -1271,7 +1271,7 @@ SwHTMLWriter& OutHTML_ImageStart( HtmlWriter& rHtml, 
SwHTMLWriter& rWrt, const S
 // URL -> ..
 const SvxMacroItem *pMacItem = rItemSet.GetItemIfSet(RES_FRMMACRO);
 
-if (pURLItem || pMacItem)
+if (pURLItem || pMacItem || (rWrt.mbReqIF && pAltImgMap))
 {
 OUString aMapURL;
 OUString aName;
@@ -1283,6 +1283,21 @@ SwHTMLWriter& OutHTML_ImageStart( HtmlWriter& rHtml, 
SwHTMLWriter& rWrt, const S
 aName = pURLItem->GetName();
 aTarget = pURLItem->GetTargetFrameName();
 }
+else if (rWrt.mbReqIF && pAltImgMap)
+{
+// Get first non-empty map element
+for (size_t i = 0; i < pAltImgMap->GetIMapObjectCount(); ++i)
+{
+if (auto* pIMapObject = pAltImgMap->GetIMapObject(i))
+{
+aMapURL = pIMapObject->GetURL();
+aName = pIMapObject->GetName();
+aTarget = pIMapObject->GetTarget();
+if (!aMapURL.isEmpty() || !aName.isEmpty() || 
!aTarget.isEmpty())
+break;
+}
+}
+}
 
 bool bEvents = pMacItem && !pMacItem->GetMacroTable().empty();
 


core.git: sw/qa sw/source

2024-04-30 Thread Mike Kaganski (via logerrit)
 sw/qa/extras/htmlexport/htmlexport.cxx |8 ++--
 sw/source/core/text/inftxt.cxx |   16 
 sw/source/core/text/itrpaint.cxx   |   17 +
 sw/source/core/text/porfly.hxx |1 +
 4 files changed, 40 insertions(+), 2 deletions(-)

New commits:
commit 42876f0a99e2ae7cb7529dd7fb4d94c5e9298b21
Author: Mike Kaganski 
AuthorDate: Tue Apr 30 22:16:12 2024 +0500
Commit: Mike Kaganski 
CommitDate: Wed May 1 06:59:40 2024 +0200

tdf#160867: export as-char frames' hyperlinks to image map

Change-Id: Idc8d41a27c8ee9cdd12fb5e17a328ec6aa104a16
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166935
Tested-by: Jenkins
Reviewed-by: Mike Kaganski 

diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx 
b/sw/qa/extras/htmlexport/htmlexport.cxx
index 329be9231bb9..1fc731b8b21d 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -3093,13 +3093,17 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, 
testHTML_160867)
 CPPUNIT_ASSERT(pDoc);
 assertXPath(pDoc, "/html/body/p"_ostr, 2);
 
-// Test export of text hyperlink in the image map. TODO: implement export 
of image hyperlink.
+// Test export of image and text hyperlinks in the image map.
 // Without the fix, the test would fail with
 // - Expected: 1
 // - Actual  : 0
 // - In <>, XPath '/html/body/p[2]/map' number of nodes is incorrect
 const OUString mapName = getXPath(pDoc, "/html/body/p[2]/map"_ostr, 
"name"_ostr);
-assertXPath(pDoc, "/html/body/p[2]/map/area"_ostr, "shape"_ostr, 
u"rect"_ustr);
+assertXPath(pDoc, "/html/body/p[2]/map/area[1]"_ostr, "shape"_ostr, 
u"rect"_ustr);
+CPPUNIT_ASSERT(
+getXPath(pDoc, "/html/body/p[2]/map/area[1]"_ostr, 
"href"_ostr).endsWith("foo/bar"));
+assertXPath(pDoc, "/html/body/p[2]/map/area[2]"_ostr, "shape"_ostr, 
u"rect"_ustr);
+CPPUNIT_ASSERT(getXPath(pDoc, "/html/body/p[2]/map/area[2]"_ostr, 
"href"_ostr).endsWith("baz"));
 assertXPath(pDoc, "/html/body/p[2]/img"_ostr, "usemap"_ostr, "#" + 
mapName);
 }
 
diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx
index a1a3bb89a87b..ddcca31668db 100644
--- a/sw/source/core/text/inftxt.cxx
+++ b/sw/source/core/text/inftxt.cxx
@@ -44,6 +44,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -51,6 +52,7 @@
 #include 
 #include "inftxt.hxx"
 #include 
+#include "porfly.hxx"
 #include "porftn.hxx"
 #include "porrst.hxx"
 #include "itratr.hxx"
@@ -1479,6 +1481,20 @@ void SwTextPaintInfo::NotifyURL_(const SwLinePortion& 
rPor) const
 const SwFormatINetFormat& rFormat = pAttr->GetINetFormat();
 pNoteURL->InsertURLNote(rFormat.GetValue(), 
rFormat.GetTargetFrame(), aIntersect);
 }
+else if (rPor.IsFlyCntPortion())
+{
+if (auto* pFlyContentPortion = dynamic_cast())
+{
+if (auto* pFlyFtame = pFlyContentPortion->GetFlyFrame())
+{
+if (auto* pFormat = pFlyFtame->GetFormat())
+{
+auto& url = pFormat->GetURL(); // TODO: url.GetMap() ?
+pNoteURL->InsertURLNote(url.GetURL(), 
url.GetTargetFrameName(), aIntersect);
+}
+}
+}
+}
 }
 }
 
diff --git a/sw/source/core/text/itrpaint.cxx b/sw/source/core/text/itrpaint.cxx
index 8fa9ca45f5fd..f02beed8ce5b 100644
--- a/sw/source/core/text/itrpaint.cxx
+++ b/sw/source/core/text/itrpaint.cxx
@@ -33,6 +33,7 @@
 #include 
 #include "txtpaint.hxx"
 #include "porfld.hxx"
+#include "porfly.hxx"
 #include "portab.hxx"
 #include 
 #include 
@@ -40,6 +41,7 @@
 #include "porrst.hxx"
 #include "pormulti.hxx"
 #include 
+#include 
 
 // Returns, if we have an underline breaking situation
 // Adding some more conditions here means you also have to change them
@@ -461,6 +463,21 @@ void SwTextPainter::DrawTextLine( const SwRect , 
SwSaveClip ,
 
 if (GetFnt()->IsURL() && pPor->InTextGrp())
 GetInfo().NotifyURL(*pPor);
+else if (pPor->IsFlyCntPortion())
+{
+if (auto* pFlyContentPortion = 
dynamic_cast(pPor))
+{
+if (auto* pFlyFrame = pFlyContentPortion->GetFlyFrame())
+{
+if (auto* pFormat = pFlyFrame->GetFormat())
+{
+auto& url = pFormat->GetURL();
+if (!url.GetURL().isEmpty()) // TODO: url.GetMap() ?
+GetInfo().NotifyURL(*pPor);
+}
+}
+}
+}
 
 bFirst &= !pPor->GetLen();
 if( pNext || !pPor->IsMarginPortion() )
diff --git a/sw/source/core/text/porfly.hxx b/sw/source/core/text/porfly.hxx
index a519c1109c87..2c56563a4436 100644
--- a/sw/source/core/text/porfly.hxx
+++ b/sw/source/core/text/porfly.hxx
@@ -76,6 

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

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

New commits:
commit 30de13743f144aced83bc43d310592f82788c910
Author: László Németh 
AuthorDate: Fri Apr 26 22:03:53 2024 +0200
Commit: László Németh 
CommitDate: Mon Apr 29 00:16:31 2024 +0200

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

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

Change-Id: I6dde79e77563468059794548b6c058cad61586a0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166795
Reviewed-by: László Németh 
Tested-by: Jenkins

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

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

2024-04-26 Thread Mike Kaganski (via logerrit)
 sw/qa/extras/odfexport/data/deleted_table.fodt |   47 +
 sw/qa/extras/odfexport/odfexport2.cxx  |7 +++
 sw/source/filter/xml/xmlfmte.cxx   |6 ---
 xmloff/source/text/txtparae.cxx|3 +
 4 files changed, 57 insertions(+), 6 deletions(-)

New commits:
commit 105ce47a695cb7ea7e6abf879e1c632b7d81f054
Author: Mike Kaganski 
AuthorDate: Fri Apr 26 16:47:26 2024 +0500
Commit: Mike Kaganski 
CommitDate: Fri Apr 26 21:19:57 2024 +0200

Make sure that collecting redline autostyles succeeds

This step was called separately in SwXMLExport::ExportAutoStyles_,
after collectAutoStyles. collectTextAutoStylesAndNodeExportOrder
(which is called from collectAutoStyles) sets mbCollected to true,
and then all the code checking mbCollected/isAutoStylesCollected
stops collecting autostyles.

This moves exportTrackedChanges call to the place where all auto-
styles are collected.

Change-Id: I3f4bd0e0ff906a35b69c052e34adb6d66ef80d48
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166735
Reviewed-by: Mike Kaganski 
Tested-by: Jenkins

diff --git a/sw/qa/extras/odfexport/data/deleted_table.fodt 
b/sw/qa/extras/odfexport/data/deleted_table.fodt
new file mode 100644
index ..830eb278ce18
--- /dev/null
+++ b/sw/qa/extras/odfexport/data/deleted_table.fodt
@@ -0,0 +1,47 @@
+
+
+http://openoffice.org/2004/office; 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" 
xmlns:dc="http://purl.org/dc/elements/1.1/; 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" 
office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ 
+  
+   false
+  
+ 
+ 
+  
+   
+  
+  
+   
+  
+  
+   
+  
+  
+   
+  
+ 
+ 
+  
+   
+
+ 
+  
+   John Doe
+   2001-01-01T01:00:00
+  
+ 
+
+   
+   
+   
+
+
+ 
+  Deleted table
+ 
+
+   
+   
+  
+ 
+
\ No newline at end of file
diff --git a/sw/qa/extras/odfexport/odfexport2.cxx 
b/sw/qa/extras/odfexport/odfexport2.cxx
index be3f891b4e81..01016b5b8ad2 100644
--- a/sw/qa/extras/odfexport/odfexport2.cxx
+++ b/sw/qa/extras/odfexport/odfexport2.cxx
@@ -1602,6 +1602,13 @@ CPPUNIT_TEST_FIXTURE(Test, 
testTableInFrameAnchoredToPage)
 assertXPath(pXmlDoc, P + "/style:text-properties", "font-style"_ostr, 
u"italic"_ustr);
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testDeletedTableAutostylesExport)
+{
+// Given a document with deleted table:
+// it must not assert on export because of missing format for an exported 
table
+loadAndReload("deleted_table.fodt");
+}
+
 } // end of anonymous namespace
 CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/sw/source/filter/xml/xmlfmte.cxx b/sw/source/filter/xml/xmlfmte.cxx
index d64810724cf8..4a70f2953868 100644
--- a/sw/source/filter/xml/xmlfmte.cxx
+++ b/sw/source/filter/xml/xmlfmte.cxx
@@ -263,12 +263,6 @@ void SwXMLExport::ExportAutoStyles_()
 if( !(getExportFlags() & SvXMLExportFlags::STYLES) )
 GetTextParagraphExport()->exportUsedDeclarations();
 
-// exported in ExportContent_
-if( getExportFlags() & SvXMLExportFlags::CONTENT )
-{
-GetTextParagraphExport()->exportTrackedChanges( true );
-}
-
 GetTextParagraphExport()->exportTextAutoStyles();
 GetShapeExport()->exportAutoStyles();
 if( getExportFlags() & SvXMLExportFlags::MASTERSTYLES )
diff --git a/xmloff/source/text/txtparae.cxx b/xmloff/source/text/txtparae.cxx
index df324c16acad..b0671175e547 100644
--- a/xmloff/source/text/txtparae.cxx
+++ b/xmloff/source/text/txtparae.cxx
@@ -1684,6 +1684,9 @@ void 
XMLTextParagraphExport::collectTextAutoStylesAndNodeExportOrder(bool bIsPro
 }
 }
 
+if (GetExport().getExportFlags() & SvXMLExportFlags::CONTENT)
+exportTrackedChanges(true);
+
 mbCollected = true;
 }
 


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

2024-04-24 Thread Heiko Tietze (via logerrit)
 sw/qa/uitest/writer_tests2/formatCharacter.py |   47 -
 sw/source/ui/chrdlg/chardlg.cxx   |  211 --
 sw/source/uibase/inc/chrdlg.hxx   |   30 ---
 sw/uiconfig/swriter/ui/characterproperties.ui |   30 ---
 4 files changed, 3 insertions(+), 315 deletions(-)

New commits:
commit 63315d601296f7c188e920f73b12260d018807d0
Author: Heiko Tietze 
AuthorDate: Tue Apr 23 17:20:47 2024 +0200
Commit: Heiko Tietze 
CommitDate: Wed Apr 24 16:13:15 2024 +0200

Resolves tdf#132253 - Remove hyperlink tab from character dialog

Change-Id: Idb7fa74dbe196262cea64946452043f7de6fa20c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166553
Tested-by: Jenkins
Reviewed-by: Heiko Tietze 

diff --git a/sw/qa/uitest/writer_tests2/formatCharacter.py 
b/sw/qa/uitest/writer_tests2/formatCharacter.py
index 265f7b4df92e..724b8813029e 100644
--- a/sw/qa/uitest/writer_tests2/formatCharacter.py
+++ b/sw/qa/uitest/writer_tests2/formatCharacter.py
@@ -65,8 +65,6 @@ class formatCharacter(UITestCase):
 xLangFontCTL = xDialog.getChild("cbCTLLanguage")
 self.assertEqual(get_state_as_dict(xLangFontCTL)["Text"], 
"[None]")
 
-
-
def test_format_character_tab_font_effects(self):
 with self.ui_test.create_doc_in_start_center("writer"):
 
@@ -115,47 +113,6 @@ class formatCharacter(UITestCase):
 
self.assertEqual(get_state_as_dict(xEmphasis)["SelectEntryText"], "Dot")
 
self.assertEqual(get_state_as_dict(xPosition)["SelectEntryText"], "Below text")
 
-
-
-   def test_format_character_tab_hyperlink(self):
-with self.ui_test.create_doc_in_start_center("writer") as document:
-
-with 
self.ui_test.execute_dialog_through_command(".uno:FontDialog") as xDialog:
-xTabs = xDialog.getChild("tabcontrol")
-select_pos(xTabs, "4")
-
-xURL = xDialog.getChild("urled")
-xURL.executeAction("TYPE", 
mkPropertyValues({"TEXT":"libreoffice.org"}))
-xTexted = xDialog.getChild("texted")
-xTexted.executeAction("TYPE", 
mkPropertyValues({"TEXT":"LibreOffice"}))
-xName = xDialog.getChild("nameed")
-xName.executeAction("TYPE", 
mkPropertyValues({"TEXT":"hyperlink"}))
-
-xVisited = xDialog.getChild("visitedlb")
-select_by_text(xVisited, "Bullets")
-xUnVisited = xDialog.getChild("unvisitedlb")
-select_by_text(xUnVisited, "Bullets")
-
-
-self.xUITest.executeCommand(".uno:GoLeft")
-self.assertEqual(document.Text.String[0:11], "LibreOffice")
-
-with 
self.ui_test.execute_dialog_through_command(".uno:FontDialog", 
close_button="cancel") as xDialog:
-xTabs = xDialog.getChild("tabcontrol")
-select_pos(xTabs, "4")
-xURL = xDialog.getChild("urled")
-xTexted = xDialog.getChild("texted")
-xName = xDialog.getChild("nameed")
-xVisited = xDialog.getChild("visitedlb")
-xUnVisited = xDialog.getChild("unvisitedlb")
-
-self.assertEqual(get_state_as_dict(xURL)["Text"], 
"http://libreoffice.org/;)
-self.assertEqual(get_state_as_dict(xTexted)["Text"], 
"LibreOffice")
-self.assertEqual(get_state_as_dict(xName)["Text"], "hyperlink")
-
self.assertEqual(get_state_as_dict(xVisited)["SelectEntryText"], "Bullets")
-
self.assertEqual(get_state_as_dict(xUnVisited)["SelectEntryText"], "Bullets")
-
-
def test_format_character_tab_asian_layout(self):
 with self.ui_test.create_doc_in_start_center("writer"):
 
@@ -221,8 +178,6 @@ class formatCharacter(UITestCase):
 self.assertEqual(get_state_as_dict(xFitToLine)["Selected"], 
"true")
 
self.assertEqual(get_state_as_dict(xNoHyphenation)["Selected"], "true")
 
-
-
def test_format_character_tab_position_scalewidthsb(self):
 with self.ui_test.create_doc_in_start_center("writer"):
 
@@ -240,6 +195,4 @@ class formatCharacter(UITestCase):
 xScalewidth = xDialog.getChild("scalewidthsb")
 self.assertEqual(get_state_as_dict(xScalewidth)["Text"], 
"101%")
 
-
-
 # vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/sw/source/ui/chrdlg/chardlg.cxx b/sw/source/ui/chrdlg/chardlg.cxx
index 14833d719282..f57a78d735c9 100644
--- a/sw/source/ui/chrdlg/chardlg.cxx
+++ b/sw/source/ui/chrdlg/chardlg.cxx
@@ -17,37 +17,18 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#include 
-#include 
-
-#include 
-#include 
-#include 
 #include 
-#include 
 #include 
-#include 
-#include 
 
 #include 
 #include 
 #include 
 #include 
-#include 
-#include 
-#include 
 #include 
-#include 
-#include 
 
 #include 
 #include 
-#include 
-#include 
-#include 
 #include 
-#include 

core.git: sw/qa sw/source

2024-04-23 Thread Miklos Vajna (via logerrit)
 sw/qa/core/frmedt/frmedt.cxx |   35 +
 sw/source/core/frmedt/fefly1.cxx |   47 ++-
 sw/source/uibase/inc/frmmgr.hxx  |2 -
 3 files changed, 82 insertions(+), 2 deletions(-)

New commits:
commit f9f2b7590bb7b3334d499b6884cc7f3e80843b8c
Author: Miklos Vajna 
AuthorDate: Tue Apr 23 08:29:07 2024 +0200
Commit: Miklos Vajna 
CommitDate: Tue Apr 23 09:48:01 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 

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 494b08b1c77c..a67d0753c97d 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;
+pAnchor->SetAnchor();
+rPam.emplace(aPosition);
+return true;
+}
+}
+
 void SwFEShell::Insert( const OUString& rGrfName, const 

core.git: sw/qa sw/source

2024-04-20 Thread Justin Luth (via logerrit)
 sw/qa/extras/ooxmlimport/ooxmlimport.cxx |3 ++
 sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx |   21 +++
 2 files changed, 24 insertions(+)

New commits:
commit 00ef339bfc747897b8e4410fa0aa4397c4e45717
Author: Justin Luth 
AuthorDate: Fri Apr 19 21:57:29 2024 -0400
Commit: Justin Luth 
CommitDate: Sat Apr 20 19:07:22 2024 +0200

tdf#81956 vml import: put groupshape in foreground if positive z-index

no interesting unit tests found, but this one at least lets you
add text to the body and visibly see the effect of foreground/background.

make CppunitTest_sw_ooxmlimport CPPUNIT_TEST_NAME=testN751077

Change-Id: Ib03e6b429ad4ec6a38d1119f3720bc56a70b98eb
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166345
Reviewed-by: Justin Luth 
Tested-by: Jenkins

diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx 
b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index e9bc24315d6b..7c2800b7aa72 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -175,6 +175,9 @@ xray ThisComponent.DrawPage(1).getByIndex(0).String
 xray ThisComponent.DrawPage(1).getByIndex(0).Anchor.PageStyleName
 */
 uno::Reference xShapes(getShape(2), uno::UNO_QUERY);
+// The groupshape should be in the foreground, not the background.
+CPPUNIT_ASSERT(getProperty(xShapes, "Opaque"));
+
 uno::Reference xShape(xShapes->getByIndex(0), 
uno::UNO_QUERY);
 CPPUNIT_ASSERT_EQUAL(OUString("TEXT1
"), xShape->getString());
 // we want to test the textbox is on the first page (it was put onto 
another page without the fix),
diff --git a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx 
b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
index 4fdacfb2f944..6e65750dec1e 100644
--- a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
+++ b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
@@ -4696,6 +4696,27 @@ void DomainMapper_Impl::PushShapeContext( const 
uno::Reference< drawing::XShape
 }
 }
 
+uno::Reference xShapePropertySet(xShape, 
uno::UNO_QUERY);
+uno::Sequence aGrabBag;
+xShapePropertySet->getPropertyValue("InteropGrabBag") >>= aGrabBag;
+
+for (const auto& rProp : aGrabBag)
+{
+if (rProp.Name == "VML-Z-ORDER")
+{
+sal_Int64 zOrder(0);
+rProp.Value >>= zOrder;
+
+text::TextContentAnchorType nAnchorType
+= text::TextContentAnchorType_AT_PARAGRAPH;
+
xShapePropertySet->getPropertyValue(getPropertyName(PROP_ANCHOR_TYPE))
+>>= nAnchorType;
+
+const uno::Any aOpaque(nAnchorType == 
text::TextContentAnchorType_AS_CHARACTER
+   || (zOrder >= 0 && 
!IsInHeaderFooter()));
+
xShapePropertySet->setPropertyValue(getPropertyName(PROP_OPAQUE), aOpaque);
+}
+}
 // A GroupShape doesn't implement text::XTextRange, but appending
 // an empty reference to the stacks still makes sense, because this
 // way bToRemove can be set, and we won't end up with duplicated


core.git: sw/qa sw/source

2024-04-20 Thread Jim Raykowski (via logerrit)
 sw/qa/extras/uiwriter/data/tdf146190.odt |binary
 sw/qa/extras/uiwriter/uiwriter9.cxx  |   38 +++
 sw/source/uibase/inc/wrtsh.hxx   |2 -
 sw/source/uibase/wrtsh/move.cxx  |   29 +++
 4 files changed, 48 insertions(+), 21 deletions(-)

New commits:
commit ca66965507494d0c5e07bfe81334749bc08af409
Author: Jim Raykowski 
AuthorDate: Sun Apr 14 14:49:48 2024 -0800
Commit: Jim Raykowski 
CommitDate: Sat Apr 20 18:14:00 2024 +0200

tdf#146190 Fix move to next drawing object using the tab key

after double click on a drawing obect in the Navigator doesn't move to
the next/previous drawing object when there is a number rule at the
current current cursor position and the current cursor position is at
the start of a paragraph.

This patch reworks the SwWrtShell::GotoDrawingObject function so the
document cursor position gets moved to the position of the drawing
object when the object is selected.

Another way to get expected results is to leave the GotoDrawingObject
function as is and move:

  else if (rSh.GetSelectionType() &
   (SelectionType::Graphic |
SelectionType::Frame |
SelectionType::Ole |
SelectionType::DrawObject |
SelectionType::DbForm))

above the:

  else if( rSh.GetNumRuleAtCurrCursorPos()
   && rSh.IsSttOfPara()
   && !rSh.HasReadonlySel() )

in the SwEditWin::KeyInput function case KEY_TAB: block.

SwWrtShell::GotoDrawingObject is made SW_DLLPUBIC by this patch to able
to be used by the included unit test.

Change-Id: I047b416ae94a9284d304798924e0c5f2be526f85
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166089
Tested-by: Jenkins
Reviewed-by: Jim Raykowski 

diff --git a/sw/qa/extras/uiwriter/data/tdf146190.odt 
b/sw/qa/extras/uiwriter/data/tdf146190.odt
new file mode 100644
index ..b686cb174bc9
Binary files /dev/null and b/sw/qa/extras/uiwriter/data/tdf146190.odt differ
diff --git a/sw/qa/extras/uiwriter/uiwriter9.cxx 
b/sw/qa/extras/uiwriter/uiwriter9.cxx
index f46d43e537b6..93d608a69247 100644
--- a/sw/qa/extras/uiwriter/uiwriter9.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter9.cxx
@@ -47,6 +47,9 @@
 #include 
 #include 
 
+#include 
+#include 
+
 namespace
 {
 class SwUiWriterTest9 : public SwModelTestBase
@@ -555,6 +558,41 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, 
testTdf158375_ole_object_disable)
 comphelper::LibreOfficeKit::setActive(false);
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf146190)
+{
+// Given a document with a number rule at the start of a paragraph and two 
drawing objects:
+createSwDoc("tdf146190.odt");
+SwXTextDocument* pXTextDocument = 
dynamic_cast(mxComponent.get());
+SwDocShell* pDocShell = pXTextDocument->GetDocShell();
+SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
+
+const SdrMarkList& rMrkList = 
pWrtShell->GetDrawView()->GetMarkedObjectList();
+
+// Assert the current cursor position has a number rule and is at the 
start of a paragraph:
+pWrtShell->SttEndDoc(/*bStt=*/true);
+CPPUNIT_ASSERT(pWrtShell->GetNumRuleAtCurrCursorPos());
+CPPUNIT_ASSERT(pWrtShell->IsSttOfPara());
+
+// Then go to "Shape 1" drawing object using the GotoDrawingObject 
function:
+pWrtShell->GotoDrawingObject(u"Shape 1");
+CPPUNIT_ASSERT_EQUAL(OUString("Shape 1"), 
rMrkList.GetMark(0)->GetMarkedSdrObj()->GetName());
+
+// Move to the next drawing object by Tab key press:
+pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
+Scheduler::ProcessEventsToIdle();
+// Without the fix in place, this test would have failed with:
+// equality assertion failed
+// - Expected: Shape 2
+// - Actual  : Shape 1
+// i.e. Tab did not move to the next drawing object
+CPPUNIT_ASSERT_EQUAL(OUString("Shape 2"), 
rMrkList.GetMark(0)->GetMarkedSdrObj()->GetName());
+
+// Tab key press should now select 'Shape 1':
+pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
+Scheduler::ProcessEventsToIdle();
+CPPUNIT_ASSERT_EQUAL(OUString("Shape 1"), 
rMrkList.GetMark(0)->GetMarkedSdrObj()->GetName());
+}
+
 } // end of anonymous namespace
 CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/sw/source/uibase/inc/wrtsh.hxx b/sw/source/uibase/inc/wrtsh.hxx
index e1727bfc9fdf..6c0d4c2dda0b 100644
--- a/sw/source/uibase/inc/wrtsh.hxx
+++ b/sw/source/uibase/inc/wrtsh.hxx
@@ -501,7 +501,7 @@ typedef bool (SwWrtShell::*FNSimpleMove)();
 SW_DLLPUBLIC bool GotoTable( const OUString& rName );
 void GotoFormatField( const SwFormatField& rField );
 const SwRangeRedline* GotoRedline( SwRedlineTable::size_type nArrPos, bool 
bSelect);
-bool GotoDrawingObject(std::u16string_view rName);
+SW_DLLPUBLIC bool GotoDrawingObject(std::u16string_view rName);
 void GotoFootnoteAnchor(const 

core.git: sw/qa sw/source

2024-04-19 Thread Justin Luth (via logerrit)
 sw/qa/extras/ooxmlexport/ooxmlexport14.cxx |1 +
 sw/source/core/text/txtfld.cxx |2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

New commits:
commit 3b7ffa204c6d04640b5e2f4d4c6b6b4a03fd26c8
Author: Justin Luth 
AuthorDate: Thu Apr 18 04:00:05 2024 -0400
Commit: Justin Luth 
CommitDate: Sat Apr 20 00:18:17 2024 +0200

tdf#140616 ApplyParagraphMarkFormatToNumbering: including highlight

I was concerned that I might override highlights
set in numbering.xml but in that case
pFormat && pFormat->hasItem(RES_CHRATR_HIGHLIGHT)
so pCleanSet no longer hasItem.
(see num3n.docx and TestDoc_highlight2.docx)
Note: must use Word 2010+ to see numbering.xml highlights!!

This is strictly a visual thing. Unit testing has traditionally
used magic tile rendering x,y positions to check the color,
which seems completely untrustworthy.

Change-Id: I026252f127107e4782d08f72bfd5e2a412142111
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166303
Tested-by: Jenkins
Reviewed-by: Justin Luth 

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
index 6528b093fd57..ba70a335ca09 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
@@ -965,6 +965,7 @@ CPPUNIT_TEST_FIXTURE(Test, testHighlightEdit_numbering)
 
 xmlDocUniquePtr pXmlStyles = parseExport("word/styles.xml");
 assertXPath(pXmlStyles, 
"//w:style[@w:styleId='CustomParaStyleHighlightGreen']/w:rPr/w:highlight"_ostr, 
"val"_ostr, "green");
+// Visually, the last bullet point's text should be green-highlighted (but 
the bullet point itself shouldn't)
 
 if (bWasExportToShade)
 {
diff --git a/sw/source/core/text/txtfld.cxx b/sw/source/core/text/txtfld.cxx
index 84f32e30971f..55e439096f3d 100644
--- a/sw/source/core/text/txtfld.cxx
+++ b/sw/source/core/text/txtfld.cxx
@@ -409,7 +409,7 @@ static void 
checkApplyParagraphMarkFormatToNumbering(SwFont* pNumFnt, SwTextForm
 
 if (oFontBackColor)
 pNumFnt->SetBackColor(oFontBackColor);
-if (aHighlight != COL_TRANSPARENT)
+if (aHighlight != COL_TRANSPARENT && 
!pCleanedSet->HasItem(RES_CHRATR_HIGHLIGHT))
 pNumFnt->SetHighlightColor(aHighlight);
 }
 


core.git: sw/qa sw/source

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

New commits:
commit 0c7ae3bd96130eaa400d55a3ba9bf1e2fe6600de
Author: Michael Stahl 
AuthorDate: Thu Apr 18 18:23:29 2024 +0200
Commit: Michael Stahl 
CommitDate: Fri Apr 19 18:12:33 2024 +0200

tdf#156146 tdf#159903 sw: add unit tests

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

Change-Id: Ia7ce5e148194a55b5d9874ed112aaa977ed16c7b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166258
Tested-by: Jenkins
Reviewed-by: Michael Stahl 

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

core.git: sw/qa sw/source

2024-04-19 Thread Justin Luth (via logerrit)
 sw/qa/extras/ooxmlexport/ooxmlexport14.cxx |3 +++
 sw/source/writerfilter/ooxml/model.xml |   11 ++-
 2 files changed, 13 insertions(+), 1 deletion(-)

New commits:
commit 4a120f4f557b99bb8371474a4e7fdaf52b148143
Author: Justin Luth 
AuthorDate: Wed Apr 17 16:11:56 2024 -0400
Commit: Miklos Vajna 
CommitDate: Fri Apr 19 14:20:58 2024 +0200

tdf#140616 writerfilter: recognize style rPr under pPr

Although it is completely NOT normal to put any rPr's
in the style's pPr (since they normally just go
into a stand-alone rPr), MSO is able to read and apply
those - while LO just ignored them (as misplaced properties).

It seems harmless to me to import it this way as well.

make CppunitTest_sw_ooxmlexport14 \
CPPUNIT_TEST_NAME=testHighlightEdit_numbering

Change-Id: Ie4a6c4c91a8214f40e34dc58c47b0bb9381bac1f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166189
Tested-by: Jenkins
Reviewed-by: Justin Luth 
Reviewed-by: Miklos Vajna 

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
index c33275b62394..6528b093fd57 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
@@ -963,6 +963,9 @@ CPPUNIT_TEST_FIXTURE(Test, testHighlightEdit_numbering)
 assertXPath(pXmlDoc, "//w:body/w:p[2]/w:pPr/w:rPr/w:highlight"_ostr, 
"val"_ostr, "none");
 // Visually, the "none" highlight means the bullet point should not have a 
character background.
 
+xmlDocUniquePtr pXmlStyles = parseExport("word/styles.xml");
+assertXPath(pXmlStyles, 
"//w:style[@w:styleId='CustomParaStyleHighlightGreen']/w:rPr/w:highlight"_ostr, 
"val"_ostr, "green");
+
 if (bWasExportToShade)
 {
 
officecfg::Office::Common::Filter::Microsoft::Export::CharBackgroundToHighlighting::set(false,
 batch);
diff --git a/sw/source/writerfilter/ooxml/model.xml 
b/sw/source/writerfilter/ooxml/model.xml
index 2f84e72c0615..c99eb836ffe6 100644
--- a/sw/source/writerfilter/ooxml/model.xml
+++ b/sw/source/writerfilter/ooxml/model.xml
@@ -12620,6 +12620,12 @@
   
 
   
+  
+
+
+  
+
+  
   
 
 
@@ -16226,7 +16232,7 @@
   
 
 
-  
+  
 
 
   
@@ -17739,6 +17745,9 @@
   
   
 
+
+  
+
 
   
   


core.git: sw/qa sw/source

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

New commits:
commit 58e79c4394783033f61e1309214d9060e2f0adf2
Author: Mike Kaganski 
AuthorDate: Fri Apr 19 00:34:28 2024 +0500
Commit: Mike Kaganski 
CommitDate: Fri Apr 19 05:23:38 2024 +0200

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

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

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

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

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

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


core.git: sw/qa sw/source

2024-04-15 Thread Oliver Specht (via logerrit)
 sw/qa/extras/uiwriter/uiwriter6.cxx |8 
 sw/qa/extras/uiwriter/uiwriter8.cxx |9 -
 sw/source/uibase/inc/wrtsh.hxx  |3 +++
 sw/source/uibase/shells/textsh.cxx  |   19 ---
 sw/source/uibase/wrtsh/wrtsh4.cxx   |   17 +
 5 files changed, 36 insertions(+), 20 deletions(-)

New commits:
commit b1170251fbca5b6b243902cf10695ab4c4c5642b
Author: Oliver Specht 
AuthorDate: Thu Apr 11 08:56:17 2024 +0200
Commit: Thorsten Behrens 
CommitDate: Mon Apr 15 19:05:14 2024 +0200

Improve case rotation in sentence case

Rotating case (Shift+F3) applies sentence case only
if multiple words are already selected or selects
sentence if SENTENCE_CASE is going to be applied.

Change-Id: I9e8536d7744a344d7ad54150783e91e843e0e81e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165986
Tested-by: Jenkins
Reviewed-by: Thorsten Behrens 

diff --git a/sw/qa/extras/uiwriter/uiwriter6.cxx 
b/sw/qa/extras/uiwriter/uiwriter6.cxx
index dbc115356cca..e4303419a599 100644
--- a/sw/qa/extras/uiwriter/uiwriter6.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter6.cxx
@@ -742,10 +742,6 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf157988)
 
 dispatchCommand(mxComponent, ".uno:ChangeCaseRotateCase", {});
 
-CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("Integer 
sodalesSODALES"));
-
-dispatchCommand(mxComponent, ".uno:ChangeCaseRotateCase", {});
-
 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("Integer sodales 
tincidunt"));
 
 dispatchCommand(mxComponent, ".uno:ChangeCaseRotateCase", {});
@@ -764,10 +760,6 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf157988)
 
 dispatchCommand(mxComponent, ".uno:ChangeCaseRotateCase", {});
 
-CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("Integer 
sodalesSODALES"));
-
-dispatchCommand(mxComponent, ".uno:ChangeCaseRotateCase", {});
-
 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("Integer sodales 
tincidunt"));
 
 dispatchCommand(mxComponent, ".uno:ChangeCaseRotateCase", {});
diff --git a/sw/qa/extras/uiwriter/uiwriter8.cxx 
b/sw/qa/extras/uiwriter/uiwriter8.cxx
index ff06611b46fd..ab820a9dfc79 100644
--- a/sw/qa/extras/uiwriter/uiwriter8.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter8.cxx
@@ -856,15 +856,6 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf116315)
 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_SHIFT | KEY_F3);
 Scheduler::ProcessEventsToIdle();
 
-// Sentence Case
-// Without the fix in place, this test would have failed with
-// - Expected: This is a Test
-// - Actual  : This is a TEST
-CPPUNIT_ASSERT_EQUAL(OUString("This is a Test"), 
getParagraph(1)->getString());
-
-pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_SHIFT | KEY_F3);
-Scheduler::ProcessEventsToIdle();
-
 // Upper Case
 CPPUNIT_ASSERT_EQUAL(OUString("This is a TEST"), 
getParagraph(1)->getString());
 
diff --git a/sw/source/uibase/inc/wrtsh.hxx b/sw/source/uibase/inc/wrtsh.hxx
index 8b8c85753e96..e1727bfc9fdf 100644
--- a/sw/source/uibase/inc/wrtsh.hxx
+++ b/sw/source/uibase/inc/wrtsh.hxx
@@ -239,6 +239,8 @@ typedef bool (SwWrtShell::*FNSimpleMove)();
 { SimpleMove( ::BwdPara_, false/*bSelect*/ ); }
 void FwdSentence( bool bSelect = false )
 { SimpleMove( ::FwdSentence_, bSelect ); }
+void EndSentence( bool bSelect = false )
+{ SimpleMove( ::EndSentence_, bSelect ); }
 void BwdSentence( bool bSelect = false )
 { SimpleMove( ::BwdSentence_, bSelect ); }
 
@@ -590,6 +592,7 @@ private:
 bool NxtWrdForDelete();
 bool PrvWrdForDelete();
 bool FwdSentence_();
+bool EndSentence_();
 bool BwdSentence_();
 SW_DLLPUBLIC bool FwdPara_();
 bool BwdPara_();
diff --git a/sw/source/uibase/shells/textsh.cxx 
b/sw/source/uibase/shells/textsh.cxx
index 1b1fb47fd1f3..93020de3bad2 100644
--- a/sw/source/uibase/shells/textsh.cxx
+++ b/sw/source/uibase/shells/textsh.cxx
@@ -878,20 +878,33 @@ void SwTextShell::ExecRotateTransliteration( SfxRequest 
const & rReq )
 {
 if( rReq.GetSlot() == SID_TRANSLITERATE_ROTATE_CASE )
 {
+TransliterationFlags transFlags = m_aRotateCase.getNextMode();
+bool bSentenceCase = TransliterationFlags::SENTENCE_CASE == transFlags;
 SwWrtShell& rSh = GetShell();
 if (rSh.HasSelection())
 {
-rSh.TransliterateText(m_aRotateCase.getNextMode());
+if (bSentenceCase)
+{
+OUString aSelection = rSh.GetSelText().trim();
+if (aSelection.getLength() <= 2 || (aSelection.indexOf(' ') < 
0 && aSelection.indexOf('') < 0))
+transFlags = m_aRotateCase.getNextMode();
+}
+rSh.TransliterateText(transFlags);
 }
 else
 {
+if (bSentenceCase)
+{
+if 

core.git: sw/qa sw/source

2024-04-10 Thread Gabor Kelemen (via logerrit)
 sw/qa/core/test_ToxMiscTest.cxx|2 --
 sw/qa/extras/accessibility/accessible_relation_set.cxx |1 -
 sw/qa/extras/uiwriter/uiwriter6.cxx|1 -
 sw/source/core/access/accpara.cxx  |1 -
 sw/source/core/bastyp/SwSmartTagMgr.cxx|1 -
 sw/source/core/crsr/crsrsh.cxx |1 -
 sw/source/core/doc/docdraw.cxx |1 -
 sw/source/core/doc/docedt.cxx  |1 -
 sw/source/core/doc/docfld.cxx  |2 --
 sw/source/core/doc/docfmt.cxx  |1 -
 sw/source/core/doc/poolfmt.cxx |1 -
 sw/source/core/doc/tblrwcl.cxx |1 -
 sw/source/core/edit/edtab.cxx  |1 -
 sw/source/core/edit/edtox.cxx  |1 -
 sw/source/core/fields/reffld.cxx   |1 -
 sw/source/core/text/txthyph.cxx|1 -
 sw/source/core/txtnode/thints.cxx  |2 --
 sw/source/core/undo/unovwr.cxx |1 -
 sw/source/filter/ww8/wrtw8esh.cxx  |1 -
 sw/source/filter/ww8/wrtw8num.cxx  |2 --
 sw/source/filter/ww8/ww8par3.cxx   |1 -
 sw/source/filter/xml/wrtxml.cxx|1 -
 sw/source/filter/xml/xmlexp.cxx|3 ---
 sw/source/filter/xml/xmlfmte.cxx   |3 ---
 sw/source/filter/xml/xmlfonte.cxx  |4 
 sw/source/filter/xml/xmlimp.cxx|1 -
 sw/source/filter/xml/xmliteme.cxx  |1 -
 sw/source/filter/xml/xmlmeta.cxx   |3 ---
 sw/source/filter/xml/xmlscript.cxx |2 --
 sw/source/filter/xml/xmltble.cxx   |2 --
 sw/source/filter/xml/xmltexte.cxx  |2 --
 sw/source/ui/chrdlg/chardlg.cxx|1 -
 sw/source/ui/chrdlg/drpcps.cxx |1 -
 sw/source/ui/config/mailconfigpage.cxx |2 --
 sw/source/ui/config/optcomp.cxx|1 -
 sw/source/ui/dbui/mailmergewizard.cxx  |1 -
 sw/source/ui/dbui/mmdocselectpage.cxx  |1 -
 sw/source/ui/dbui/mmgreetingspage.cxx  |1 -
 sw/source/ui/dbui/mmlayoutpage.cxx |2 --
 sw/source/ui/dbui/mmresultdialogs.cxx  |1 -
 sw/source/ui/envelp/envlop1.cxx|2 --
 sw/source/ui/envelp/labelexp.cxx   |1 -
 sw/source/ui/envelp/labfmt.cxx |2 --
 sw/source/ui/fldui/changedb.cxx|1 -
 sw/source/ui/index/cntex.cxx   |2 --
 sw/source/ui/misc/contentcontrollistitemdlg.cxx|2 --
 sw/source/ui/misc/glossary.cxx |1 -
 sw/source/ui/misc/srtdlg.cxx   |1 -
 sw/source/uibase/app/docsh2.cxx|1 -
 sw/source/uibase/app/swmodul1.cxx  |2 --
 sw/source/uibase/dialog/SwSpellDialogChildWindow.cxx   |2 --
 sw/source/uibase/docvw/romenu.cxx  |3 ---
 sw/source/uibase/fldui/fldmgr.cxx  |1 -
 sw/source/uibase/fldui/xfldui.cxx  |1 -
 sw/source/uibase/lingu/hhcwrp.cxx  |1 -
 sw/source/uibase/shells/basesh.cxx |1 -
 sw/source/uibase/shells/drawdlg.cxx|2 --
 sw/source/uibase/shells/drwbassh.cxx   |1 -
 sw/source/uibase/shells/grfshex.cxx|2 --
 sw/source/uibase/shells/textsh2.cxx|3 ---
 sw/source/uibase/uiview/view.cxx   |1 -
 sw/source/uibase/uiview/view2.cxx  |1 -
 sw/source/uibase/uiview/viewmdi.cxx|2 --
 sw/source/uibase/uiview/viewsrch.cxx   |2 --
 sw/source/uibase/utlui/numfmtlb.cxx|3 ---
 65 files changed, 99 deletions(-)

New commits:
commit 1a91641fd6fd84eb0bfae75db54f35c7771a2a1c
Author: Gabor Kelemen 
AuthorDate: Mon Apr 1 10:33:57 2024 +0200
Commit: Gabor Kelemen 
CommitDate: Wed Apr 10 09:19:42 2024 +0200

tdf#146619 Drop unused 'using namespace' in: sw/

Change-Id: I56463130ab617b0e11e237718cb8456913373818
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165696
Tested-by: Jenkins
Reviewed-by: Gabor Kelemen 

diff --git a/sw/qa/core/test_ToxMiscTest.cxx b/sw/qa/core/test_ToxMiscTest.cxx
index c7e6223b927b..3e75f06b16bd 100644
--- a/sw/qa/core/test_ToxMiscTest.cxx
+++ b/sw/qa/core/test_ToxMiscTest.cxx
@@ -12,8 +12,6 @@
 #include 
 #include 
 
-using namespace sw;
-
 class 

core.git: sw/qa sw/source

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

New commits:
commit 607fcac441c7f3a7d3c169c19039e581d707f2bb
Author: Miklos Vajna 
AuthorDate: Mon Apr 8 06:36:37 2024 +0200
Commit: Miklos Vajna 
CommitDate: Mon Apr 8 08:05:33 2024 +0200

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

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

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

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

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

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

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


core.git: sw/qa sw/source

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

New commits:
commit c6075e716200e9c6bae1b10be2cf10013958e83a
Author: Samuel Mehrbrodt 
AuthorDate: Mon Mar 18 15:19:42 2024 +0100
Commit: Samuel Mehrbrodt 
CommitDate: Thu Mar 28 10:43:17 2024 +0100

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

Change-Id: Ifde41deb66c8dcb72842e18e539609ff351be832
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164972
Tested-by: Jenkins
Reviewed-by: Samuel Mehrbrodt 

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


core.git: sw/qa sw/source

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

New commits:
commit d9c778391796e91ea3da361bf3901000350c26dd
Author: Mike Kaganski 
AuthorDate: Wed Mar 27 16:01:51 2024 +0500
Commit: Mike Kaganski 
CommitDate: Wed Mar 27 17:06:38 2024 +0100

tdf#160390: make sure to forward the iterator

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

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

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


core.git: sw/qa sw/source

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

New commits:
commit 8f2de92b3da99346f7282e623d47912f40f92b7b
Author: Michael Stahl 
AuthorDate: Fri Mar 22 12:28:43 2024 +0100
Commit: Michael Stahl 
CommitDate: Fri Mar 22 15:15:06 2024 +0100

sw: GetSelectableFromAny() broken for SwXTextRange

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

(regression from commit 635448a996714a81cb15b41ac4bb0c73cabfb74f)

Change-Id: I90dd7acbd259e8ca562a534ad0bc9a5b85356553
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165162
Reviewed-by: Noel Grandin 
Tested-by: Jenkins
Reviewed-by: Michael Stahl 

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


core.git: sw/qa sw/source

2024-03-21 Thread Justin Luth (via logerrit)
 sw/qa/extras/uiwriter/uiwriter7.cxx |5 +
 sw/source/core/crsr/findtxt.cxx |   19 +++
 2 files changed, 24 insertions(+)

New commits:
commit e830394c068c229bb840018f2f0e8810da6a1487
Author: Justin Luth 
AuthorDate: Tue Mar 19 15:28:32 2024 -0400
Commit: Miklos Vajna 
CommitDate: Thu Mar 21 10:59:23 2024 +0100

related tdf#147583 sw find: fix backwards search for string at end of para

Prior to this fix, it was finding every single character in the document
when searching for ".$".

Interestingly, the unit test worked even before the patch.
Not sure how that could be possible...

make CppunitTest_sw_uiwriter7 \
CPPUNIT_TEST_NAME=testTdf147583_backwardSearch

Change-Id: I20779898c01736eb39ecd7db7d66c2c24e4358b0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165037
Tested-by: Jenkins
Reviewed-by: Justin Luth 
Reviewed-by: Mike Kaganski 
Reviewed-by: Miklos Vajna 

diff --git a/sw/qa/extras/uiwriter/uiwriter7.cxx 
b/sw/qa/extras/uiwriter/uiwriter7.cxx
index bf9a4ee1bd1c..dda894b7fda5 100644
--- a/sw/qa/extras/uiwriter/uiwriter7.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter7.cxx
@@ -386,6 +386,11 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest7, 
testTdf147583_backwardSearch)
 xIndex.set(xSearch->findAll(xSearchDes), uno::UNO_SET_THROW);
 // should actually be 10 (including the empty para with the comment 
marker, and the last para)
 CPPUNIT_ASSERT_EQUAL(sal_Int32(8), xIndex->getCount());
+
+xSearchDes->setSearchString(".$"); // any last character (not just 
full-stops) in a paragraph
+xIndex.set(xSearch->findAll(xSearchDes), uno::UNO_SET_THROW);
+// should be one for every non-empty paragraph
+CPPUNIT_ASSERT_EQUAL(sal_Int32(14), xIndex->getCount());
 }
 
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest7, testTdf69282)
diff --git a/sw/source/core/crsr/findtxt.cxx b/sw/source/core/crsr/findtxt.cxx
index 930ac7926ce2..34d16d2a91b9 100644
--- a/sw/source/core/crsr/findtxt.cxx
+++ b/sw/source/core/crsr/findtxt.cxx
@@ -726,6 +726,25 @@ bool DoSearch(SwPaM & rSearchPam,
 SwTextNode const*const pNode, SwTextFrame const*const pFrame,
 SwRootFrame const*const pLayout, SwPaM& rPam)
 {
+if (bRegSearch && rSearchOpt.searchString.endsWith("$"))
+{
+bool bAlwaysSearchingForEndOfPara = true;
+sal_Int32 nIndex = 0;
+while ((nIndex = rSearchOpt.searchString.indexOf("|", nIndex)) != -1)
+{
+if (!nIndex || rSearchOpt.searchString[nIndex - 1] != '$')
+{
+bAlwaysSearchingForEndOfPara = false;
+break;
+}
+++nIndex;
+}
+// when searching for something at the end of the paragraph, the para 
end must be in range
+const AmbiguousIndex& rParaEnd = bSrchForward ? nEnd : nStart;
+if (bAlwaysSearchingForEndOfPara && nTextLen.GetAnyIndex() != 
rParaEnd.GetAnyIndex())
+return false;
+}
+
 bool bFound = false;
 OUString sCleanStr;
 std::vector aFltArr;


core.git: sw/qa sw/source

2024-03-20 Thread Justin Luth (via logerrit)
 sw/qa/extras/uiwriter/uiwriter9.cxx |   26 --
 sw/source/core/doc/docnum.cxx   |   11 ---
 sw/source/uibase/shells/txtnum.cxx  |1 -
 sw/source/uibase/wrtsh/wrtsh1.cxx   |   31 +--
 4 files changed, 25 insertions(+), 44 deletions(-)

New commits:
commit 91e5d1ef52964dc43875ed62acd766524fa7cc5c
Author: Justin Luth 
AuthorDate: Tue Mar 19 09:22:34 2024 -0400
Commit: Miklos Vajna 
CommitDate: Wed Mar 20 16:20:14 2024 +0100

tdf#159054 sw: fix .uno:DefaultNumber toggle on Heading numbering

This fixes a 7.2 regression from
commit c456f839a597f537f1c59becd7d0bb6c86248ef8
Author: Anshu on Wed Jan 6 15:04:16 2021 +0530
tdf#115965 tdf#92622 NoList default in menu,tool,sidebar

The current implementation would set the number format
to SVX_NUM_NUMBER_NONE, but it still looks like a number to the toolbar,
so toggling didn't work since 7.4's bcede3c0ed94d4
It also never cleared out the prefix/suffix when toggled off,
and it affected ALL paragraphs using that outline numbering style.

Remove numbering was doing the same kind of thing.

I think the toggle was trying to follow the drop-down behaviour
of modifying the outline numbering style itself.
While I think the drop-down handling could be considered appropriate,
using the toggle to pseudo-disable the entire style just seems wrong.

This patch kills that, and in addition
automatically gains all the nice undo/redo functionality.

This is one tiny step in making outline numbering go away.

make CppunitTest_sw_uiwriter9 \
CPPUNIT_TEST_NAME=testTdf159054_disableOutlineNumbering

Change-Id: Id6a24ac25479cb8f35bf1c2c58344390ed7512fe
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164985
Reviewed-by: Justin Luth 
Tested-by: Justin Luth 
Reviewed-by: Miklos Vajna 

diff --git a/sw/qa/extras/uiwriter/uiwriter9.cxx 
b/sw/qa/extras/uiwriter/uiwriter9.cxx
index a18f14c9ad9a..f46d43e537b6 100644
--- a/sw/qa/extras/uiwriter/uiwriter9.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter9.cxx
@@ -429,20 +429,26 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, 
testTdf159054_disableOutlineNumbering)
 dispatchCommand(mxComponent, ".uno:DefaultNumbering", {});
 
 // the selected paragraphs should definitely have the list label removed
-CPPUNIT_ASSERT_EQUAL(OUString("."), getProperty(xPara1, 
"ListLabelString"));
-CPPUNIT_ASSERT_EQUAL(OUString("."), getProperty(xPara2, 
"ListLabelString"));
-// current implementation: the numbering style itself is changed too - 
affects all Heading 1's.
-// A valid alternative implementation would be to simply 
SetCountInList(false) for 1st para,
-// and leave the Outline style format alone.
-CPPUNIT_ASSERT_EQUAL(OUString("."), getProperty(xPara3, 
"ListLabelString"));
+CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty(xPara1, 
"ListLabelString"));
+CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty(xPara2, 
"ListLabelString"));
+// the third paragraph must retain the existing numbering format
+CPPUNIT_ASSERT_EQUAL(OUString("A."), getProperty(xPara3, 
"ListLabelString"));
 
 // on the selection, simulate pressing the toolbar button to toggle ON 
numbering again
 dispatchCommand(mxComponent, ".uno:DefaultNumbering", {});
 
-// current implementation: the entire format was removed, so turn 
(default) numbering on
-CPPUNIT_ASSERT_EQUAL(OUString("."), getProperty(xPara1, 
"ListLabelString"));
-CPPUNIT_ASSERT_EQUAL(OUString("."), getProperty(xPara2, 
"ListLabelString"));
-CPPUNIT_ASSERT_EQUAL(OUString("."), getProperty(xPara3, 
"ListLabelString"));
+// the outline numbering format must be re-applied to the first two 
paragraphs
+CPPUNIT_ASSERT_EQUAL(OUString("A."), getProperty(xPara1, 
"ListLabelString"));
+CPPUNIT_ASSERT_EQUAL(OUString("B."), getProperty(xPara2, 
"ListLabelString"));
+CPPUNIT_ASSERT_EQUAL(OUString("C."), getProperty(xPara3, 
"ListLabelString"));
+
+// on the selection, simulate a right click - list - No list
+dispatchCommand(mxComponent, ".uno:RemoveBullets", {});
+
+// the selected paragraphs should definitely have the list label removed
+CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty(xPara1, 
"ListLabelString"));
+CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty(xPara2, 
"ListLabelString"));
+CPPUNIT_ASSERT_EQUAL(OUString("A."), getProperty(xPara3, 
"ListLabelString"));
 }
 
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf158375_dde_disable)
diff --git a/sw/source/core/doc/docnum.cxx b/sw/source/core/doc/docnum.cxx
index 1c7d1792abe5..73b04ad24122 100644
--- a/sw/source/core/doc/docnum.cxx
+++ b/sw/source/core/doc/docnum.cxx
@@ -1368,10 +1368,15 @@ void SwDoc::DelNumRules(const SwPaM& rPam, SwRootFrame 
const*const pLayout)
 {
 pTNd->ChkCondColl();
 }
-else if( !pOutlNd &&
- 

core.git: sw/qa sw/source

2024-03-18 Thread Justin Luth (via logerrit)
 sw/qa/extras/uiwriter/data/tdf147583_backwardSearch.odt |binary
 sw/qa/extras/uiwriter/uiwriter7.cxx |   31 +++
 sw/source/core/crsr/findtxt.cxx |   67 
 3 files changed, 66 insertions(+), 32 deletions(-)

New commits:
commit 8b58007fc5a619012b58a1f8d8731a753bc1c40d
Author: Justin Luth 
AuthorDate: Fri Mar 15 20:01:39 2024 -0400
Commit: Miklos Vajna 
CommitDate: Mon Mar 18 14:25:39 2024 +0100

tdf#147583 sw find: fix backwards search for emptyPara/endOfPara

A comment added 10 years ago thought that it had never worked.

The very last paragraph end cannot be selected manually,
and so of course it can't work in find either.
It didn't work earlier either.

Everything goes ballistic if searching inside comments,
but that would be handled elsewhere anyway I guess.
It didn't work earlier either.

Keeping the search "inside the selection" didn't work earlier either.
That should be fixed now.

make CppunitTest_sw_uiwriter7 \
CPPUNIT_TEST_NAME=testTdf147583_backwardSearch

Change-Id: I48a72084d277b8c270255de9296a2743162937cf
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164892
Tested-by: Jenkins
Reviewed-by: Justin Luth 
Reviewed-by: Miklos Vajna 

diff --git a/sw/qa/extras/uiwriter/data/tdf147583_backwardSearch.odt 
b/sw/qa/extras/uiwriter/data/tdf147583_backwardSearch.odt
new file mode 100644
index ..9bfde3bfaa6b
Binary files /dev/null and 
b/sw/qa/extras/uiwriter/data/tdf147583_backwardSearch.odt differ
diff --git a/sw/qa/extras/uiwriter/uiwriter7.cxx 
b/sw/qa/extras/uiwriter/uiwriter7.cxx
index fe873d8cfb3b..898ed6dcd1b5 100644
--- a/sw/qa/extras/uiwriter/uiwriter7.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter7.cxx
@@ -358,6 +358,37 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest7, testTextSearch)
  pCursor->GetPointNode().GetTextNode()->GetText());
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest7, testTdf147583_backwardSearch)
+{
+createSwDoc("tdf147583_backwardSearch.odt");
+uno::Reference xSearch(mxComponent, uno::UNO_QUERY);
+uno::Reference xSearchDes = 
xSearch->createSearchDescriptor();
+uno::Reference xProp(xSearchDes, uno::UNO_QUERY);
+
+uno::Reference xIndex;
+const sal_Int32 nParas = getParagraphs();
+
+//specifying the search attributes
+uno::Reference xPropSet(xSearchDes, 
uno::UNO_QUERY_THROW);
+xSearchDes->setPropertyValue("SearchRegularExpression", uno::Any(true)); 
// regex
+xSearchDes->setSearchString("$"); // the end of the paragraph pilcrow 
marker
+
+// xSearchDes->setPropertyValue("SearchBackwards", uno::Any(false));
+// xIndex.set(xSearch->findAll(xSearchDes), uno::UNO_SET_THROW);
+// // all paragraphs (including the unselected last one) should be found
+// CPPUNIT_ASSERT_EQUAL(nParas, xIndex->getCount());
+
+xSearchDes->setPropertyValue("SearchBackwards", uno::Any(true));
+xIndex.set(xSearch->findAll(xSearchDes), uno::UNO_SET_THROW);
+// all paragraphs (except the troublesome last one) are found
+CPPUNIT_ASSERT_EQUAL(nParas - 1, xIndex->getCount());
+
+xSearchDes->setSearchString("^$"); // empty paragraphs
+xIndex.set(xSearch->findAll(xSearchDes), uno::UNO_SET_THROW);
+// should actually be 10 (including the empty para with the comment 
marker, and the last para)
+CPPUNIT_ASSERT_EQUAL(sal_Int32(8), xIndex->getCount());
+}
+
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest7, testTdf69282)
 {
 createSwDoc();
diff --git a/sw/source/core/crsr/findtxt.cxx b/sw/source/core/crsr/findtxt.cxx
index 1edde20d7ccc..930ac7926ce2 100644
--- a/sw/source/core/crsr/findtxt.cxx
+++ b/sw/source/core/crsr/findtxt.cxx
@@ -727,7 +727,6 @@ bool DoSearch(SwPaM & rSearchPam,
 SwRootFrame const*const pLayout, SwPaM& rPam)
 {
 bool bFound = false;
-SwPosition& rPtPos = *rPam.GetPoint();
 OUString sCleanStr;
 std::vector aFltArr;
 LanguageType eLastLang = LANGUAGE_SYSTEM;
@@ -869,39 +868,43 @@ bool DoSearch(SwPaM & rSearchPam,
 
 if ( bFound )
 return true;
-else if ((bChkEmptyPara && !nStart.GetAnyIndex() && 
!nTextLen.GetAnyIndex())
- || bChkParaEnd)
+
+if (!bChkEmptyPara && !bChkParaEnd)
+return false;
+
+if (bChkEmptyPara && bSrchForward && nTextLen.GetAnyIndex())
+return false; // the length is not zero - there is content here
+
+// move to the end (or start) of the paragraph
+*rSearchPam.GetPoint() = *rPam.GetPoint();
+if (pLayout)
 {
-*rSearchPam.GetPoint() = *rPam.GetPoint();
-if (pLayout)
-{
-*rSearchPam.GetPoint() = pFrame->MapViewToModelPos(
-bChkParaEnd ? nTextLen.GetFrameIndex() : TextFrameIndex(0));
-}
-else
-{
-rSearchPam.GetPoint()->SetContent( bChkParaEnd ? 
nTextLen.GetModelIndex() : 0 );
-}
-rSearchPam.SetMark();
-const 

core.git: sw/qa sw/source

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

New commits:
commit 873af30a36504751c6923d4235abd4de040e0001
Author: Michael Stahl 
AuthorDate: Thu Mar 14 12:14:28 2024 +0100
Commit: Michael Stahl 
CommitDate: Thu Mar 14 14:16:08 2024 +0100

sw: fix ~SwIndexReg assert in testTdf149498

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

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

Change-Id: I75e271c84a6624ffb0df151b171acb1e1f743928
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164807
Tested-by: Jenkins
Reviewed-by: Michael Stahl 

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


core.git: sw/qa sw/source

2024-03-14 Thread Matt K (via logerrit)
 sw/qa/core/objectpositioning/data/tdf154863-img-move-crash.docx |binary
 sw/qa/core/objectpositioning/objectpositioning.cxx  |   14 
++
 sw/source/core/layout/tabfrm.cxx|1 
 3 files changed, 15 insertions(+)

New commits:
commit 1b5010bfb745a3a7f0e596b237ab70694484fc33
Author: Matt K 
AuthorDate: Fri Feb 2 10:35:13 2024 -0600
Commit: Miklos Vajna 
CommitDate: Thu Mar 14 08:25:09 2024 +0100

tdf#154863 Add unit test to cover crash on image move

This reverts commit 332faa63407305852f5044e4bbc41302ccfe46cd.

This change adds a CppUnit test that changes the position
of an image in an example document which causes a crash
if the bug exists.

This also adds a delete guard for a SwFrame used to
prevent a use-after-free condition.

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

diff --git a/sw/qa/core/objectpositioning/data/tdf154863-img-move-crash.docx 
b/sw/qa/core/objectpositioning/data/tdf154863-img-move-crash.docx
new file mode 100644
index ..ca402edef74d
Binary files /dev/null and 
b/sw/qa/core/objectpositioning/data/tdf154863-img-move-crash.docx differ
diff --git a/sw/qa/core/objectpositioning/objectpositioning.cxx 
b/sw/qa/core/objectpositioning/objectpositioning.cxx
index bf560cbdaf90..717d63ded052 100644
--- a/sw/qa/core/objectpositioning/objectpositioning.cxx
+++ b/sw/qa/core/objectpositioning/objectpositioning.cxx
@@ -25,6 +25,8 @@
 #include 
 #include 
 
+#include 
+
 namespace
 {
 /// Covers sw/source/core/objectpositioning/ fixes.
@@ -56,6 +58,18 @@ CPPUNIT_TEST_FIXTURE(Test, testOverlapCrash)
 pWrtShell->SplitNode();
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testImgMoveCrash)
+{
+createSwDoc("tdf154863-img-move-crash.docx");
+uno::Reference xShape(getShapeByName(u"Image26"), 
uno::UNO_QUERY);
+uno::Reference xShapeProps(xShape, uno::UNO_QUERY);
+xShapeProps->setPropertyValue("VertOrient", 
uno::Any(static_cast(0)));
+xShapeProps->setPropertyValue("VertOrientPosition", 
uno::Any(static_cast(3000)));
+Scheduler::ProcessEventsToIdle();
+// Crash expected before assert if bug exists
+CPPUNIT_ASSERT(true);
+}
+
 CPPUNIT_TEST_FIXTURE(Test, testVertPosFromBottom)
 {
 // Create a document, insert a shape and position it 1cm above the bottom 
of the body area.
diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index edb10beb35c6..cd44758e574b 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -1754,6 +1754,7 @@ bool SwContentFrame::CalcLowers(SwLayoutFrame & rLay, 
SwLayoutFrame const& rDont
 {
 // #i23129#, #i36347# - pass correct page frame to
 // the object formatter
+SwFrameDeleteGuard aDeleteGuard(pCnt);
 if ( !SwObjectFormatter::FormatObjsAtFrame( *pCnt,
   
*(pCnt->FindPageFrame()) ) )
 {


core.git: sw/qa sw/source

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

New commits:
commit 7335babda93974104a39202c434e9499b8086f3a
Author: Michael Stahl 
AuthorDate: Wed Mar 13 09:38:00 2024 +0100
Commit: Michael Stahl 
CommitDate: Wed Mar 13 13:34:19 2024 +0100

sw: layout: use page style set on hidden paragraph

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

(regression from commit 0c96119895b347f8eb5bb89f393351bd3c02b9f1)

Change-Id: Iad5e76f5cc437d35b4ae9bde6bc9b73dbe32bf3d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164761
Tested-by: Jenkins
Reviewed-by: Michael Stahl 

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

   
-  
+  

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


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

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

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


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

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

core.git: sw/qa sw/source

2024-03-06 Thread Miklos Vajna (via logerrit)
 sw/qa/uibase/dochdl/dochdl.cxx   |   26 ++
 sw/source/uibase/dochdl/swdtflvr.cxx |9 +
 2 files changed, 35 insertions(+)

New commits:
commit 1bca99617ad54d966625caadd71e52134c70ae44
Author: Miklos Vajna 
AuthorDate: Wed Mar 6 11:03:20 2024 +0100
Commit: Miklos Vajna 
CommitDate: Wed Mar 6 16:11:22 2024 +0100

cool#8465 sw lok: classify anchored images as complex selection

Regression from commit 7a8dc25defee31edbb75a2f8c35f92ee2d3f3a83 (sw lok:
simplify SwTransferable::isComplex(), 2021-02-23), in case as-char
imagse were part of a selection, we considered that complex, but at-char
was considered as simple, which is inconsistent.

This was not intentional, simply the rework to avoid copying the
selection to a temporary document lost this functionality.

Fix the problem by using CollectFrameAtNode() to find at-char images,
which tries to use the layout, so is not meant to be too slow.

An alternative would be sw::GetFlysAnchoredAt(), but that doesn't try to
use the layout, so avoid that.

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

diff --git a/sw/qa/uibase/dochdl/dochdl.cxx b/sw/qa/uibase/dochdl/dochdl.cxx
index 95314b48be1f..2c209a65d3d9 100644
--- a/sw/qa/uibase/dochdl/dochdl.cxx
+++ b/sw/qa/uibase/dochdl/dochdl.cxx
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /// Covers sw/source/uibase/dochdl/ fixes.
 class SwUibaseDochdlTest : public SwModelTestBase
@@ -76,6 +77,31 @@ CPPUNIT_TEST_FIXTURE(SwUibaseDochdlTest, 
testComplexSelection)
 CPPUNIT_ASSERT(!xTransfer->isComplex());
 }
 
+CPPUNIT_TEST_FIXTURE(SwUibaseDochdlTest, testComplexSelectionAtChar)
+{
+// Given a document with an at-char anchored image:
+createSwDoc();
+SwDoc* pDoc = getSwDoc();
+SwDocShell* pDocShell = pDoc->GetDocShell();
+SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
+SfxItemSet aFrameSet(pDoc->GetAttrPool(), svl::Items);
+SwFormatAnchor aAnchor(RndStdIds::FLY_AT_CHAR);
+aFrameSet.Put(aAnchor);
+Graphic aGrf;
+pWrtShell->SwFEShell::Insert(OUString(), OUString(), , );
+pWrtShell->UnSelectFrame();
+
+// When checking if the selection is simple or complex:
+pWrtShell->SelAll();
+uno::Reference xTransfer = new 
SwTransferable(*pWrtShell);
+bool bComplex = xTransfer->isComplex();
+
+// Then make sure it's complex:
+// Without the accompanying fix in place, this test would have failed, a 
selection containing an
+// image was considered simple.
+CPPUNIT_ASSERT(bComplex);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/dochdl/swdtflvr.cxx 
b/sw/source/uibase/dochdl/swdtflvr.cxx
index cb8748a73cd0..a862c7dd90b8 100644
--- a/sw/source/uibase/dochdl/swdtflvr.cxx
+++ b/sw/source/uibase/dochdl/swdtflvr.cxx
@@ -122,6 +122,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -459,6 +460,14 @@ sal_Bool SAL_CALL SwTransferable::isComplex()
 }
 }
 
+FrameClientSortList_t vFrames;
+::CollectFrameAtNode(rNd, vFrames, true);
+if (!vFrames.empty())
+{
+// There is an at-char anchored object to this node, 
that's complex.
+return true;
+}
+
 nTextLength += pTextNode->GetText().getLength();
 if (nTextLength >= 1024 * 512)
 return true; // Complex


core.git: sw/qa sw/source

2024-03-06 Thread Justin Luth (via logerrit)
 sw/qa/extras/ww8export/data/tdf160049_anchorMargin.doc |binary
 sw/qa/extras/ww8export/ww8export4.cxx  |   10 ++
 sw/source/filter/ww8/ww8graf.cxx   |6 ++
 3 files changed, 16 insertions(+)

New commits:
commit 3aeaee800f675a5f733e06bb4ea73909570f9004
Author: Justin Luth 
AuthorDate: Tue Mar 5 19:43:51 2024 -0500
Commit: Miklos Vajna 
CommitDate: Wed Mar 6 11:27:04 2024 +0100

tdf#160049 doc import: use margins with left/right HoriOrientRelation

No interesting existing unit tests.

make CppunitTest_sw_ww8export4 \
CPPUNIT_TEST_NAME=testTdf160049_anchorMargin

Change-Id: Ib855d9f35db9e0f47aff18400b69a990cd1ad5ca
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/16
Tested-by: Jenkins
Reviewed-by: Justin Luth 
Reviewed-by: Miklos Vajna 

diff --git a/sw/qa/extras/ww8export/data/tdf160049_anchorMargin.doc 
b/sw/qa/extras/ww8export/data/tdf160049_anchorMargin.doc
new file mode 100644
index ..d1082515fd9c
Binary files /dev/null and 
b/sw/qa/extras/ww8export/data/tdf160049_anchorMargin.doc differ
diff --git a/sw/qa/extras/ww8export/ww8export4.cxx 
b/sw/qa/extras/ww8export/ww8export4.cxx
index ea50ed2a19b9..7ab6f76ec3a6 100644
--- a/sw/qa/extras/ww8export/ww8export4.cxx
+++ b/sw/qa/extras/ww8export/ww8export4.cxx
@@ -51,6 +51,16 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf77964)
 CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AS_CHARACTER, 
getProperty(getShapeByName(u"Image2"), 
"AnchorType"));
 }
 
+DECLARE_WW8EXPORT_TEST(testTdf160049_anchorMargin, 
"tdf160049_anchorMargin.doc")
+{
+// given a document with a LEFT "column/text" anchored image
+
+// The image takes into account the margin, so it looks like it is in the 
middle of the doc,
+// which is "Paragraph text area"/PRINT_AREA/1, not "Entire paragraph 
area"/FRAME/0
+CPPUNIT_ASSERT_EQUAL(css::text::RelOrientation::PRINT_AREA,
+ getProperty(getShape(1), 
"HoriOrientRelation"));
+}
+
 DECLARE_WW8EXPORT_TEST(testTdf150197_anlv2ListFormat, 
"tdf150197_anlv2ListFormat.doc")
 {
 CPPUNIT_ASSERT_EQUAL(OUString("1."), 
getProperty(getParagraph(2), "ListLabelString"));
diff --git a/sw/source/filter/ww8/ww8graf.cxx b/sw/source/filter/ww8/ww8graf.cxx
index a7c9ec979e09..28b1211683d1 100644
--- a/sw/source/filter/ww8/ww8graf.cxx
+++ b/sw/source/filter/ww8/ww8graf.cxx
@@ -2400,6 +2400,12 @@ RndStdIds 
SwWW8ImplReader::ProcessEscherAlign(SvxMSDffImportRec& rRecord, WW8_FS
 rFSPA.nXaLeft = 0;
 rFSPA.nXaRight = nWidth;
 }
+else if ((eHoriOri == text::HoriOrientation::LEFT || eHoriOri == 
text::HoriOrientation::RIGHT)
+ && eHoriRel == text::RelOrientation::FRAME)
+{
+// relative left/right honors paragraph margins, but not with center 
or none/absolute offset
+eHoriRel = text::RelOrientation::PRINT_AREA;
+}
 
 // #i24255# - position of floating screen objects in
 // R2L layout are given in L2R layout, thus convert them of all


core.git: sw/qa sw/source

2024-03-04 Thread Mike Kaganski (via logerrit)
 sw/qa/extras/htmlexport/data/char_border_and_font_color.fodt |   14 
 sw/qa/extras/htmlexport/htmlexport.cxx   |   21 
 sw/source/filter/html/css1atr.cxx|6 
 sw/source/filter/html/htmlatr.cxx|  409 ---
 4 files changed, 223 insertions(+), 227 deletions(-)

New commits:
commit 6d797c83d9fb891b783de39646b42d34a895c81e
Author: Mike Kaganski 
AuthorDate: Mon Mar 4 12:20:13 2024 +0600
Commit: Mike Kaganski 
CommitDate: Mon Mar 4 13:26:06 2024 +0100

tdf160017: make sure to emit the closing tags in correct order

This reimplements how the starts and ends of attributes are stored in
HTMLEndPosLst. Instead of a plain list, now it is a sorted map, with
positions as keys, and a vector of HTMLStartEndPos* as values.

In commit b94b1fe936ddc4a9b86fbeb9c9c6ab0fca52f0bc (CharBrd 9.1: HTML
filters, 2013-09-08), the character borders attributes started to be
set in a special order, in front of the position's other attributes,
to allow merging them. But that created a problem of knowing in which
order to close respective tags.

The change here sorts the closing tags for the current node only when
writing them. At this point, it is possible to consider the opening
positions correctly.

Change-Id: I466ffa1c0eb28874ded003035e0cf772e31585b3
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164325
Tested-by: Jenkins
Reviewed-by: Mike Kaganski 

diff --git a/sw/qa/extras/htmlexport/data/char_border_and_font_color.fodt 
b/sw/qa/extras/htmlexport/data/char_border_and_font_color.fodt
new file mode 100644
index ..bda2ec63133c
--- /dev/null
+++ b/sw/qa/extras/htmlexport/data/char_border_and_font_color.fodt
@@ -0,0 +1,14 @@
+
+
+
+ 
+  
+   
+  
+ 
+ 
+  
+   foo
+  
+ 
+
\ No newline at end of file
diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx 
b/sw/qa/extras/htmlexport/htmlexport.cxx
index fcb60925488c..45eb06130d3e 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -3017,6 +3017,27 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, 
testReqIF_NoBrClearForImageWrap)
 0);
 }
 
+CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testReqIF_Tdf160017_spanClosingOrder)
+{
+// Given a document with a paragraph having explicit font color and 
character border properties:
+createSwDoc("char_border_and_font_color.fodt");
+// When exporting to reqif:
+ExportToReqif();
+// Without the fix, this would fail, because there was an extra closing 

+WrapReqifFromTempFile();
+}
+
+CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testHTML_Tdf160017_spanClosingOrder)
+{
+// Given a document with a paragraph having explicit font color and 
character border properties:
+createSwDoc("char_border_and_font_color.fodt");
+// When exporting to HTML:
+ExportToHTML();
+// Parse it as XML (strict!)
+// Without the fix, this would fail, because span and font elements closed 
in wrong order
+CPPUNIT_ASSERT(parseXml(maTempFile));
+}
+
 } // end of anonymous namespace
 CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/sw/source/filter/html/css1atr.cxx 
b/sw/source/filter/html/css1atr.cxx
index a07b0c9ce8d9..48badab293dd 100644
--- a/sw/source/filter/html/css1atr.cxx
+++ b/sw/source/filter/html/css1atr.cxx
@@ -3301,14 +3301,16 @@ SwHTMLWriter& OutCSS1_SvxBox( SwHTMLWriter& rWrt, const 
SfxPoolItem& rHt )
 
 if( rHt.Which() == RES_CHRATR_BOX )
 {
+constexpr std::string_view inline_block("inline-block");
 if( rWrt.m_bTagOn )
 {
 // Inline-block to make the line height changing correspond to the 
character border
-rWrt.OutCSS1_PropertyAscii(sCSS1_P_display, "inline-block");
+rWrt.OutCSS1_PropertyAscii(sCSS1_P_display, inline_block);
 }
 else
 {
-HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), 
Concat2View(rWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_span), false );
+if (!IgnorePropertyForReqIF(rWrt.mbReqIF, sCSS1_P_display, 
inline_block))
+HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), 
Concat2View(rWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_span), false );
 return rWrt;
 }
 }
diff --git a/sw/source/filter/html/htmlatr.cxx 
b/sw/source/filter/html/htmlatr.cxx
index 9f67d1ee0304..c880082018f1 100644
--- a/sw/source/filter/html/htmlatr.cxx
+++ b/sw/source/filter/html/htmlatr.cxx
@@ -1058,7 +1058,7 @@ public:
 
 HTMLStartEndPos( const SfxPoolItem& rItem, sal_Int32 nStt, sal_Int32 nE );
 
-const SfxPoolItem* GetItem() const { return m_pItem.get(); }
+const SfxPoolItem& GetItem() const { return *m_pItem; }
 
 void SetStart(sal_Int32 nStt) { m_nStart = nStt; }
 sal_Int32 GetStart() const { return m_nStart; }
@@ -1075,7 +1075,7 @@ HTMLStartEndPos::HTMLStartEndPos(const SfxPoolItem& 
rItem, sal_Int32 nStt, sal_I
 , 

core.git: sw/qa sw/source

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

New commits:
commit 186de7178c6065e1de13fd216b46ac9b716e44c5
Author: Miklos Vajna 
AuthorDate: Thu Feb 29 08:17:41 2024 +0100
Commit: Miklos Vajna 
CommitDate: Thu Feb 29 11:39:54 2024 +0100

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

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

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

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

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

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

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

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

2024-02-28 Thread Miklos Vajna (via logerrit)
 sw/qa/extras/rtfexport/data/listWithLgl.rtf |   23 +
 sw/qa/extras/rtfexport/rtfexport3.cxx   |   26 
 sw/source/filter/ww8/rtfattributeoutput.cxx |7 +-
 writerfilter/source/rtftok/rtfcontrolwords.cxx  |2 -
 writerfilter/source/rtftok/rtfdispatchvalue.cxx |3 ++
 5 files changed, 59 insertions(+), 2 deletions(-)

New commits:
commit e8487bedb20a429565b4a0e4bd2d6806cc603b7f
Author: Miklos Vajna 
AuthorDate: Wed Feb 28 08:34:02 2024 +0100
Commit: Miklos Vajna 
CommitDate: Wed Feb 28 09:58:29 2024 +0100

Related: tdf#150408 RTF filter: handle legal numbering

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

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

Fix the problem by extending RTFDocumentImpl::dispatchTableSprmValue()
for the numbering table import + RtfAttributeOutput::NumberingLevel()
for the export.

The import default for this value was also wrong, given that the default
is to enable it when the control word is present.

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

diff --git a/sw/qa/extras/rtfexport/data/listWithLgl.rtf 
b/sw/qa/extras/rtfexport/data/listWithLgl.rtf
new file mode 100644
index ..4355049eb3dc
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/listWithLgl.rtf
@@ -0,0 +1,23 @@
+{ tf1
+{\*\listtable
+{\list\listtemplateid197063698
+{\listlevel\levelnfc1\levelnfcn1\leveljc0\leveljcn0\levelfollow2\levelstartat1\levelspace0\levelindent0
+{\leveltext\'04CH \'00;}
+{\levelnumbers\'04;}
+ tlchcs1 f0 \ltrchcs0 \s15i0\li0\lin0 }
+{\listlevel\levelnfc22\levelnfcn22\leveljc0\leveljcn0\levelfollow0\levelstartat1\levellegal\levelspace0\levelindent0
+{\leveltext\'08Sect \'00.\'01;}
+{\levelnumbers
+\'06\'08;}
+ tlchcs1 f0 \ltrchcs0 \s16i720\li0\jclisttab   x2160\lin0 }
+\listid1297755732}
+}
+{\*\listoverridetable
+{\listoverride\listid1297755732\listoverridecount0\ls1}
+}
+\paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440
+\pard\plain\ls1\par
+\pard\plaini720   x2160\ls1\ilvl1 Foo\par
+\pard\plain\ls1\par
+\pard\plaini720   x2160\ls1\ilvl1 Bar\par
+}
diff --git a/sw/qa/extras/rtfexport/rtfexport3.cxx 
b/sw/qa/extras/rtfexport/rtfexport3.cxx
index e88461102dfb..263af642b39f 100644
--- a/sw/qa/extras/rtfexport/rtfexport3.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport3.cxx
@@ -718,6 +718,32 @@ DECLARE_RTFEXPORT_TEST(testTdf158409, "tdf158409.rtf")
 CPPUNIT_ASSERT_EQUAL(8.0, getProperty(xRun, "CharHeight"));
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testLegalNumbering)
+{
+auto verify = [this]() {
+// Second level's numbering should use Arabic numbers for first level 
reference
+auto xPara = getParagraph(1);
+CPPUNIT_ASSERT_EQUAL(OUString("CH I"), getProperty(xPara, 
"ListLabelString"));
+xPara = getParagraph(2);
+// Without the accompanying fix in place, this test would have failed 
with:
+// - Expected: Sect 1.01
+// - Actual  : Sect I.01
+// i.e. \levellegal was ignored on import/export.
+CPPUNIT_ASSERT_EQUAL(OUString("Sect 1.01"),
+ getProperty(xPara, "ListLabelString"));
+xPara = getParagraph(3);
+CPPUNIT_ASSERT_EQUAL(OUString("CH II"), getProperty(xPara, 
"ListLabelString"));
+xPara = getParagraph(4);
+CPPUNIT_ASSERT_EQUAL(OUString("Sect 2.01"),
+ getProperty(xPara, "ListLabelString"));
+};
+
+createSwDoc("listWithLgl.rtf");
+verify();
+saveAndReload(mpFilter);
+verify();
+}
+
 } // end of anonymous namespace
 CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx 
b/sw/source/filter/ww8/rtfattributeoutput.cxx
index 36bb03149c06..b996446b01eb 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -1632,7 +1632,7 @@ void RtfAttributeOutput::NumberingLevel(sal_uInt8 nLevel, 
sal_uInt16 nStart,
 const wwFont* pFont, const SfxItemSet* 
pOutSet,
 sal_Int16 nIndentAt, sal_Int16 
nFirstLineIndex,
 sal_Int16 /*nListTabPos*/, const 
OUString& rNumberingString,
-const SvxBrushItem* pBrush, bool 
/*isLegal*/)
+const SvxBrushItem* pBrush, bool 
isLegal)
 {
 m_rExport.Strm().WriteOString(SAL_NEWLINE_STRING);
 if (nLevel > 8) // RTF knows only 9 levels
@@ -1771,6 +1771,11 @@ void RtfAttributeOutput::NumberingLevel(sal_uInt8 
nLevel, sal_uInt16 nStart,
 

core.git: sw/qa sw/source

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

New commits:
commit a73b3994fb6a2cc10b2d65cbaad201762610cecc
Author: Miklos Vajna 
AuthorDate: Tue Feb 27 08:29:31 2024 +0100
Commit: Miklos Vajna 
CommitDate: Tue Feb 27 09:39:12 2024 +0100

Related: tdf#150408 DOC filter: handle legal numbering

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

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

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

RTF still needs doing.

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

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


core.git: sw/qa sw/source

2024-02-26 Thread Justin Luth (via logerrit)
 sw/qa/extras/ww8export/ww8export3.cxx |7 +++
 sw/source/filter/ww8/wrtw8esh.cxx |5 +++--
 2 files changed, 10 insertions(+), 2 deletions(-)

New commits:
commit 589ac948c0650a16c734db7337c6c31b950be151
Author: Justin Luth 
AuthorDate: Mon Feb 26 09:56:11 2024 -0500
Commit: Justin Luth 
CommitDate: Mon Feb 26 17:16:55 2024 +0100

related tdf#126533 doc export: don't lose "tiled" aspect of image fill.

This affects patterns as well as textures/images.

make CppunitTest_sw_ww8export3 
CPPUNIT_TEST_NAME=testTdf101826_xattrTextBoxFill

Change-Id: I2742a6f333fc6688b3570772a1dbc8371741f210
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163948
Tested-by: Jenkins
Reviewed-by: Justin Luth 

diff --git a/sw/qa/extras/ww8export/ww8export3.cxx 
b/sw/qa/extras/ww8export/ww8export3.cxx
index 97ea979d01e8..66c5ae5c471c 100644
--- a/sw/qa/extras/ww8export/ww8export3.cxx
+++ b/sw/qa/extras/ww8export/ww8export3.cxx
@@ -11,6 +11,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -621,6 +622,12 @@ DECLARE_WW8EXPORT_TEST(testTdf101826_xattrTextBoxFill, 
"tdf101826_xattrTextBoxFi
 CPPUNIT_ASSERT_MESSAGE("background color", Color(0xFF, 0xFF, 0x00) != 
getProperty(getShape(4), "BackColor"));
 //Basic Picture Fill: Tux image
 CPPUNIT_ASSERT_EQUAL_MESSAGE("background image", 
drawing::FillStyle_BITMAP, getProperty(getShape(5), 
"FillStyle"));
+// Basic Pattern fill: many thin, green, vertical stripes on yellow 
background
+auto eMode = getProperty(getShapeByName(u"Frame2"), 
"FillBitmapMode");
+CPPUNIT_ASSERT_EQUAL_MESSAGE("tiled pattern", drawing::BitmapMode_REPEAT, 
eMode);
+// Basic Texture fill: tiled blue denim texture
+eMode = getProperty(getShapeByName(u"Frame6"), 
"FillBitmapMode");
+CPPUNIT_ASSERT_EQUAL_MESSAGE("tiled texture", drawing::BitmapMode_REPEAT, 
eMode);
 }
 
 DECLARE_WW8EXPORT_TEST(testTdf123433_fillStyleStop, 
"tdf123433_fillStyleStop.doc")
diff --git a/sw/source/filter/ww8/wrtw8esh.cxx 
b/sw/source/filter/ww8/wrtw8esh.cxx
index 7931387e32fa..55c140e2a7c9 100644
--- a/sw/source/filter/ww8/wrtw8esh.cxx
+++ b/sw/source/filter/ww8/wrtw8esh.cxx
@@ -1849,8 +1849,9 @@ void SwBasicEscherEx::WriteBrushAttr(const SvxBrushItem 
,
 nOpaque = 255 - pGraphicObject->GetAttr().GetAlpha();
 if (0 != nOpaque)
 bSetOpacity = true;
-
-rPropOpt.AddOpt( ESCHER_Prop_fillType, ESCHER_FillPicture );
+const ESCHER_FillStyle eFillType
+= rBrush.GetGraphicPos() == GPOS_TILED ? ESCHER_FillTexture : 
ESCHER_FillPicture;
+rPropOpt.AddOpt(ESCHER_Prop_fillType, eFillType);
 rPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x140014 );
 rPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0 );
 }


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

2024-02-23 Thread Justin Luth (via logerrit)
 sw/qa/extras/rtfexport/data/tdf159824_gradientAngle1.rtf |   17 
 sw/qa/extras/rtfexport/data/tdf159824_gradientAngle2.rtf |   17 
 sw/qa/extras/rtfexport/rtfexport8.cxx|   57 +--
 sw/source/filter/ww8/rtfattributeoutput.cxx  |9 ++
 writerfilter/source/rtftok/rtfsdrimport.cxx  |4 +
 5 files changed, 97 insertions(+), 7 deletions(-)

New commits:
commit 695f8fb19d839efe03a402d2a7e7ef73b6d8f436
Author: Justin Luth 
AuthorDate: Wed Feb 21 16:37:31 2024 -0500
Commit: Justin Luth 
CommitDate: Fri Feb 23 20:28:05 2024 +0100

related tdf#159824 RTF import/export gradient angle

The fillAngle is important for obvious visual reasons,
but also significantly because a negative angle
means that the start/end colors should be swapped
(which is the normal case since
LO's 0 degree angle == -180 VML/RTF angle).

There were no existing unit tests with a "fillAngle" specified,
or with a non-180 angle (0 VML/RTF angle) in LO.

make CppunitTest_sw_rtfexport8 \
CPPUNIT_TEST_NAME=testTdf159824_gradientAngle1
make CppunitTest_sw_rtfexport8 \
CPPUNIT_TEST_NAME=testTdf159824_gradientAngle2
make CppunitTest_sw_rtfexport8 \
CPPUNIT_TEST_NAME=testTdf159824_axialGradient

Change-Id: I4bb2c47bd2a79833d11bedac72ba2152b65b7c73
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163714
Tested-by: Jenkins
Reviewed-by: Justin Luth 

diff --git a/sw/qa/extras/rtfexport/data/tdf159824_gradientAngle1.rtf 
b/sw/qa/extras/rtfexport/data/tdf159824_gradientAngle1.rtf
new file mode 100644
index ..37fd8ae2e339
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/tdf159824_gradientAngle1.rtf
@@ -0,0 +1,17 @@
+{ tf1nsi\deff3deflang1025
+
+\landscape\paperh5940\paperw8391
+
+{
+\shp{\*\shpinst\shptop382\shpbottom2737\shpleft759\shpright5064
+{\sp{\sn shapeType}{\sv 202}}
+{\sp{\sn fillType}{\sv 7}}
+{\sp{\sn fillAngle}{\sv 6}}
+{\sp{\sn fillFocus}{\sv 0}}
+{\sp{\sn fillColor}{\sv 1758337}}
+{\sp{\sn fillBackColor}{\sv 16777215}}
+
+{\shptxt\par \pard}}
+}
+
+\par }
diff --git a/sw/qa/extras/rtfexport/data/tdf159824_gradientAngle2.rtf 
b/sw/qa/extras/rtfexport/data/tdf159824_gradientAngle2.rtf
new file mode 100644
index ..223864f3281b
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/tdf159824_gradientAngle2.rtf
@@ -0,0 +1,17 @@
+{ tf1nsi\deff3deflang1025
+
+\landscape\paperh5940\paperw8391
+
+{
+\shp{\*\shpinst\shptop382\shpbottom2737\shpleft759\shpright5064
+{\sp{\sn shapeType}{\sv 202}}
+{\sp{\sn fillType}{\sv 7}}
+{\sp{\sn fillAngle}{\sv -12}}
+{\sp{\sn fillFocus}{\sv 0}}
+{\sp{\sn fillColor}{\sv 1758337}}
+{\sp{\sn fillBackColor}{\sv 16777215}}
+
+{\shptxt\par \pard}}
+}
+
+\par }
diff --git a/sw/qa/extras/rtfexport/rtfexport8.cxx 
b/sw/qa/extras/rtfexport/rtfexport8.cxx
index ab787919dfa9..c0b8cbad9a0a 100644
--- a/sw/qa/extras/rtfexport/rtfexport8.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport8.cxx
@@ -195,8 +195,8 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf159824_axialGradient)
  getProperty(xFrame, "FillStyle"));
 awt::Gradient2 aGradient = getProperty(xFrame, 
"FillGradient");
 
-//const Color aColA(0x127622); // green
-//const Color aColB(0xff); // white
+const Color aColA(0x127622); // green
+const Color aColB(0xff); // white
 
 // MCGR: Use the completely imported transparency gradient to check for 
correctness
 basegfx::BColorStops aColorStops = 
model::gradient::getColorStopsFromUno(aGradient.ColorStops);
@@ -205,11 +205,54 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf159824_axialGradient)
 CPPUNIT_ASSERT_EQUAL(size_t(3), aColorStops.size());
 CPPUNIT_ASSERT_EQUAL(awt::GradientStyle_LINEAR, aGradient.Style);
 CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[0].getStopOffset(), 
0.0));
-//CPPUNIT_ASSERT_EQUAL(aColB, Color(aColorStops[0].getStopColor()));
-// CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[1].getStopOffset(), 
0.5));
-// CPPUNIT_ASSERT_EQUAL(aColA, Color(aColorStops[1].getStopColor()));
-// CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[2].getStopOffset(), 
1.0));
-// CPPUNIT_ASSERT_EQUAL(aColB, Color(aColorStops[2].getStopColor()));
+CPPUNIT_ASSERT_EQUAL(aColB, Color(aColorStops[0].getStopColor()));
+CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[1].getStopOffset(), 
0.5));
+CPPUNIT_ASSERT_EQUAL(aColA, Color(aColorStops[1].getStopColor()));
+CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[2].getStopOffset(), 
1.0));
+CPPUNIT_ASSERT_EQUAL(aColB, Color(aColorStops[2].getStopColor()));
+}
+
+DECLARE_RTFEXPORT_TEST(testTdf159824_gradientAngle1, 
"tdf159824_gradientAngle1.rtf")
+{
+// given a frame with a white (top) to lime (bottom) linear gradient at an 
RTF 1° angle
+uno::Reference xTextFramesSupplier(mxComponent, 
uno::UNO_QUERY);
+uno::Reference 
xIndexAccess(xTextFramesSupplier->getTextFrames(),
+   

core.git: sw/qa sw/source

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

New commits:
commit 9ba68c769d41d1075152a22bf37e78fb9320317b
Author: Justin Luth 
AuthorDate: Wed Feb 21 11:52:36 2024 -0500
Commit: Miklos Vajna 
CommitDate: Fri Feb 23 11:01:19 2024 +0100

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

This fixes alg's 7.6 regression from
commit bb198176684c3d9377e26c04a29ec66deb811949

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

make CppunitTest_sw_rtfexport \
CPPUNIT_TEST_NAME=testTdf159824_axialGradient

Change-Id: I220f1bf689b4b219bc0ae187e95aedb1a29a7233
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163705
Tested-by: Jenkins
Reviewed-by: Justin Luth 
Reviewed-by: Miklos Vajna 

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


core.git: sw/qa sw/source

2024-02-23 Thread Justin Luth (via logerrit)
 sw/qa/extras/ooxmlexport/ooxmlexport7.cxx|3 --
 sw/source/filter/ww8/docxattributeoutput.cxx |   32 +--
 2 files changed, 25 insertions(+), 10 deletions(-)

New commits:
commit b8071eef3b40c9fb2b161901aba9d9105317441f
Author: Justin Luth 
AuthorDate: Tue Feb 20 22:41:22 2024 -0500
Commit: Miklos Vajna 
CommitDate: Fri Feb 23 10:58:18 2024 +0100

related tdf#126533 vml export: fix axial colors

This is a follow-up from the earlier tdf#65295 clone
which removed swapping colors on IMport for axials.
Well, tdf#65295 had also removed EXport swap for the linear case,
so, now that import doesn't swap, remove the axial export swap too.

Additionally, some linear gradients are actually axials,
so identify those symmetrical gradients that have
identical start/end colors to avoid exporting as a "solid" color.

[I tried changing the import to detect it was an axial,
 but got RTF export failures, chart2 false positives,
 and unit-test-the-implementation failures.]

make CppunitTest_sw_ooxmlexport7 \
CPPUNIT_TEST_NAME=testTdf126533_negativeAxialAngle

The only other unit test that hit this code was
textframe-gradient.docx - which is dominated by DML import/export.
I can see with Word 2003 that this patch fixes the VML export
for this unit test file also.

Change-Id: I75e993c7c127a861617b14072a98778ddde03a08
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163676
Tested-by: Justin Luth 
Reviewed-by: Justin Luth 

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx
index ef4bcb2d..a362cb36c221 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx
@@ -642,9 +642,6 @@ DECLARE_OOXMLEXPORT_TEST(testTdf77219_backgroundShape, 
"tdf77219_backgroundShape
 
 DECLARE_OOXMLEXPORT_TEST(testTdf126533_negativeAxialAngle, 
"tdf126533_negativeAxialAngle.docx")
 {
-if (isExported())
-return;
-
 // axiel gradient is purple foreground/lime background in the middle 
(top-left to bottom-right)
 uno::Reference 
xPageStyle(getStyles("PageStyles")->getByName("Standard"),
uno::UNO_QUERY);
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index 787908091589..8f4c8fb3dcb7 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -9648,16 +9648,34 @@ void DocxAttributeOutput::FormatFillGradient( const 
XFillGradientItem& rFillGrad
 switch (rGradient.GetGradientStyle())
 {
 case css::awt::GradientStyle_AXIAL:
-AddToAttrList(m_rExport.SdrExporter().getFlyFillAttrList(), 
XML_type, "gradient");
-AddToAttrList( m_rExport.SdrExporter().getFlyFillAttrList(), 
XML_focus, "50%" );
-// If it is an 'axial' gradient - swap the colors
-// (because in the import process they were imported swapped)
-sColor1 = sEndColor;
-sColor2 = sStartColor;
-break;
 case css::awt::GradientStyle_LINEAR:
+{
+bool bIsSymmetrical = rGradient.GetGradientStyle() == 
css::awt::GradientStyle_AXIAL;
+if (!bIsSymmetrical)
+{
+const basegfx::BColorStops& rColorStops = 
rGradient.GetColorStops();
+if (rColorStops.size() > 2 && rColorStops.isSymmetrical())
+{
+for (auto& rStop : rColorStops)
+{
+if (basegfx::fTools::less(rStop.getStopOffset(), 
0.5))
+continue;
+if (basegfx::fTools::more(rStop.getStopOffset(), 
0.5))
+break;
+
+// the color in the middle is considered the start 
color for focus 50
+sColor1 = 
msfilter::util::ConvertColor(Color(rStop.getStopColor()));
+bIsSymmetrical = true;
+}
+}
+}
+
+if (bIsSymmetrical)
+AddToAttrList( 
m_rExport.SdrExporter().getFlyFillAttrList(), XML_focus, "50%" );
+
 AddToAttrList(m_rExport.SdrExporter().getFlyFillAttrList(), 
XML_type, "gradient");
 break;
+}
 case css::awt::GradientStyle_RADIAL:
 case css::awt::GradientStyle_ELLIPTICAL:
 case css::awt::GradientStyle_SQUARE:


core.git: sw/qa sw/source

2024-02-23 Thread Justin Luth (via logerrit)
 sw/qa/extras/ooxmlexport/ooxmlexport21.cxx   |4 
 sw/source/filter/ww8/docxattributeoutput.cxx |   18 +++---
 2 files changed, 15 insertions(+), 7 deletions(-)

New commits:
commit 1a4639dd8024484971859bcce31470584bc6b973
Author: Justin Luth 
AuthorDate: Wed Feb 14 10:48:08 2024 -0500
Commit: Miklos Vajna 
CommitDate: Fri Feb 23 10:57:11 2024 +0100

related tdf#126533 DOCX: vml export gradientRadial instead of gradient

... for everything except the linear gradients (linear/axial)

Interestingly, there was nothing in make sw.check that hit this.

make CppunitTest_sw_ooxmlexport21 \
CPPUNIT_TEST_NAME=testTdf126533_pageGradient

Change-Id: Id58ed8b312ec29a10ce461ff0e032838b745b11b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163470
Reviewed-by: Justin Luth 
Tested-by: Jenkins
Reviewed-by: Miklos Vajna 

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
index d2bd3440a90b..2e6c10c99031 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
@@ -10,6 +10,7 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -384,6 +385,9 @@ DECLARE_OOXMLEXPORT_TEST(testTdf126533_pageGradient, 
"fill.docx")
uno::UNO_QUERY);
 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT,
  getProperty(xPageStyle, 
"FillStyle"));
+
+awt::Gradient2 aGradient = getProperty(xPageStyle, 
"FillGradient");
+CPPUNIT_ASSERT_EQUAL(awt::GradientStyle_RECT, aGradient.Style);
 }
 
 DECLARE_OOXMLEXPORT_TEST(testTdf126533_pageBitmap, "tdf126533_pageBitmap.docx")
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index c2b7ea47d395..787908091589 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -9627,8 +9627,6 @@ void DocxAttributeOutput::FormatFillGradient( const 
XFillGradientItem& rFillGrad
 {
 if (m_oFillStyle && *m_oFillStyle == drawing::FillStyle_GRADIENT && 
!m_rExport.SdrExporter().getDMLTextFrameSyntax())
 {
-AddToAttrList( m_rExport.SdrExporter().getFlyFillAttrList(), XML_type, 
"gradient" );
-
 const basegfx::BGradient& rGradient = rFillGradient.GetGradientValue();
 OString sStartColor = 
msfilter::util::ConvertColor(Color(rGradient.GetColorStops().front().getStopColor()));
 OString sEndColor = 
msfilter::util::ConvertColor(Color(rGradient.GetColorStops().back().getStopColor()));
@@ -9650,17 +9648,23 @@ void DocxAttributeOutput::FormatFillGradient( const 
XFillGradientItem& rFillGrad
 switch (rGradient.GetGradientStyle())
 {
 case css::awt::GradientStyle_AXIAL:
+AddToAttrList(m_rExport.SdrExporter().getFlyFillAttrList(), 
XML_type, "gradient");
 AddToAttrList( m_rExport.SdrExporter().getFlyFillAttrList(), 
XML_focus, "50%" );
 // If it is an 'axial' gradient - swap the colors
 // (because in the import process they were imported swapped)
 sColor1 = sEndColor;
 sColor2 = sStartColor;
 break;
-case css::awt::GradientStyle_LINEAR: break;
-case css::awt::GradientStyle_RADIAL: break;
-case css::awt::GradientStyle_ELLIPTICAL: break;
-case css::awt::GradientStyle_SQUARE: break;
-case css::awt::GradientStyle_RECT: break;
+case css::awt::GradientStyle_LINEAR:
+AddToAttrList(m_rExport.SdrExporter().getFlyFillAttrList(), 
XML_type, "gradient");
+break;
+case css::awt::GradientStyle_RADIAL:
+case css::awt::GradientStyle_ELLIPTICAL:
+case css::awt::GradientStyle_SQUARE:
+case css::awt::GradientStyle_RECT:
+AddToAttrList(m_rExport.SdrExporter().getFlyFillAttrList(), 
XML_type,
+  "gradientRadial");
+break;
 default:
 break;
 }


core.git: sw/qa sw/source

2024-02-23 Thread Justin Luth (via logerrit)
 sw/qa/extras/ooxmlexport/ooxmlexport21.cxx |3 +--
 sw/source/filter/ww8/docxexport.cxx|   21 +
 2 files changed, 22 insertions(+), 2 deletions(-)

New commits:
commit f3efd1dc397e2801a30e705120a21a4e384596ec
Author: Justin Luth 
AuthorDate: Tue Feb 13 13:58:08 2024 -0500
Commit: Miklos Vajna 
CommitDate: Fri Feb 23 10:56:07 2024 +0100

tdf#126533 DOCX: export page vml fill gradient

Simplistic export of gradient fill.

I just used the existing docxattribute stuff that textboxes
use to export their background as VML fallback.

Note that docxattribute only knows how to export gradient,
not gradientRadial. (Done in follow-up patch.)

Lots of stuff is missing in terms properly supporting gradients.
But likely fixing page background will fix
the same problem in textboxes etc.

Given how incredibly different LO and MSO are in terms of gradients,
it makes sense to commit this change and at least get the basics
wired in.

make CppunitTest_sw_ooxmlexport21 \
CPPUNIT_TEST_NAME=testTdf126533_pageGradient

Change-Id: I2ac14fdef2fe29609bc8d5a5d8f65b3f0da71889
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163469
Reviewed-by: Justin Luth 
Tested-by: Jenkins
Reviewed-by: Miklos Vajna 

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
index 224f8f2aa27d..d2bd3440a90b 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
@@ -377,10 +377,9 @@ DECLARE_OOXMLEXPORT_TEST(testTdf126533_noPageBitmap, 
"tdf126533_noPageBitmap.doc
  getProperty(xPageStyle, 
"FillStyle"));
 }
 
-CPPUNIT_TEST_FIXTURE(Test, testTdf126533_pageGradient)
+DECLARE_OOXMLEXPORT_TEST(testTdf126533_pageGradient, "fill.docx")
 {
 // given a document with a gradient page background
-loadFromFile(u"fill.docx");
 uno::Reference 
xPageStyle(getStyles("PageStyles")->getByName("Standard"),
uno::UNO_QUERY);
 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT,
diff --git a/sw/source/filter/ww8/docxexport.cxx 
b/sw/source/filter/ww8/docxexport.cxx
index 466fe652d5dd..787c90e32b12 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -55,6 +55,7 @@
 #include 
 
 #include 
+#include 
 #include 
 
 #include 
@@ -1916,6 +1917,7 @@ void DocxExport::WriteMainText()
   
msfilter::util::ConvertColor(oBrush->GetColor()));
 
 const SwAttrSet& rPageStyleAttrSet = 
m_rDoc.GetPageDesc(0).GetMaster().GetAttrSet();
+const drawing::FillStyle eFillType = 
rPageStyleAttrSet.Get(XATTR_FILLSTYLE).GetValue();
 const GraphicObject* pGraphicObj = oBrush->GetGraphicObject();
 if (pGraphicObj) // image/pattern/texture
 {
@@ -1934,6 +1936,25 @@ void DocxExport::WriteMainText()
 m_pDocumentFS->endElementNS(XML_v, XML_background);
 }
 }
+else if (eFillType == drawing::FillStyle_GRADIENT)
+{
+SfxItemSetFixed 
aSet(m_rDoc.GetAttrPool());
+aSet.Set(rPageStyleAttrSet);
+
+// Collect all of the gradient attributes into SdrExporter() 
AttrLists
+m_pAttrOutput->OutputStyleItemSet(aSet, /*TestForDefault=*/true);
+assert(SdrExporter().getFlyAttrList().is() && "type and fillcolor 
are always provided");
+assert(SdrExporter().getFlyFillAttrList().is() && "color2 is 
always provided");
+
+rtl::Reference 
xFlyAttrList(SdrExporter().getFlyAttrList());
+rtl::Reference 
xFillAttrList(SdrExporter().getFlyFillAttrList());
+m_pDocumentFS->startElementNS(XML_v, XML_background, xFlyAttrList);
+m_pDocumentFS->singleElementNS(XML_v, XML_fill, xFillAttrList);
+m_pDocumentFS->endElementNS(XML_v, XML_background);
+
+SdrExporter().getFlyAttrList().clear();
+SdrExporter().getFlyFillAttrList().clear();
+}
 
 m_pDocumentFS->endElementNS(XML_w, XML_background);
 }


core.git: sw/qa sw/source

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

New commits:
commit bf269ed81fe2ec7c89a0f7d2d22e8e1982f558f4
Author: Mike Kaganski 
AuthorDate: Wed Feb 21 16:20:08 2024 +0600
Commit: Mike Kaganski 
CommitDate: Wed Feb 21 14:55:25 2024 +0100

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

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

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

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

core.git: sw/qa sw/source

2024-02-20 Thread Justin Luth (via logerrit)
 sw/qa/extras/ooxmlexport/data/tdf126533_pageBitmap.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlexport21.cxx  |   16 +++
 sw/source/filter/ww8/docxexport.cxx |   22 +---
 sw/source/filter/ww8/rtfexport.cxx  |3 +-
 sw/source/filter/ww8/wrtww8.cxx |2 -
 5 files changed, 37 insertions(+), 6 deletions(-)

New commits:
commit ed91971c9312e4b8a33c03c28d339bff6c5accc7
Author: Justin Luth 
AuthorDate: Fri Feb 9 15:43:32 2024 -0500
Commit: Miklos Vajna 
CommitDate: Wed Feb 21 08:42:31 2024 +0100

tdf#126533 docx export: page background vml fill: basic image

This is the absolute minimal possible combination
to export an image to page background.

However, none of the other properties
that I see strike me as particularly important
or connected to our image properties.

Plus MSO ignores things like "frame" and tiles anyway.

Import is also pretty basic, so any improvement to imports
can also add the corresponding export component.

For example: it seems like MSO tiles all images
based on somewhat magical sizing (they do always export
o:targetscreensize="999,999" which we ignore).
But note that MSO does pixel display and not logical display
for page background - something we do NOT want to emulate,
so any importing of properties needs to be done intelligently.

But MSO's UI only allows for basic image insertion,
so very few files will have complex settings.

make CppunitTest_sw_ooxmlexport21 \
CPPUNIT_TEST_NAME=testTdf126533_pageBitmap

Change-Id: Ib410594d1e3377aefb8ee94f209a1a1155154b17
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163203
Tested-by: Jenkins
Reviewed-by: Justin Luth 

diff --git a/sw/qa/extras/ooxmlexport/data/tdf126533_pageBitmap.docx 
b/sw/qa/extras/ooxmlexport/data/tdf126533_pageBitmap.docx
new file mode 100644
index ..67131acd2fd8
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf126533_pageBitmap.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
index e455467a74ef..224f8f2aa27d 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
@@ -387,6 +387,22 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf126533_pageGradient)
  getProperty(xPageStyle, 
"FillStyle"));
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf126533_pageBitmap, "tdf126533_pageBitmap.docx")
+{
+// given a document with a page background image
+uno::Reference 
xPageStyle(getStyles("PageStyles")->getByName("Standard"),
+   uno::UNO_QUERY);
+CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_BITMAP,
+ getProperty(xPageStyle, 
"FillStyle"));
+
+if (!isExported())
+return;
+
+xmlDocUniquePtr pXmlDocRels = parseExport("word/_rels/document.xml.rels");
+assertXPath(pXmlDocRels,
+
"/rels:Relationships/rels:Relationship[@Target='media/image1.jpeg']"_ostr, 1);
+}
+
 } // end of anonymous namespace
 CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/sw/source/filter/ww8/docxexport.cxx 
b/sw/source/filter/ww8/docxexport.cxx
index 869862909678..fcb55e19c314 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -1911,11 +1911,25 @@ void DocxExport::WriteMainText()
 // Write background page color
 if (std::unique_ptr oBrush = getBackground(); oBrush)
 {
-Color backgroundColor = oBrush->GetColor();
-OString aBackgroundColorStr = 
msfilter::util::ConvertColor(backgroundColor);
+m_pDocumentFS->startElementNS(XML_w, XML_background, FSNS(XML_w, 
XML_color),
+  
msfilter::util::ConvertColor(oBrush->GetColor()));
 
-m_pDocumentFS->singleElementNS(XML_w, XML_background, FSNS(XML_w, 
XML_color),
-   aBackgroundColorStr);
+const GraphicObject* pGraphicObj = oBrush->GetGraphicObject();
+if (pGraphicObj) // image/pattern/texture
+{
+const OUString aRelId = 
m_pDrawingML->writeGraphicToStorage(pGraphicObj->GetGraphic());
+if (!aRelId.isEmpty())
+{
+m_pDocumentFS->startElementNS(XML_v, XML_background);
+
+m_pDocumentFS->singleElementNS(XML_v, XML_fill, FSNS(XML_r, 
XML_id), aRelId,
+XML_type, "frame");
+
+m_pDocumentFS->endElementNS(XML_v, XML_background);
+}
+}
+
+m_pDocumentFS->endElementNS(XML_w, XML_background);
 }
 
 // body
diff --git a/sw/source/filter/ww8/rtfexport.cxx 
b/sw/source/filter/ww8/rtfexport.cxx
index 135a84da36a5..7dbe10221ef1 100644
--- a/sw/source/filter/ww8/rtfexport.cxx
+++ b/sw/source/filter/ww8/rtfexport.cxx
@@ -471,7 

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

2024-02-20 Thread Michael Stahl (via logerrit)
 sw/qa/extras/rtfimport/data/tdf153196.rtf |  114 ++
 sw/qa/extras/rtfimport/rtfimport.cxx  |   20 +++
 sw/source/uibase/utlui/uitool.cxx |1 
 writerfilter/source/dmapper/DomainMapper_Impl.cxx |8 +
 writerfilter/source/dmapper/DomainMapper_Impl.hxx |4 
 writerfilter/source/dmapper/PropertyMap.cxx   |   34 +-
 6 files changed, 178 insertions(+), 3 deletions(-)

New commits:
commit 340f8ea4ae7f11b4d3a95499188a29fe801867cf
Author: Michael Stahl 
AuthorDate: Tue Feb 20 11:54:13 2024 +0100
Commit: Michael Stahl 
CommitDate: Tue Feb 20 22:28:57 2024 +0100

tdf#153196 writerfilter: fix page style for even/odd section break

This is a bit of a special case, where the first section starts with an
evenPage break (\sbkeven), which causes a Left-only page style to be
created.

In completeCopyHeaderFooter(), the HeaderTextFirst and FooterTextFirst
are copied from the source style to the Left-only page style, but then
they also need to be deleted from the source style, because the
Left-only page style is the one that is used for the first page of the
section, and the source style is used for the subsequent pages.

Additionally, when there is *only* a "first" header/footer, and no
previous section has one to inherit, Word will not display a
header/footer at all on subsequent pages; a PageStyle will always have a
header/footer if it has a HeaderTextFirst/FooterTextFirst.

In this case, delete the header/footer from the source style.

Unfortunately exporting this doesn't work ideally, a spurious evenPage
footer will be created, both due to the FooterShare being automatically
reset for no obvious reason in ItemSetToPageDesc(), and
setProperty("FooterIsShared", true) "stashing" the left footer since
commit b802ab694a8a7357d4657f3e11b571144fa7c7bf.

(presumably regression from commit b32881b6723072c8d1a652ea147d12e75766d504)

Change-Id: Ie4f9c49605df690e9705e14777c0e4bcb0dfad8e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163668
Tested-by: Jenkins
Reviewed-by: Michael Stahl 

diff --git a/sw/qa/extras/rtfimport/data/tdf153196.rtf 
b/sw/qa/extras/rtfimport/data/tdf153196.rtf
new file mode 100644
index ..835cdeeb41b8
--- /dev/null
+++ b/sw/qa/extras/rtfimport/data/tdf153196.rtf
@@ -0,0 +1,114 @@
+{ 
tf1deflang1025nsinsicpg1250\uc1deff31507\deff0\stshfdbch31506\stshfloch31506\stshfhich31506\stshfbi31507\deflang1038\deflangfe1038
   hemelang1038hemelangfe0 hemelangcs0{onttbl{0bidi roman
charset0prq2{\*\panose 02020603050405020304}Times New Roman{\*alt Times New 
Roman};}
+{0bidi romancharset0prq2{\*\panose 02020603050405020304}Times New 
Roman{\*alt Times New Roman};}{39bidi swisscharset0prq2{\*\panose 
020f0502020204030204}Calibri;}
+{lomajor31500bidi romancharset0prq2{\*\panose 02020603050405020304}Times 
New Roman{\*alt Times New Roman};}{dbmajor31501bidi romancharset0
prq2{\*\panose 02020603050405020304}Times New Roman{\*alt Times New Roman};}
+{himajor31502bidi swisscharset0prq2{\*\panose 
020f0302020204030204}Calibri Light;}{bimajor31503bidi romancharset0
prq2{\*\panose 02020603050405020304}Times New Roman{\*alt Times New Roman};}
+{lominor31504bidi romancharset0prq2{\*\panose 02020603050405020304}Times 
New Roman{\*alt Times New Roman};}{dbminor31505bidi romancharset0
prq2{\*\panose 02020603050405020304}Times New Roman{\*alt Times New Roman};}
+{himinor31506bidi swisscharset0prq2{\*\panose 
020f0502020204030204}Calibri;}{biminor31507bidi romancharset0
prq2{\*\panose 02020603050405020304}Times New Roman{\*alt Times New Roman};}
+{364bidi romancharset238prq2 Times New Roman CE{\*alt Times New 
Roman};}{365bidi romancharset204prq2 Times New Roman Cyr{\*alt Times New 
Roman};}
+{367bidi romancharset161prq2 Times New Roman Greek{\*alt Times New 
Roman};}{368bidi romancharset162prq2 Times New Roman Tur{\*alt Times New 
Roman};}
+{369bidi romancharset177prq2 Times New Roman (Hebrew){\*alt Times New 
Roman};}{370bidi romancharset178prq2 Times New Roman (Arabic){\*alt Times 
New Roman};}
+{371bidi romancharset186prq2 Times New Roman Baltic{\*alt Times New 
Roman};}{372bidi romancharset163prq2 Times New Roman (Vietnamese){\*alt 
Times New Roman};}
+{364bidi romancharset238prq2 Times New Roman CE{\*alt Times New 
Roman};}{365bidi romancharset204prq2 Times New Roman Cyr{\*alt Times New 
Roman};}
+{367bidi romancharset161prq2 Times New Roman Greek{\*alt Times New 
Roman};}{368bidi romancharset162prq2 Times New Roman Tur{\*alt Times New 
Roman};}
+{369bidi romancharset177prq2 Times New Roman (Hebrew){\*alt Times New 
Roman};}{370bidi romancharset178prq2 Times New Roman (Arabic){\*alt Times 
New Roman};}
+{371bidi romancharset186prq2 Times 

core.git: sw/qa sw/source

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

New commits:
commit 2da4acdbf8c5a8ba3ef51e5f5dc3439716e71a91
Author: Miklos Vajna 
AuthorDate: Tue Feb 20 08:06:08 2024 +0100
Commit: Miklos Vajna 
CommitDate: Tue Feb 20 09:36:32 2024 +0100

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

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

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

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

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

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

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


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

2024-02-15 Thread Michael Stahl (via logerrit)
 sw/qa/extras/ooxmlexport/data/tdf158597.docx  |binary
 sw/qa/extras/ooxmlexport/ooxmlexport21.cxx|  257 ++
 sw/source/core/unocore/unomap1.cxx|1 
 sw/source/core/unocore/unoobj.cxx |   14 -
 writerfilter/source/dmapper/DomainMapper_Impl.cxx |2 
 5 files changed, 268 insertions(+), 6 deletions(-)

New commits:
commit ff9be3fd30ead41359734f9281b034a988d71196
Author: Michael Stahl 
AuthorDate: Wed Feb 14 19:13:34 2024 +0100
Commit: Michael Stahl 
CommitDate: Thu Feb 15 17:33:06 2024 +0100

tdf#158597 writerfilter,sw: fix toggle properties in ListAutoFormat

... for DOCX import.

These can be set both via paragraph style and via character style in the
w:pPr/w:rPr, so use the applyToggleAttributes().

Adding a test for this requires adding the "CharStyleName" property to
GetAutoCharStylePropertyMap().

Change-Id: I9701d5ac82ec3e7757650c08861791dc398a1a77
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163386
Tested-by: Jenkins
Reviewed-by: Michael Stahl 

diff --git a/sw/qa/extras/ooxmlexport/data/tdf158597.docx 
b/sw/qa/extras/ooxmlexport/data/tdf158597.docx
new file mode 100644
index ..ad7924ce71b3
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf158597.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
index cb008645adaf..f1d4a5e7121a 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
@@ -9,6 +9,7 @@
 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -16,6 +17,7 @@
 #include 
 
 #include 
+#include 
 #include 
 
 #include 
@@ -33,6 +35,261 @@ public:
 }
 };
 
+DECLARE_OOXMLEXPORT_TEST(testTdf158597, "tdf158597.docx")
+{
+// test with 2 properties: font size, italic (toggle)
+{
+uno::Reference xParagraph(getParagraph(1));
+CPPUNIT_ASSERT_EQUAL(OUString("No style"), xParagraph->getString());
+uno::Reference xProps(xParagraph, uno::UNO_QUERY);
+CPPUNIT_ASSERT_EQUAL(OUString("List Paragraph"),
+ getProperty(xProps, "ParaStyleName"));
+uno::Reference xRun(getRun(xParagraph, 1));
+CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty(xRun, 
"CharStyleName"));
+CPPUNIT_ASSERT_EQUAL(11.f, getProperty(xRun, "CharHeight"));
+CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, 
getProperty(xRun, "CharPosture"));
+CPPUNIT_ASSERT(!xProps->getPropertyValue("ListAutoFormat").hasValue());
+}
+{
+uno::Reference xParagraph(getParagraph(2));
+CPPUNIT_ASSERT_EQUAL(OUString("Char style mark"), 
xParagraph->getString());
+uno::Reference xProps(xParagraph, uno::UNO_QUERY);
+CPPUNIT_ASSERT_EQUAL(OUString("List Paragraph"),
+ getProperty(xProps, "ParaStyleName"));
+uno::Reference xRun(getRun(xParagraph, 1));
+CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty(xRun, 
"CharStyleName"));
+CPPUNIT_ASSERT_EQUAL(11.f, getProperty(xRun, "CharHeight"));
+CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, 
getProperty(xRun, "CharPosture"));
+comphelper::SequenceAsHashMap 
listAutoFormat(xProps->getPropertyValue("ListAutoFormat"));
+CPPUNIT_ASSERT_EQUAL(OUString("Emphasis"), 
listAutoFormat["CharStyleName"].get());
+CPPUNIT_ASSERT(!listAutoFormat["CharHeight"].hasValue());
+CPPUNIT_ASSERT(!listAutoFormat["CharPosture"].hasValue());
+}
+{
+uno::Reference xParagraph(getParagraph(3));
+CPPUNIT_ASSERT_EQUAL(OUString("Char style mark and text"), 
xParagraph->getString());
+uno::Reference xProps(xParagraph, uno::UNO_QUERY);
+CPPUNIT_ASSERT_EQUAL(OUString("List Paragraph"),
+ getProperty(xProps, "ParaStyleName"));
+uno::Reference xRun(getRun(xParagraph, 1));
+CPPUNIT_ASSERT_EQUAL(OUString("Emphasis"), getProperty(xRun, 
"CharStyleName"));
+CPPUNIT_ASSERT_EQUAL(16.f, getProperty(xRun, "CharHeight"));
+CPPUNIT_ASSERT_EQUAL(awt::FontSlant_ITALIC,
+ getProperty(xRun, "CharPosture"));
+comphelper::SequenceAsHashMap 
listAutoFormat(xProps->getPropertyValue("ListAutoFormat"));
+CPPUNIT_ASSERT_EQUAL(OUString("Emphasis"), 
listAutoFormat["CharStyleName"].get());
+CPPUNIT_ASSERT(!listAutoFormat["CharHeight"].hasValue());
+CPPUNIT_ASSERT(!listAutoFormat["CharPosture"].hasValue());
+}
+{
+uno::Reference xParagraph(getParagraph(4));
+CPPUNIT_ASSERT_EQUAL(OUString("Char style text"), 
xParagraph->getString());
+uno::Reference xProps(xParagraph, uno::UNO_QUERY);
+CPPUNIT_ASSERT_EQUAL(OUString("List Paragraph"),
+ getProperty(xProps, "ParaStyleName"));
+uno::Reference xRun(getRun(xParagraph, 1));
+

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

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

New commits:
commit 582ef812702413dbe7fb0f132bca3e3e4c2e1d40
Author: Michael Stahl 
AuthorDate: Fri Feb 9 17:51:03 2024 +0100
Commit: Michael Stahl 
CommitDate: Mon Feb 12 11:05:45 2024 +0100

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

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

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

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

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

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

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

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

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

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

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

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

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

Change-Id: I43fa9431721650a6d748d1f4bda9aeaa7a9c6b45
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163200
Tested-by: Jenkins
Reviewed-by: Michael Stahl 

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

core.git: sw/qa sw/source

2024-02-05 Thread Michael Stahl (via logerrit)
 sw/qa/extras/odfimport/data/tdf123968.odt |binary
 sw/qa/extras/odfimport/odfimport.cxx  |   12 
 sw/source/core/fields/expfld.cxx  |   20 +++-
 sw/source/core/inc/unofield.hxx   |2 +-
 sw/source/core/unocore/unofield.cxx   |   30 +++---
 5 files changed, 51 insertions(+), 13 deletions(-)

New commits:
commit 99055ae98ef1fe67b8db4a8c3167a8acaeaac02f
Author: Michael Stahl 
AuthorDate: Fri Feb 2 20:10:24 2024 +0100
Commit: Michael Stahl 
CommitDate: Mon Feb 5 16:28:26 2024 +0100

tdf#123968 sw: fix assert on importing ooo62823-1.sxw

svl/source/items/itemset.cxx:662: const SfxPoolItem* 
implCreateItemEntry(SfxItemPool&, const SfxPoolItem*, bool): Assertion 
`pSource->Which() == nWhich && "ITEM: Clone of Item did NOT copy/set WhichID 
(!)"' failed.

XMLVariableInputFieldImportContext::PrepareField() first sets "Input"
and then "SubType" property.

Apparently i missed that *both* of these are mutable in the API, and
both together determine whether the field is a RES_TXTATR_INPUTFIELD or
RES_TXTATR_FIELD.

So call SwXTextField::TransmuteLeadToInputField() also when the
"SubType" is set, and adapt it to toggling 2 different things.

Hmm... actually this will change these fields to be inline editable
after ODF import, which was the intention all along.

It turns out that there is even a unit test testTdf123968 for this; it
works in the usual case, but in this case the input field is in a
header, so in styles.xml, and the styles.xml is imported before
content.xml and does not contain the variable-decls element, so the
variable field type has the GSE_EXPR subtype (default?), and setting the
"Input" property doesn't transmute it.

(regression from commit 742baabbe4d077e1ba913a7989300908f4637ac7)

Change-Id: Ib5757cda32287e51651f05f5b19e82d7be0431e3
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162941
Tested-by: Jenkins
Reviewed-by: Michael Stahl 

diff --git a/sw/qa/extras/odfimport/data/tdf123968.odt 
b/sw/qa/extras/odfimport/data/tdf123968.odt
index 1c081619ea30..cd1ec8a3859a 100644
Binary files a/sw/qa/extras/odfimport/data/tdf123968.odt and 
b/sw/qa/extras/odfimport/data/tdf123968.odt differ
diff --git a/sw/qa/extras/odfimport/odfimport.cxx 
b/sw/qa/extras/odfimport/odfimport.cxx
index aa158b43b132..115e30b61368 100644
--- a/sw/qa/extras/odfimport/odfimport.cxx
+++ b/sw/qa/extras/odfimport/odfimport.cxx
@@ -1169,9 +1169,21 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf123968)
 SwTextNode& rStart = 
dynamic_cast(pShellCursor->Start()->GetNode());
 
 // The field is now editable like any text, thus the field content "New 
value" shows up for the cursor.
+// This field's variable is declared as string and used as string - 
typical.
 CPPUNIT_ASSERT_EQUAL(OUString("inputfield: " + 
OUStringChar(CH_TXT_ATR_INPUTFIELDSTART)
   + "New value" + 
OUStringChar(CH_TXT_ATR_INPUTFIELDEND)),
  rStart.GetText());
+
+// This field's variable is declared as float and used as string - not
+// typical; this can easily happen if the input field is in a 
header/footer,
+// because only content.xml contains the variable-decls, styles.xml is
+// imported before content.xml, and apparently the default variable type is
+// numeric.
+SwTextNode& rEnd = 
dynamic_cast(pShellCursor->End()->GetNode());
+CPPUNIT_ASSERT_EQUAL(OUString("inputfield: " + 
OUStringChar(CH_TXT_ATR_INPUTFIELDSTART)
+  + "String input for num variable" + 
OUStringChar(CH_TXT_ATR_INPUTFIELDEND)),
+ rEnd.GetText());
+
 }
 
 CPPUNIT_TEST_FIXTURE(Test, testTdf133459)
diff --git a/sw/source/core/fields/expfld.cxx b/sw/source/core/fields/expfld.cxx
index 434f67672903..6ed4cdb7c125 100644
--- a/sw/source/core/fields/expfld.cxx
+++ b/sw/source/core/fields/expfld.cxx
@@ -881,10 +881,9 @@ std::unique_ptr SwSetExpField::Copy() const
 
 void SwSetExpField::SetSubType(sal_uInt16 nSub)
 {
+assert((nSub & 0xff) != 
(nsSwGetSetExpType::GSE_STRING|nsSwGetSetExpType::GSE_EXPR) && "SubType is 
illegal!");
 static_cast(GetTyp())->SetType(nSub & 0xff);
 mnSubType = nSub & 0xff00;
-
-OSL_ENSURE( (nSub & 0xff) != 3, "SubType is illegal!" );
 }
 
 sal_uInt16 SwSetExpField::GetSubType() const
@@ -1100,8 +1099,19 @@ bool SwSetExpField::PutValue( const uno::Any& rAny, 
sal_uInt16 nWhichId )
 break;
 case FIELD_PROP_SUBTYPE:
 nTmp32 = lcl_APIToSubType(rAny);
-if(nTmp32 >= 0)
-SetSubType(o3tl::narrowing((GetSubType() & 0xff00) | 
nTmp32));
+if (0 <= nTmp32 && nTmp32 != (GetSubType() & 0xff))
+{
+auto const subType(o3tl::narrowing((GetSubType() & 
0xff00) | nTmp32));
+if (((nTmp32 & nsSwGetSetExpType::GSE_STRING) != (GetSubType() & 

core.git: sw/qa sw/source

2024-02-04 Thread Samuel Mehrbrodt (via logerrit)
 sw/qa/uitest/data/tdf159428.odt |binary
 sw/qa/uitest/navigator/tdf159428.py |   49 +++
 sw/source/uibase/utlui/content.cxx  |  111 +---
 3 files changed, 104 insertions(+), 56 deletions(-)

New commits:
commit 070b4ddda4983773e8a989a116924bee0f651f25
Author: Samuel Mehrbrodt 
AuthorDate: Mon Jan 29 16:04:45 2024 +0100
Commit: Samuel Mehrbrodt 
CommitDate: Mon Feb 5 07:50:17 2024 +0100

tdf#159428 Prefer heading over bookmarks in Navigator

When a bookmark is in a heading, highlighting the heading
is more important than highlighting the bookmark.

Change-Id: I6348e42b14ece226a25961bd3145193645972e79
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162694
Tested-by: Jenkins
Reviewed-by: Samuel Mehrbrodt 

diff --git a/sw/qa/uitest/data/tdf159428.odt b/sw/qa/uitest/data/tdf159428.odt
new file mode 100644
index ..6b30d6bf0cdc
Binary files /dev/null and b/sw/qa/uitest/data/tdf159428.odt differ
diff --git a/sw/qa/uitest/navigator/tdf159428.py 
b/sw/qa/uitest/navigator/tdf159428.py
new file mode 100644
index ..3a8634a57629
--- /dev/null
+++ b/sw/qa/uitest/navigator/tdf159428.py
@@ -0,0 +1,49 @@
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+from uitest.framework import UITestCase
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from uitest.uihelper.common import get_state_as_dict, get_url_for_data_file
+
+class tdf159428(UITestCase):
+
+def test_tdf159428(self):
+global selectionChangedResult
+with self.ui_test.load_file(get_url_for_data_file('tdf159428.odt')):
+xWriterDoc = self.xUITest.getTopFocusWindow()
+xWriterEdit = xWriterDoc.getChild("writer_edit")
+
+self.xUITest.executeCommand(".uno:Sidebar")
+xWriterEdit.executeAction("SIDEBAR", mkPropertyValues({"PANEL": 
"SwNavigatorPanel"}))
+
+xNavigatorPanel = 
self.ui_test.wait_until_child_is_available('NavigatorPanel')
+xContentTree = xNavigatorPanel.getChild("contenttree")
+
+# select fist bookmark - Heading "H1" should be tracked
+self.xUITest.executeCommand(".uno:GoToNextPara")
+self.xUITest.executeCommand(".uno:GoToNextPara")
+xWriterEdit.executeAction("SELECT", mkPropertyValues({"START_POS": 
"111", "END_POS": "119"}))
+self.ui_test.wait_until_property_is_updated(xContentTree, 
"SelectEntryText", "H1")
+
self.assertEqual(get_state_as_dict(xContentTree)["SelectEntryText"], "H1")
+
+# select second bookmark - Heading "H1 mit Lesezeichen" should be 
tracked
+self.xUITest.executeCommand(".uno:GoToNextPara")
+xWriterEdit.executeAction("SELECT", mkPropertyValues({"START_POS": 
"0", "END_POS": "18"}))
+self.ui_test.wait_until_property_is_updated(xContentTree, 
"SelectEntryText", "H1 mit Lesezeichen")
+
self.assertEqual(get_state_as_dict(xContentTree)["SelectEntryText"], "H1 mit 
Lesezeichen")
+
+# select third bookmark - no heading tracked
+self.xUITest.executeCommand(".uno:GoToPrevPara")
+self.xUITest.executeCommand(".uno:GoToPrevPara")
+self.xUITest.executeCommand(".uno:GoToPrevPara")
+xWriterEdit.executeAction("SELECT", mkPropertyValues({"START_POS": 
"141", "END_POS": "146"}))
+self.ui_test.wait_until_property_is_updated(xContentTree, 
"SelectEntryText", "Lesezeichen 3")
+
self.assertEqual(get_state_as_dict(xContentTree)["SelectEntryText"], 
"Lesezeichen 3")
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/sw/source/uibase/utlui/content.cxx 
b/sw/source/uibase/utlui/content.cxx
index 5655b67ceab1..b058cf46c464 100644
--- a/sw/source/uibase/utlui/content.cxx
+++ b/sw/source/uibase/utlui/content.cxx
@@ -4305,52 +4305,6 @@ void SwContentTree::UpdateTracking()
   aContentAtPos.pFndTextAttr);
 return;
 }
-// bookmarks - track first bookmark at cursor
-if (mTrackContentType[ContentTypeId::BOOKMARK] &&
-(m_pActiveShell->GetSelectionType() & SelectionType::Text))
-{
-SwPaM* pCursor = m_pActiveShell->GetCursor();
-IDocumentMarkAccess* const pMarkAccess = 
m_pActiveShell->getIDocumentMarkAccess();
-IDocumentMarkAccess::const_iterator_t ppBookmark = 
pMarkAccess->getBookmarksBegin();
-if (pCursor && ppBookmark != pMarkAccess->getBookmarksEnd() &&
-!(m_bIsRoot && m_nRootType != ContentTypeId::BOOKMARK))
-{
-OUString sBookmarkName;
-

core.git: sw/qa sw/source

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

New commits:
commit 256e2c679bcbb3ea446884d0ff4e3f8687b82ede
Author: Miklos Vajna 
AuthorDate: Tue Jan 30 16:51:49 2024 +0100
Commit: Miklos Vajna 
CommitDate: Tue Jan 30 19:56:35 2024 +0100

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

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

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

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

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

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

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

core.git: sw/qa sw/source

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

New commits:
commit 863a4cde77a5045d44b1da583f00c0a72762f19a
Author: Xisco Fauli 
AuthorDate: Tue Jan 23 15:28:26 2024 +0100
Commit: Xisco Fauli 
CommitDate: Wed Jan 24 15:40:25 2024 +0100

tdf#159336: export EditWidget with multiline enabled

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

-> The content control is displayed in one line

Change-Id: Ia8666c8a6520e94ae06693ea8767c1d79aa5d3a0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162446
Reviewed-by: Xisco Fauli 
Tested-by: Jenkins

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


core.git: sw/qa sw/source

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

New commits:
commit 6e3ad6ca0ae6cf62056610ddae9097973a887d99
Author: Miklos Vajna 
AuthorDate: Tue Jan 23 15:34:07 2024 +0100
Commit: Miklos Vajna 
CommitDate: Tue Jan 23 19:19:07 2024 +0100

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

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

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

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

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

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

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

core.git: sw/qa sw/source

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

New commits:
commit 229864a103b6ba8714a62609167be2deae16b987
Author: Mike Kaganski 
AuthorDate: Fri Jan 19 11:07:58 2024 +0600
Commit: Mike Kaganski 
CommitDate: Fri Jan 19 07:09:17 2024 +0100

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

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

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


core.git: sw/qa sw/source

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

New commits:
commit ab7893544dc6be6dc192dffefd57cd5ddd421c35
Author: Michael Stahl 
AuthorDate: Wed Jan 17 16:56:38 2024 +0100
Commit: Michael Stahl 
CommitDate: Thu Jan 18 13:04:58 2024 +0100

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

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

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

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

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

Change-Id: Ic8246ac91c741f5a215f89dc159c44d7c7cf2ce1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162203
Tested-by: Jenkins
Reviewed-by: Michael Stahl 

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

core.git: sw/qa sw/source

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

New commits:
commit 8b393bba9bd4f8988457f3a78b0306462bf2
Author: László Németh 
AuthorDate: Wed Jan 10 20:41:04 2024 +0100
Commit: László Németh 
CommitDate: Thu Jan 18 01:29:38 2024 +0100

tdf#159102 sw smart justify: fix automatic hyphenation

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

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

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

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

Change-Id: I58ecb8f1ea9f55ef2457d7ff4aca6aefa59a6dd1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162199
Tested-by: Jenkins
Reviewed-by: László Németh 

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

core.git: sw/qa sw/source

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

New commits:
commit 81f67b474fad0b8967a7edebcb560daa35b87455
Author: Justin Luth 
AuthorDate: Fri Jan 12 09:34:51 2024 -0500
Commit: Justin Luth 
CommitDate: Sat Jan 13 01:51:52 2024 +0100

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

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

make CppunitTest_sw_ooxmlexport19 CPPUNIT_TEST_NAME=testTdf97371

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

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

Change-Id: I29864d53f3b5e2fc9830793275f17a11eac0516f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161985
Tested-by: Jenkins
Reviewed-by: Justin Luth 

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


core.git: sw/qa sw/source

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

New commits:
commit 6dbe164d730726b0a91fdef70ba16410f9d81dc4
Author: Mike Kaganski 
AuthorDate: Thu Jan 11 13:16:45 2024 +0600
Commit: Mike Kaganski 
CommitDate: Thu Jan 11 09:13:37 2024 +0100

tdf#159050: let fly portion swallow hole portion width

Change-Id: I65492418ca5f5f5b04e5f9bab9ac3e6bf2108aff
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161910
Tested-by: Jenkins
Reviewed-by: Mike Kaganski 

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


core.git: sw/qa sw/source

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

New commits:
commit 7bd7085bcfce0b32179197a14189604d4c7478e1
Author: Mike Kaganski 
AuthorDate: Wed Jan 10 22:39:39 2024 +0600
Commit: Mike Kaganski 
CommitDate: Thu Jan 11 03:59:36 2024 +0100

tdf#159110: store URLs to DOCX correctly

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

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

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

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

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


core.git: sw/qa sw/source

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

New commits:
commit d511367c102ef2ada0f73dbe81744d39865d58ba
Author: László Németh 
AuthorDate: Tue Jan 9 13:35:23 2024 +0100
Commit: László Németh 
CommitDate: Tue Jan 9 20:03:00 2024 +0100

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

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

Change-Id: If8b7af40ff50d12c0f2428a6f2475e261fbd0f42
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161827
Tested-by: Jenkins
Reviewed-by: László Németh 

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

core.git: sw/qa sw/source

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

New commits:
commit 14c0f2cd140da66d38a8282332f2cb734bb74e39
Author: László Németh 
AuthorDate: Mon Jan 8 01:28:36 2024 +0100
Commit: László Németh 
CommitDate: Mon Jan 8 13:20:11 2024 +0100

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

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

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

Change-Id: I3fd88a30df2739ce8a3cdc24da07684a3ac5a41b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161777
Tested-by: László Németh 
Reviewed-by: László Németh 

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


core.git: sw/qa sw/source

2024-01-08 Thread Julien Nabet (via logerrit)
 sw/source/core/docnode/ndtbl.cxx|5 +
 sw/source/uibase/shells/basesh.cxx  |3 +++
 sw/source/uibase/shells/textsh1.cxx |3 ++-
 3 files changed, 10 insertions(+), 1 deletion(-)

New commits:
commit 08c4ed96cc94df4a3859aa167e92e6f6da9c2ce7
Author: Julien Nabet 
AuthorDate: Mon Jan 8 09:28:07 2024 +0100
Commit: Julien Nabet 
CommitDate: Mon Jan 8 09:28:26 2024 +0100

Revert "Related tdf#76007: Make it possible to insert a Table in a Footnote 
or Endnote"

This reverts commit 75680dd751062b7ca34ff91e03de3add3fc973c6.

I won't be able to debug layout problems indicated by Miklos.

Change-Id: Ie610949a229468ba00d04b3542e14bdb68d7e1dd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161752
Tested-by: Julien Nabet 
Reviewed-by: Julien Nabet 

diff --git a/sw/qa/core/data/html/pass/ofz5909-1.html 
b/sw/qa/core/data/html/fail/ofz5909-1.html
similarity index 100%
rename from sw/qa/core/data/html/pass/ofz5909-1.html
rename to sw/qa/core/data/html/fail/ofz5909-1.html
diff --git a/sw/source/core/docnode/ndtbl.cxx b/sw/source/core/docnode/ndtbl.cxx
index c6aa9ddb67c5..a7a2bee478da 100644
--- a/sw/source/core/docnode/ndtbl.cxx
+++ b/sw/source/core/docnode/ndtbl.cxx
@@ -347,6 +347,11 @@ const SwTable* SwDoc::InsertTable( const 
SwInsertTableOptions& rInsTableOpts,
 assert(nCols && "Table without rows?");
 
 {
+// Do not copy into Footnotes!
+if( rPos.GetNode() < GetNodes().GetEndOfInserts() &&
+rPos.GetNode().GetIndex() >= 
GetNodes().GetEndOfInserts().StartOfSectionIndex() )
+return nullptr;
+
 // If the ColumnArray has a wrong count, ignore it!
 if( pColArr &&
 static_cast(nCols + ( text::HoriOrientation::NONE == 
eAdjust ? 2 : 1 )) != pColArr->size() )
diff --git a/sw/source/uibase/shells/basesh.cxx 
b/sw/source/uibase/shells/basesh.cxx
index 7ab234a80044..c96945ccdf30 100644
--- a/sw/source/uibase/shells/basesh.cxx
+++ b/sw/source/uibase/shells/basesh.cxx
@@ -3066,6 +3066,9 @@ void SwBaseShell::InsertTable( SfxRequest& _rRequest )
 const SfxItemSet* pArgs = _rRequest.GetArgs();
 SwWrtShell& rSh = GetShell();
 
+if ( rSh.GetFrameType( nullptr, true ) & FrameTypeFlags::FOOTNOTE )
+return;
+
 SwView  = GetView(); // Because GetView() does not work after 
the shell exchange
 bool bHTMLMode = 0 != (::GetHtmlMode(rTempView.GetDocShell())_ON);
 bool bCallEndUndo = false;
diff --git a/sw/source/uibase/shells/textsh1.cxx 
b/sw/source/uibase/shells/textsh1.cxx
index c8c83fc29115..f23d5a229ec9 100644
--- a/sw/source/uibase/shells/textsh1.cxx
+++ b/sw/source/uibase/shells/textsh1.cxx
@@ -2337,7 +2337,8 @@ void SwTextShell::GetState( SfxItemSet  )
 
 case FN_INSERT_TABLE:
 if ( rSh.CursorInsideInputField()
- || rSh.GetTableFormat() )
+ || rSh.GetTableFormat()
+ || (rSh.GetFrameType(nullptr,true) & 
FrameTypeFlags::FOOTNOTE) )
 {
 rSet.DisableItem( nWhich );
 }


core.git: sw/qa sw/source

2024-01-07 Thread Julien Nabet (via logerrit)
 sw/source/core/docnode/ndtbl.cxx|5 -
 sw/source/uibase/shells/basesh.cxx  |3 ---
 sw/source/uibase/shells/textsh1.cxx |3 +--
 3 files changed, 1 insertion(+), 10 deletions(-)

New commits:
commit 75680dd751062b7ca34ff91e03de3add3fc973c6
Author: Julien Nabet 
AuthorDate: Wed Dec 20 22:50:59 2023 +0100
Commit: Julien Nabet 
CommitDate: Sun Jan 7 11:44:55 2024 +0100

Related tdf#76007: Make it possible to insert a Table in a Footnote or 
Endnote

There's still layout refresh pb.

Change-Id: I613cbf77a32452fdc42501e2eaf8450b7dedf327
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161085
Tested-by: Jenkins
Reviewed-by: Julien Nabet 

diff --git a/sw/qa/core/data/html/fail/ofz5909-1.html 
b/sw/qa/core/data/html/pass/ofz5909-1.html
similarity index 100%
rename from sw/qa/core/data/html/fail/ofz5909-1.html
rename to sw/qa/core/data/html/pass/ofz5909-1.html
diff --git a/sw/source/core/docnode/ndtbl.cxx b/sw/source/core/docnode/ndtbl.cxx
index a7a2bee478da..c6aa9ddb67c5 100644
--- a/sw/source/core/docnode/ndtbl.cxx
+++ b/sw/source/core/docnode/ndtbl.cxx
@@ -347,11 +347,6 @@ const SwTable* SwDoc::InsertTable( const 
SwInsertTableOptions& rInsTableOpts,
 assert(nCols && "Table without rows?");
 
 {
-// Do not copy into Footnotes!
-if( rPos.GetNode() < GetNodes().GetEndOfInserts() &&
-rPos.GetNode().GetIndex() >= 
GetNodes().GetEndOfInserts().StartOfSectionIndex() )
-return nullptr;
-
 // If the ColumnArray has a wrong count, ignore it!
 if( pColArr &&
 static_cast(nCols + ( text::HoriOrientation::NONE == 
eAdjust ? 2 : 1 )) != pColArr->size() )
diff --git a/sw/source/uibase/shells/basesh.cxx 
b/sw/source/uibase/shells/basesh.cxx
index c96945ccdf30..7ab234a80044 100644
--- a/sw/source/uibase/shells/basesh.cxx
+++ b/sw/source/uibase/shells/basesh.cxx
@@ -3066,9 +3066,6 @@ void SwBaseShell::InsertTable( SfxRequest& _rRequest )
 const SfxItemSet* pArgs = _rRequest.GetArgs();
 SwWrtShell& rSh = GetShell();
 
-if ( rSh.GetFrameType( nullptr, true ) & FrameTypeFlags::FOOTNOTE )
-return;
-
 SwView  = GetView(); // Because GetView() does not work after 
the shell exchange
 bool bHTMLMode = 0 != (::GetHtmlMode(rTempView.GetDocShell())_ON);
 bool bCallEndUndo = false;
diff --git a/sw/source/uibase/shells/textsh1.cxx 
b/sw/source/uibase/shells/textsh1.cxx
index f23d5a229ec9..c8c83fc29115 100644
--- a/sw/source/uibase/shells/textsh1.cxx
+++ b/sw/source/uibase/shells/textsh1.cxx
@@ -2337,8 +2337,7 @@ void SwTextShell::GetState( SfxItemSet  )
 
 case FN_INSERT_TABLE:
 if ( rSh.CursorInsideInputField()
- || rSh.GetTableFormat()
- || (rSh.GetFrameType(nullptr,true) & 
FrameTypeFlags::FOOTNOTE) )
+ || rSh.GetTableFormat() )
 {
 rSet.DisableItem( nWhich );
 }


core.git: sw/qa sw/source

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

New commits:
commit 96b3ed389fa5d434ed738d7f84dada4b6e2fabec
Author: László Németh 
AuthorDate: Fri Jan 5 01:11:34 2024 +0100
Commit: László Németh 
CommitDate: Fri Jan 5 06:08:09 2024 +0100

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

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

Change-Id: Ia3f39ad6549ea909bfe327ff8c8cbde821b90f46
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161652
Tested-by: Jenkins
Reviewed-by: László Németh 

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


core.git: sw/qa sw/source

2024-01-02 Thread Justin Luth (via logerrit)
 sw/qa/extras/uiwriter/uiwriter9.cxx |   27 
 sw/source/uibase/shells/textsh1.cxx |  115 +---
 2 files changed, 122 insertions(+), 20 deletions(-)

New commits:
commit 41452912e8ec11ecfead11588e7c70ad08903fd9
Author: Justin Luth 
AuthorDate: Sat Dec 23 21:20:04 2023 -0500
Commit: Miklos Vajna 
CommitDate: Wed Jan 3 08:49:35 2024 +0100

tdf#111969 sw: right-click menu recognizes start of hyperlink

Prior to these fixes, the right-click building a menu
for a hyperlink started half-a-character to late,
because it doesn't activate at the start of a hyperlink,
since a start == end cursor doesn't register character attributes.

So this kind of fix may be needed for any kind of field
or similar attribute that uses GetContentAtPos
that interacts with the mouse cursor/menus etc.

make CppunitTest_sw_uiwriter9 CPPUNIT_TEST_NAME=testTdf158785

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

diff --git a/sw/qa/extras/uiwriter/uiwriter9.cxx 
b/sw/qa/extras/uiwriter/uiwriter9.cxx
index a22ce3df306e..ef48220bc983 100644
--- a/sw/qa/extras/uiwriter/uiwriter9.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter9.cxx
@@ -66,6 +66,33 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf158785)
 aLogicR.AdjustX(1);
 pWrtShell->GetContentAtPos(aLogicR, aContentAtPos);
 CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::NONE, aContentAtPos.eContentAtPos);
+
+/*
+ * tdf#111969: the beginning of the hyperlink should allow the right-click 
menu to remove it
+ */
+// move cursor (with no selection) to the start of the hyperlink - after 
the N-dash
+pWrtShell->SttEndDoc(/*bStart=*/true);
+pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, 
/*bBasicCall=*/false);
+aLogicL = pWrtShell->GetCharRect().Center();
+aLogicR = aLogicL;
+
+// sanity check - we really are right in front of the hyperlink
+aLogicL.AdjustX(-1);
+aContentAtPos = IsAttrAtPos::InetAttr;
+pWrtShell->GetContentAtPos(aLogicL, aContentAtPos);
+CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::NONE, aContentAtPos.eContentAtPos);
+aLogicR.AdjustX(1);
+aContentAtPos = IsAttrAtPos::InetAttr;
+pWrtShell->GetContentAtPos(aLogicR, aContentAtPos);
+CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::InetAttr, aContentAtPos.eContentAtPos);
+
+// Remove the hyperlink
+dispatchCommand(mxComponent, ".uno:RemoveHyperlink", {});
+
+// The test: was the hyperlink actually removed?
+aContentAtPos = IsAttrAtPos::InetAttr;
+pWrtShell->GetContentAtPos(aLogicR, aContentAtPos);
+CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::NONE, aContentAtPos.eContentAtPos);
 }
 
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf111969)
diff --git a/sw/source/uibase/shells/textsh1.cxx 
b/sw/source/uibase/shells/textsh1.cxx
index 23e968ffd524..f23d5a229ec9 100644
--- a/sw/source/uibase/shells/textsh1.cxx
+++ b/sw/source/uibase/shells/textsh1.cxx
@@ -74,7 +74,9 @@
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1389,7 +1391,27 @@ void SwTextShell::Execute(SfxRequest )
 }
 break;
 case SID_EDIT_HYPERLINK:
+{
+if (!rWrtSh.HasSelection())
+{
+SfxItemSetFixed 
aSet(GetPool());
+rWrtSh.GetCurAttr(aSet);
+if (SfxItemState::SET > aSet.GetItemState(RES_TXTATR_INETFMT))
+{
+// Didn't find a hyperlink to edit yet.
+
+// If the cursor is just before an unselected hyperlink,
+// the dialog will not know that it should edit that 
hyperlink,
+// so in this case, first select it so the dialog will 
find the hyperlink.
+// The dialog would leave the hyperlink selected anyway 
after a successful edit
+// (although it isn't normally selected after a cancel, 
but oh well).
+if (!rWrtSh.SelectTextAttr(RES_TXTATR_INETFMT))
+break;
+}
+}
+
 GetView().GetViewFrame().SetChildWindow(SID_HYPERLINK_DIALOG, 
true);
+}
 break;
 case SID_REMOVE_HYPERLINK:
 {
@@ -1837,17 +1859,32 @@ void SwTextShell::Execute(SfxRequest )
 {
 SfxItemSetFixed 
aSet(GetPool());
 rWrtSh.GetCurAttr(aSet);
+
+const SwFormatINetFormat* pINetFormat = nullptr;
 if(SfxItemState::SET <= aSet.GetItemState( RES_TXTATR_INETFMT ))
+pINetFormat = (RES_TXTATR_INETFMT);
+else if (!rWrtSh.HasSelection())
 {
-const SwFormatINetFormat& rINetFormat = 
aSet.Get(RES_TXTATR_INETFMT);
+// is the cursor at the beginning of a hyperlink?
+const SwTextNode* pTextNd = 
rWrtSh.GetCursor()->GetPointNode().GetTextNode();
+ 

core.git: sw/qa sw/source

2024-01-02 Thread Justin Luth (via logerrit)
 sw/qa/extras/uiwriter/uiwriter9.cxx |2 +-
 sw/source/core/crsr/crsrsh.cxx  |1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

New commits:
commit 242f6985556af7aac77b68c6dfea20d4b32c5f52
Author: Justin Luth 
AuthorDate: Sat Dec 23 13:41:20 2023 -0500
Commit: Miklos Vajna 
CommitDate: Wed Jan 3 08:46:33 2024 +0100

tdf#111969 sw: acknowledge that last half-character for context menu

This patch depends on the previous one.

This fixes the right-click menu building features
half-a-character too early (redlines, smarttag)
and ending half-a-character too early.

Note that hyperlinks already started half-a-char too late,
now they start a whole character too late. See follow-up

Note that fields ended OK, but still started
too early until this patch.

make CppunitTest_sw_uiwriter9 CPPUNIT_TEST_NAME=testTdf111969B

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

diff --git a/sw/qa/extras/uiwriter/uiwriter9.cxx 
b/sw/qa/extras/uiwriter/uiwriter9.cxx
index 8febc2f2145e..a22ce3df306e 100644
--- a/sw/qa/extras/uiwriter/uiwriter9.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter9.cxx
@@ -151,7 +151,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf111969B)
 // the test: simulate a right-click of a mouse (at the end-edge of the 
second N-dash)
 // which sets the cursor and then acts on that pos.
 pWrtShell->SwCursorShell::SetCursor(aLogicL, false, /*Block=*/false, 
/*FieldInfo=*/true);
-//CPPUNIT_ASSERT(!pWrtShell->GetCurField(true));
+CPPUNIT_ASSERT(!pWrtShell->GetCurField(true));
 }
 
 } // end of anonymous namespace
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index ed9f47dc81c5..9448533ff75d 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -1057,6 +1057,7 @@ int SwCursorShell::SetCursor(const Point& rLPt, bool 
bOnlyText, bool bBlock, boo
 bOnlyText ?  CursorMoveState::SetOnlyText 
: CursorMoveState::NONE );
 aTmpState.m_bSetInReadOnly = IsReadOnlyAvailable();
 aTmpState.m_bFieldInfo = bFieldInfo; // always set cursor at field-start 
if point is over field
+aTmpState.m_bPosMatchesBounds = bFieldInfo; // always set cursor at 
character-start if over char
 
 SwTextNode const*const pTextNd = sw::GetParaPropsNode(*GetLayout(), 
pCursor->GetPoint()->GetNode());
 


core.git: sw/qa sw/source

2023-12-30 Thread Mike Kaganski (via logerrit)
 sw/qa/extras/layout/data/space+break.fodt |2 
 sw/qa/extras/layout/layout3.cxx   |   50 +++-
 sw/qa/extras/uiwriter/uiwriter4.cxx   |  159 +-
 sw/source/core/text/guess.cxx |  180 +++---
 sw/source/core/text/inftxt.cxx|   99 +---
 sw/source/core/text/inftxt.hxx|   19 +++
 sw/source/core/text/itrcrsr.cxx   |   18 ++-
 sw/source/core/text/itrform2.cxx  |2 
 sw/source/core/text/porlin.cxx|   14 +-
 sw/source/core/text/portxt.cxx|4 
 sw/source/core/text/txttab.cxx|2 
 11 files changed, 365 insertions(+), 184 deletions(-)

New commits:
commit 853e13f9146e83b959bc53152ec103470d55fb4f
Author: Mike Kaganski 
AuthorDate: Fri Dec 29 14:22:23 2023 +0600
Commit: Mike Kaganski 
CommitDate: Sat Dec 30 09:51:28 2023 +0100

tdf#57187: make sure to put trailing blanks to hole portion in narrow lines

This needs to avoid special processing of trailing spaces after some tabs
(tdf#106234). Also it needs to allow cursor movement over the newly added
Hole portions.

It turns out, that it also simplifies the fixes for tdf#104349 and 
tdf#104668.
The special handling of paint of the trailing blanks is not needed, when the
trailing blanks are SwHolePortion, which doesn't draw any background. Also,
there's no need in special code in SwTextGuess::Guess for that case.

This required to enable creation of the hole portions also for left-aligned
lines, which were not adjusting break position correctly, because of a wrong
condition that could never be true.

Change-Id: I0e391be7b1caee4277a505368c3b13a00b5d9506
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161400
Tested-by: Jenkins
Reviewed-by: Mike Kaganski 

diff --git a/sw/qa/extras/layout/data/space+break.fodt 
b/sw/qa/extras/layout/data/space+break.fodt
index fbd81f37f501..7b53a8b012fa 100644
--- a/sw/qa/extras/layout/data/space+break.fodt
+++ b/sw/qa/extras/layout/data/space+break.fodt
@@ -44,7 +44,7 @@
  
  
   
-   Lorem ipsum Lorem ipsum Lorem ipsum Lorem 
ipsum
+   Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem 
ipsum
   
  
 
\ No newline at end of file
diff --git a/sw/qa/extras/layout/layout3.cxx b/sw/qa/extras/layout/layout3.cxx
index 15f113754d46..da882cba559d 100644
--- a/sw/qa/extras/layout/layout3.cxx
+++ b/sw/qa/extras/layout/layout3.cxx
@@ -2125,26 +2125,62 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf152307)
 CPPUNIT_ASSERT_MESSAGE(aMsg.getStr(), nTabBottom < nFooterTop);
 }
 
-CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf158900)
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf57187_Tdf158900)
 {
 // Given a document with a single paragraph, having some long space runs 
and line breaks
 createSwDoc("space+break.fodt");
 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
-// Make sure there is only one page, one paragraph, and four lines
+// Make sure there is only one page, one paragraph, and five lines
 assertXPath(pXmlDoc, "/root/page"_ostr, 1);
 assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion"_ostr, 1);
-// Without the fix in place, this would fail: there used to be 5 lines
-assertXPath(pXmlDoc, 
"/root/page/body/txt/SwParaPortion/SwLineLayout"_ostr, 4);
-// Check that the second line has correct portions
-// Without the fix in place, this would fail: the line had only 2 portions 
(text + hole),
-// and the break was on a separate third line
+// Without the fix in place, this would fail: there used to be 6 lines
+assertXPath(pXmlDoc, 
"/root/page/body/txt/SwParaPortion/SwLineLayout"_ostr, 5);
+
+// tdf#57187: Check that relatively short lines have spaces not 
participating in layout.
+// First line has 11 spaces in the end, and then a manual line break. It 
is rather short:
+// without block justification, it is narrower than the available space.
+// It uses the "first check if everything fits to line" return path in 
SwTextGuess::Guess.
+// Check that the spaces are put into a Hole portion, thus not 
participating in layout.
+// Without the fix, this would fail: there were only 2 portions, no Hole 
nor Margin portions.
+assertXPath(pXmlDoc, 
"/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*"_ostr, 4);
+assertXPath(pXmlDoc, 
"/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*[1]"_ostr, "type"_ostr,
+u"PortionType::Text"_ustr);
+assertXPath(pXmlDoc, 
"/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*[1]"_ostr,
+"length"_ostr, u"11"_ustr);
+assertXPath(pXmlDoc, 
"/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*[2]"_ostr, "type"_ostr,
+u"PortionType::Hole"_ustr);
+assertXPath(pXmlDoc, 
"/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*[2]"_ostr,
+"length"_ostr, u"11"_ustr);
+assertXPath(pXmlDoc, 

core.git: sw/qa sw/source

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

New commits:
commit a22ac6caece8da5add6800bdfba9865bdcfde064
Author: Mike Kaganski 
AuthorDate: Thu Dec 28 15:06:56 2023 +0600
Commit: Mike Kaganski 
CommitDate: Thu Dec 28 11:18:41 2023 +0100

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


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

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


  1   2   3   4   5   6   7   8   9   10   >