sw/qa/extras/uiwriter/data/placeholder-bold.fodt | 114 +++++++++++++++++++++++ sw/qa/extras/uiwriter/uiwriter3.cxx | 49 +++++++++ sw/source/filter/html/swhtml.cxx | 14 ++ sw/source/filter/html/swhtml.hxx | 2 4 files changed, 179 insertions(+)
New commits: commit f45d2fa85ba89eb7d71b51c3324f5938509b3201 Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Thu Aug 8 17:41:05 2024 +0200 Commit: Michael Stahl <michael.st...@allotropia.de> CommitDate: Fri Aug 9 13:57:07 2024 +0200 sw: HTML import: apply existing hard formatting at insert position When selecting a placeholder field and pasting some HTML over it, the existing formatting of the placeholder field is inconsistently retained on the first paragraph of the pasted text, but not on subsequent ones. Fix this by retaining it on all of the pasted text; copy it after doing the 2 SplitNode() calls in SwHTMLParser::CallParser() and apply it directly to new paragraphs in SwHTMLParser::SetTextCollAttrs() after applying the paragraph style (which resets hard formatting). Change-Id: I8c3596372b415fece46f6bb018cb8c26ff89c5ad Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171648 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> diff --git a/sw/qa/extras/uiwriter/data/placeholder-bold.fodt b/sw/qa/extras/uiwriter/data/placeholder-bold.fodt new file mode 100644 index 000000000000..55ecf66df714 --- /dev/null +++ b/sw/qa/extras/uiwriter/data/placeholder-bold.fodt @@ -0,0 +1,114 @@ +<?xml version='1.0' encoding='UTF-8'?> +<office:document 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: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"> + <office:meta><meta:creation-date>2024-08-08T18:32:28.420082817</meta:creation-date><dc:date>2024-08-08T18:33:51.021911316</dc:date><meta:editing-duration>PT1M27S</meta:editing-duration><meta:editing-cycles>1</meta:editing-cycles><meta:document-statistic meta:table-count="0" meta:image-count="0" meta:object-count="0" meta:page-count="1" meta:paragraph-count="1" meta:word-count="3" meta:character-count="21" meta:non-whitespace-character-count="19"/><meta:generator>ZetaOffice/7.4.8.0.0$Linux_X86_64 LibreOffice_project/ab7057b1137e2241f51e62b58a0c605ec9a4b29c</meta:generator></office:meta> + <office:font-face-decls> + <style:font-face style:name="Arial Unicode MS1" svg:font-family="'Arial Unicode MS'" style:font-family-generic="system" style:font-pitch="variable"/> + <style:font-face style:name="Liberation Serif" svg:font-family="'Liberation Serif'" style:font-family-generic="roman" style:font-pitch="variable"/> + <style:font-face style:name="Noto Serif CJK SC" svg:font-family="'Noto Serif CJK SC'" style:font-family-generic="system" style:font-pitch="variable"/> + </office:font-face-decls> + <office:styles> + <style:default-style style:family="graphic"> + <style:graphic-properties svg:stroke-color="#3465a4" draw:fill-color="#729fcf" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.3cm" draw:shadow-offset-y="0.3cm" draw:start-line-spacing-horizontal="0.283cm" draw:start-line-spacing-vertical="0.283cm" draw:end-line-spacing-horizontal="0.283cm" draw:end-line-spacing-vertical="0.283cm" style:flow-with-text="false"/> + <style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" style:writing-mode="lr-tb" style:font-independent-line-spacing="false"> + <style:tab-stops/> + </style:paragraph-properties> + <style:text-properties style:use-window-font-color="true" loext:opacity="0%" loext:color-lum-mod="100%" loext:color-lum-off="0%" style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="de" fo:country="DE" style:letter-kerning="true" style:font-name-asian="Noto Serif CJK SC" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Arial Unicode MS1" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN"/> + </style:default-style> + <style:default-style style:family="paragraph"> + <style:paragraph-properties fo:orphans="2" fo:widows="2" fo:hyphenation-ladder-count="no-limit" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="1.251cm" style:writing-mode="page"/> + <style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="de" fo:country="DE" style:letter-kerning="true" style:font-name-asian="Noto Serif CJK SC" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Arial Unicode MS1" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2" loext:hyphenation-no-caps="false" loext:hyphenation-no-last-word="false" loext:hyphenation-word-char-count="5" loext:hyphenation-zone="no-limit"/> + </style:default-style> + <style:default-style style:family="table"> + <style:table-properties table:border-model="collapsing"/> + </style:default-style> + <style:default-style style:family="table-row"> + <style:table-row-properties fo:keep-together="auto"/> + </style:default-style> + <style:style style:name="Standard" style:family="paragraph" style:class="text"/> + <text:outline-style style:name="Outline"> + <text:outline-level-style text:level="1" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="2" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="3" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="4" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="5" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="6" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="7" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="8" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="9" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="10" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + </text:outline-style> + <text:notes-configuration text:note-class="footnote" style:num-format="1" text:start-value="0" text:footnotes-position="page" text:start-numbering-at="document"/> + <text:notes-configuration text:note-class="endnote" style:num-format="i" text:start-value="0"/> + <text:linenumbering-configuration text:number-lines="false" text:offset="0.499cm" style:num-format="1" text:number-position="left" text:increment="5"/> + </office:styles> + <office:automatic-styles> + <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Standard"> + <style:text-properties/> + </style:style> + <style:style style:name="T1" style:family="text"> + <style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/> + </style:style> + <style:page-layout style:name="pm1"> + <style:page-layout-properties fo:page-width="21.001cm" fo:page-height="29.7cm" style:num-format="1" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm" style:writing-mode="lr-tb" style:footnote-max-height="0cm" loext:margin-gutter="0cm"> + <style:footnote-sep style:width="0.018cm" style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" style:line-style="solid" style:adjustment="left" style:rel-width="25%" style:color="#000000"/> + </style:page-layout-properties> + <style:header-style/> + <style:footer-style/> + </style:page-layout> + </office:automatic-styles> + <office:master-styles> + <style:master-page style:name="Standard" style:page-layout-name="pm1"/> + </office:master-styles> + <office:body> + <office:text> + <text:sequence-decls> + <text:sequence-decl text:display-outline-level="0" text:name="Illustration"/> + <text:sequence-decl text:display-outline-level="0" text:name="Table"/> + <text:sequence-decl text:display-outline-level="0" text:name="Text"/> + <text:sequence-decl text:display-outline-level="0" text:name="Drawing"/> + <text:sequence-decl text:display-outline-level="0" text:name="Figure"/> + </text:sequence-decls> + <text:p text:style-name="P1">Test <text:span text:style-name="T1"><text:placeholder text:placeholder-type="text" text:description="to be replaced"><replaceme></text:placeholder></text:span><text:s/>test</text:p> + </office:text> + </office:body> +</office:document> \ No newline at end of file diff --git a/sw/qa/extras/uiwriter/uiwriter3.cxx b/sw/qa/extras/uiwriter/uiwriter3.cxx index ecd1f07a7d99..870b0fb80800 100644 --- a/sw/qa/extras/uiwriter/uiwriter3.cxx +++ b/sw/qa/extras/uiwriter/uiwriter3.cxx @@ -10,6 +10,7 @@ #include <swmodeltestbase.hxx> #include <LibreOfficeKit/LibreOfficeKitEnums.h> #include <vcl/scheduler.hxx> +#include <com/sun/star/awt/FontWeight.hpp> #include <com/sun/star/table/TableBorder2.hpp> #include <com/sun/star/text/XDocumentIndex.hpp> #include <com/sun/star/text/XTextFrame.hpp> @@ -39,6 +40,54 @@ public: } }; +CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testPlaceholderHTMLPaste) +{ + { + createSwDoc(); + + SwDoc* const pDoc = getSwDoc(); + SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + pWrtShell->Insert(u"AAA"_ustr); + pWrtShell->SplitNode(); + pWrtShell->Insert(u"BBB"_ustr); + pWrtShell->SplitNode(); + pWrtShell->Insert(u"CCC"_ustr); + + dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {}); + dispatchCommand(mxComponent, u".uno:Copy"_ustr, {}); + } + + createSwDoc("placeholder-bold.fodt"); + + // select placeholder field + SwDoc* const pDoc = getSwDoc(); + SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 5, /*bBasicCall=*/false); + pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false); + + // Paste special as HTML + uno::Sequence<beans::PropertyValue> aPropertyValues = comphelper::InitPropertySequence( + { { "SelectedFormat", uno::Any(static_cast<sal_uInt32>(SotClipboardFormatId::HTML)) } }); + + dispatchCommand(mxComponent, u".uno:ClipboardFormatItems"_ustr, aPropertyValues); + + CPPUNIT_ASSERT_EQUAL(int(4), getParagraphs()); + + CPPUNIT_ASSERT_EQUAL( + awt::FontWeight::NORMAL, + getProperty<float>(getRun(getParagraph(1), 1, u"Test "_ustr), u"CharWeight"_ustr)); + CPPUNIT_ASSERT_EQUAL( + awt::FontWeight::BOLD, + getProperty<float>(getRun(getParagraph(1), 2, u"AAA"_ustr), u"CharWeight"_ustr)); + CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, + getProperty<float>(getParagraph(2), u"CharWeight"_ustr)); + CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, + getProperty<float>(getParagraph(3), u"CharWeight"_ustr)); + CPPUNIT_ASSERT_EQUAL( + awt::FontWeight::NORMAL, + getProperty<float>(getRun(getParagraph(4), 1, u" test"_ustr), u"CharWeight"_ustr)); +} + CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf151974) { createSwDoc("tdf151974.odt"); diff --git a/sw/source/filter/html/swhtml.cxx b/sw/source/filter/html/swhtml.cxx index 767ce605fbf7..3ce6c858d3ab 100644 --- a/sw/source/filter/html/swhtml.cxx +++ b/sw/source/filter/html/swhtml.cxx @@ -578,6 +578,13 @@ SvParserState SwHTMLParser::CallParser() aInsertionRangePam.Move( fnMoveBackward ); m_xDoc->getIDocumentRedlineAccess().SplitRedline( aInsertionRangePam ); + if (SwAttrSet const*const pAttrs = pPos->GetNode().GetTextNode()->GetpSwAttrSet()) + { + m_pTargetCharAttrs.reset(new SfxItemSet(*pAttrs->GetPool(), + svl::Items<RES_CHRATR_BEGIN, RES_CHRATR_END-1>)); + m_pTargetCharAttrs->Put(*pAttrs); + } + m_xDoc->SetTextFormatColl( *m_pPam, m_pCSS1Parser->GetTextCollFromPool( RES_POOLCOLL_STANDARD )); } @@ -4812,6 +4819,13 @@ void SwHTMLParser::SetTextCollAttrs( HTMLAttrContext *pContext ) // set the style m_xDoc->SetTextFormatColl( *m_pPam, pCollToSet ); + if (m_pTargetCharAttrs) + { + std::unique_ptr<SfxItemSet> const pCharSet(new SfxItemSet(*m_pTargetCharAttrs)); + pCharSet->Differentiate(pCollToSet->GetAttrSet()); + m_xDoc->getIDocumentContentOperations().InsertItemSet(*m_pPam, *pCharSet); + } + // if applicable correct the paragraph indent const SvxFirstLineIndentItem & rFirstLine = pCollToSet->GetFirstLineIndent(); const SvxTextLeftMarginItem & rTextLeftMargin = pCollToSet->GetTextLeftMargin(); diff --git a/sw/source/filter/html/swhtml.hxx b/sw/source/filter/html/swhtml.hxx index 33f03ecf3fc3..1f50803633dc 100644 --- a/sw/source/filter/html/swhtml.hxx +++ b/sw/source/filter/html/swhtml.hxx @@ -500,6 +500,8 @@ class SwHTMLParser : public SfxHTMLParser, public SvtListener /// This is the URL of the outer <object> data if it's not OLE2 or an image. OUString m_aEmbedURL; + std::unique_ptr<SfxItemSet> m_pTargetCharAttrs; + void DeleteFormImpl(); void DocumentDetected();