summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2023-06-23 09:31:01 +0300
committerAndras Timar <andras.timar@collabora.com>2023-07-08 20:37:08 +0200
commit4d4cf7990f6d0c615ca9eb1f4bca296d01f13735 (patch)
tree3aa11190ec4cda6445eff5dd32c51d0afac2beb6 /sw
parentba498a05be02b59aa71416cc4a9313ab89b11532 (diff)
tdf#133560: re-anchor objects, to use paragraph's dispose for bEndOfDocument
1. During import, XParagraphAppend::finishParagraph(Insert) are called, which are implemented using SwXText::Impl::finishOrAppendParagraph, and the latter calls m_pDoc->getIDocumentContentOperations().AppendTextNode( *aPam.GetPoint() ); // remove attributes from the previous paragraph m_pDoc->ResetAttrs(aPam); so that there is always another (empty) paragraph after the finalized one; 2. During import, lcl_AddRange is called to create anchored text content; the start and end of it may reference the very end of the document (using xTextAppend->getEnd()) - i.e., that last (maybe empty, maybe extra) paragraph. 3. In many places, and in particular, in DomainMapper_Impl destructor, DomainMapper_Impl::RemoveLastParagraph is called; and the latter uses one of the two techniques to remove that last paragraph: 3.1. It either obtains the paragraph's lang::XComponent interface, and calls its dispose (SwXParagraph::dispose), which eventually calls DocumentContentOperationsManager::DelFullPara; 3.2. Or it uses cursor to select 1 ch back, and replace the resulting selection with nothing. 3.1 has an advantage of keeping the formatting of the remaining (second- to-last) paragraph, but DocumentContentOperationsManager::DelFullPara, among other things, removes all anchored objects, thus this mode is not used for the end-of-document case (e.g., see commit message of commit e521930ea1c855c236efb67793e540d07c201d35 "fdo#58327: writerfilter: RemoveLastParagraph is tricky:", 2013-01-10); 3.2 keeps the anchored objects, but needs workarounds to keep bookmarks, and destroys the remaining paragraph character formatting. Let me try to use #3.1 also in the end-of-document case, by introducing code to move anchored objects to previous paragraph before calling XComponent::dispose. Indeed, it may happen that more processing could be needed, if more properties would happen to be bound to the very last extra paragraph. This change adds a call to DocumentRedlineManager::CompressRedlines in DocumentContentOperationsManager::DelFullPara, because previously, this was called during #3.2 inside setString. testTdf150086 failed without this change. testTdf131386 and testTdf152872 were changed to the now-correct import of last paragraph properties (previously both of them relied on the hidden property not present there, while it is there in Word). In DomainMapper_Impl::RemoveLastParagraph, the check of the content of selection made by moving backward one character was generalized to be run before both cases, because RTF sometimes has only one paragraph after a table (see e.g. testTdf148515), which now could be removed in the absence of the check. testTdf104390 was changed to not check the number of runs, because now the paragraph keeps the trailing "paragraph mark formatting" empty run, which previously was dropped using setString path. Also, the fix for tdf#148273 is re-implemented here, by dropping RES_PARATR_LIST_AUTOFMT in lcl_RstAttr. Likely keeping it was an unintended side effect of placing RES_PARATR_LIST_AUTOFMT inside RES_PARATR_LIST_BEGIN/END. After the change, explicit drop of it will be not needed at arbitrary boundary, which is section break; this property should only be applied where it's defined. This change can't be done separately, because of interrelated unit test failures left and right. In XMLParaContext::endFastElement, setting ListAutoFormat property must be set only after setting style now, because otherwise it will be reset in lcl_RstAttr when the style is set. Some test documents were modified, to drop font from the last paragraph properties, because their respective tests started to crash (see commit 172270a8f04388a8f8062f672f9c3f3144a01a1f "abort writer layout tests if a font isn't found", 2022-05-01). Before this change, these paragraphs had lost their formatting, so those fonts weren't used in layout. Change-Id: I7e41c20e68e24c78fae1d2005c3fd75fb146ba2c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153481 Tested-by: Mike Kaganski <mike.kaganski@collabora.com> Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com> (cherry picked from commit fc1b9ab2913bc8c2d8414b6d8de3ceed3910c5d8) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153520 Tested-by: Jenkins Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154104 Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Diffstat (limited to 'sw')
-rw-r--r--sw/inc/unoprnms.hxx2
-rw-r--r--sw/qa/extras/layout/data/tdf116256.docxbin21136 -> 21085 bytes
-rw-r--r--sw/qa/extras/layout/data/tdf136613.docxbin25266 -> 25224 bytes
-rw-r--r--sw/qa/extras/layout/layout2.cxx13
-rw-r--r--sw/qa/extras/ooxmlexport/data/lastEmptyLineWithDirectFormatting.docxbin0 -> 1816 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport18.cxx11
-rw-r--r--sw/qa/extras/rtfexport/rtfexport5.cxx4
-rw-r--r--sw/qa/extras/rtfimport/rtfimport.cxx7
-rw-r--r--sw/source/core/doc/DocumentContentOperationsManager.cxx7
-rw-r--r--sw/source/core/doc/docfmt.cxx6
-rw-r--r--sw/source/core/unocore/unoobj.cxx9
11 files changed, 37 insertions, 22 deletions
diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx
index f98e8b7b2c07..b1a81877799e 100644
--- a/sw/inc/unoprnms.hxx
+++ b/sw/inc/unoprnms.hxx
@@ -541,8 +541,6 @@ inline constexpr OUStringLiteral UNO_NAME_SEPARATOR_LINE_VERTIVAL_ALIGNMENT
inline constexpr OUStringLiteral UNO_NAME_SEPARATOR_LINE_IS_ON = u"SeparatorLineIsOn";
inline constexpr OUStringLiteral UNO_NAME_IS_SKIP_HIDDEN_TEXT = u"IsSkipHiddenText";
inline constexpr OUStringLiteral UNO_NAME_IS_SKIP_PROTECTED_TEXT = u"IsSkipProtectedText";
-inline constexpr OUStringLiteral UNO_NAME_RESET_PARAGRAPH_LIST_ATTRIBUTES
- = u"ResetParagraphListAttributes";
inline constexpr OUStringLiteral UNO_NAME_NO_FORMAT_ATTR = u"NoFormatAttr";
inline constexpr OUStringLiteral UNO_NAME_DOCUMENT_INDEX_MARKS = u"DocumentIndexMarks";
inline constexpr OUStringLiteral UNO_NAME_FOOTNOTE_IS_COLLECT_AT_TEXT_END
diff --git a/sw/qa/extras/layout/data/tdf116256.docx b/sw/qa/extras/layout/data/tdf116256.docx
index f067e04f0614..6939bc99b9db 100644
--- a/sw/qa/extras/layout/data/tdf116256.docx
+++ b/sw/qa/extras/layout/data/tdf116256.docx
Binary files differ
diff --git a/sw/qa/extras/layout/data/tdf136613.docx b/sw/qa/extras/layout/data/tdf136613.docx
index a67e2f6c3b2c..cbfa8896765c 100644
--- a/sw/qa/extras/layout/data/tdf136613.docx
+++ b/sw/qa/extras/layout/data/tdf136613.docx
Binary files differ
diff --git a/sw/qa/extras/layout/layout2.cxx b/sw/qa/extras/layout/layout2.cxx
index ed42f55673c7..8bfb73c88a02 100644
--- a/sw/qa/extras/layout/layout2.cxx
+++ b/sw/qa/extras/layout/layout2.cxx
@@ -636,8 +636,8 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf152872)
assertXPath(pXmlDoc, "/root/page[1]/body/txt", 2);
assertXPath(pXmlDoc, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout", "portion", "C DE");
- assertXPath(pXmlDoc, "/root/page/body/txt[2]/SwParaPortion", 0); // 5 is empty
- assertXPath(pXmlDoc, "/root/page/body/txt[2]/infos/bounds", "height", "379");
+ assertXPath(pXmlDoc, "/root/page/body/txt[2]/SwParaPortion", 0); // 5 is empty and hidden
+ assertXPath(pXmlDoc, "/root/page/body/txt[2]/infos/bounds", "height", "0");
dispatchCommand(mxComponent, ".uno:ControlCodes", {});
@@ -652,8 +652,11 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf152872)
// and be a full-height frame now, but that needs more work...
assertXPath(pXmlDoc, "/root/page/body/txt[3]/infos/bounds", "height", "0");
assertXPath(pXmlDoc, "/root/page/body/txt[4]/SwParaPortion/SwLineLayout", "portion", "E");
+ // 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", 0); // 5 is empty
- assertXPath(pXmlDoc, "/root/page/body/txt[5]/infos/bounds", "height", "379");
+ assertXPath(pXmlDoc, "/root/page/body/txt[5]/infos/bounds", "height", "0");
dispatchCommand(mxComponent, ".uno:ControlCodes", {});
@@ -662,8 +665,8 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf152872)
assertXPath(pXmlDoc, "/root/page[1]/body/txt", 2);
assertXPath(pXmlDoc, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout", "portion", "C DE");
- assertXPath(pXmlDoc, "/root/page/body/txt[2]/SwParaPortion", 0); // 5 is empty
- assertXPath(pXmlDoc, "/root/page/body/txt[2]/infos/bounds", "height", "379");
+ assertXPath(pXmlDoc, "/root/page/body/txt[2]/SwParaPortion", 0); // 5 is empty and hidden
+ assertXPath(pXmlDoc, "/root/page/body/txt[2]/infos/bounds", "height", "0");
}
CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf151954)
diff --git a/sw/qa/extras/ooxmlexport/data/lastEmptyLineWithDirectFormatting.docx b/sw/qa/extras/ooxmlexport/data/lastEmptyLineWithDirectFormatting.docx
new file mode 100644
index 000000000000..5cfb4fcce170
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/lastEmptyLineWithDirectFormatting.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
index e686e1c3dd02..b2a4fdafeec3 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
@@ -598,6 +598,17 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf155945)
CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(getParagraph(2), "ParaBottomMargin"));
}
+CPPUNIT_TEST_FIXTURE(Test, testTdf133560)
+{
+ createSwDoc("lastEmptyLineWithDirectFormatting.docx");
+
+ CPPUNIT_ASSERT_EQUAL(4, getParagraphs());
+ // Without a fix in place, this would fail with
+ // - Expected: 12
+ // - Actual : 48
+ CPPUNIT_ASSERT_EQUAL(12.0f, getProperty<float>(getParagraph(4), "CharHeight"));
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/extras/rtfexport/rtfexport5.cxx b/sw/qa/extras/rtfexport/rtfexport5.cxx
index a93f44d763c2..d002caabad75 100644
--- a/sw/qa/extras/rtfexport/rtfexport5.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport5.cxx
@@ -1461,8 +1461,8 @@ DECLARE_RTFEXPORT_TEST(testTdf104390, "tdf104390.rtf")
CPPUNIT_ASSERT_EQUAL(36.f, getProperty<float>(xRun, "CharHeight"));
CPPUNIT_ASSERT_EQUAL(OUString("Courier New"), getProperty<OUString>(xRun, "CharFontName"));
- // Ensure there is only one run
- CPPUNIT_ASSERT_MESSAGE("Extra elements in paragraph", !xRunEnum->hasMoreElements());
+ // Ensure this run covers whole paragraph text (ignore possible empty "paragraph marker" run)
+ CPPUNIT_ASSERT_EQUAL(xPara->getString().getLength(), xRun->getString().getLength());
}
DECLARE_RTFEXPORT_TEST(testTdf153681, "tdf153681.odt")
diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx
index eb2596e44c44..144bfcf1f22e 100644
--- a/sw/qa/extras/rtfimport/rtfimport.cxx
+++ b/sw/qa/extras/rtfimport/rtfimport.cxx
@@ -1007,7 +1007,12 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf131386)
createSwDoc("hidden-para-separator.rtf");
SwDoc const* const pDoc = getSwDoc();
SwNodeIndex ix(pDoc->GetNodes().GetEndOfContent(), -1);
- CPPUNIT_ASSERT(!ix.GetNode().GetTextNode()->GetAttr(RES_PARATR_LIST_AUTOFMT).GetStyleHandle());
+ CPPUNIT_ASSERT(ix.GetNode()
+ .GetTextNode()
+ ->GetAttr(RES_PARATR_LIST_AUTOFMT)
+ .GetStyleHandle()
+ ->Get(RES_CHRATR_HIDDEN)
+ .GetValue());
--ix;
--ix;
CPPUNIT_ASSERT(ix.GetNode()
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index c8df21dd0e49..b1a14de36c3f 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -2330,6 +2330,13 @@ bool DocumentContentOperationsManager::DelFullPara( SwPaM& rPam )
rPam.DeleteMark();
m_rDoc.GetNodes().Delete( aRg.aStart, nNodeDiff+1 );
}
+
+ if (!m_rDoc.getIDocumentRedlineAccess().IsIgnoreRedline()
+ && !m_rDoc.getIDocumentRedlineAccess().GetRedlineTable().empty())
+ {
+ m_rDoc.getIDocumentRedlineAccess().CompressRedlines();
+ }
+
m_rDoc.getIDocumentState().SetModified();
return true;
diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx
index fde6f931d3f3..9e8df615959a 100644
--- a/sw/source/core/doc/docfmt.cxx
+++ b/sw/source/core/doc/docfmt.cxx
@@ -112,10 +112,10 @@ static bool lcl_RstAttr( SwNode* pNd, void* pArgs )
SwDoc& rDoc = pNode->GetDoc();
// remove unused attribute RES_LR_SPACE
- // add list attributes
+ // add list attributes, except RES_PARATR_LIST_AUTOFMT
SfxItemSetFixed<
RES_PARATR_NUMRULE, RES_PARATR_NUMRULE,
- RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END - 1,
+ RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_AUTOFMT - 1,
RES_PAGEDESC, RES_BREAK,
RES_FRMATR_STYLE_NAME, RES_FRMATR_CONDITIONAL_STYLE_NAME> aSavedAttrsSet(rDoc.GetAttrPool());
const SfxItemSet* pAttrSetOfNode = pNode->GetpSwAttrSet();
@@ -123,7 +123,7 @@ static bool lcl_RstAttr( SwNode* pNd, void* pArgs )
std::vector<sal_uInt16> aClearWhichIds;
// restoring all paragraph list attributes
{
- SfxItemSetFixed<RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END - 1> aListAttrSet( rDoc.GetAttrPool() );
+ SfxItemSetFixed<RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_AUTOFMT - 1> aListAttrSet( rDoc.GetAttrPool() );
aListAttrSet.Set(*pAttrSetOfNode);
if ( aListAttrSet.Count() )
{
diff --git a/sw/source/core/unocore/unoobj.cxx b/sw/source/core/unocore/unoobj.cxx
index 899c228bbacf..ca448c5b4eec 100644
--- a/sw/source/core/unocore/unoobj.cxx
+++ b/sw/source/core/unocore/unoobj.cxx
@@ -2264,15 +2264,6 @@ SwXTextCursor::setPropertyValue(
}
rUnoCursor.SetSkipOverProtectSections(bSet);
}
- else if (rPropertyName == UNO_NAME_RESET_PARAGRAPH_LIST_ATTRIBUTES)
- {
- SwTextNode* pTextNode= GetPaM()->GetPointNode().GetTextNode();
-
- if(pTextNode)
- {
- pTextNode->ResetAttr(RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END);
- }
- }
else if (rPropertyName == UNO_NAME_NO_FORMAT_ATTR)
{
bool bSet(false);