sw/qa/extras/ooxmlexport/data/tdf131801.docx |binary sw/qa/extras/ooxmlexport/ooxmlexport15.cxx | 52 ++++++++++++++++++++++ sw/source/core/attr/swatrset.cxx | 10 ++++ sw/source/core/text/txtfld.cxx | 31 +++++++++++-- sw/source/core/unocore/unoobj.cxx | 11 ++++ sw/source/filter/ww8/wrtw8nds.cxx | 3 - writerfilter/source/dmapper/DomainMapper_Impl.cxx | 4 - 7 files changed, 102 insertions(+), 9 deletions(-)
New commits: commit c77b9c349f0a48392d8cb7a49532844b2cafb5ba Author: Vasily Melenchuk <[email protected]> AuthorDate: Tue Aug 18 17:59:26 2020 +0200 Commit: Michael Stahl <[email protected]> CommitDate: Fri Aug 28 17:30:57 2020 +0200 tdf#131801: sw: support of style references in ListAutoFormat ListAutoFormat property did support char attributes, but not style references ("CharStyleName"). It is important for correct formatting of pilcrow symbol or list format in some DOCX scenarios. Export to DOCX already works, but not to RTF/DOC. Change-Id: I1bf23d1e45fcc213adcf9aa6f404be803919fbee Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100893 Tested-by: Michael Stahl <[email protected]> Reviewed-by: Michael Stahl <[email protected]> diff --git a/sw/qa/extras/ooxmlexport/data/tdf131801.docx b/sw/qa/extras/ooxmlexport/data/tdf131801.docx new file mode 100644 index 000000000000..61872b5399f5 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf131801.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx index 601a9cc742ce..821a254ea0fe 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx @@ -12,6 +12,7 @@ #include <com/sun/star/drawing/FillStyle.hpp> #include <tools/color.hxx> #include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/NamedValue.hpp> #include <com/sun/star/text/RelOrientation.hpp> #include <com/sun/star/text/XTextViewCursorSupplier.hpp> #include <com/sun/star/text/XPageCursor.hpp> @@ -46,6 +47,57 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf123621, "tdf123621.docx") "/wp:positionV/wp:posOffset", "1080135"); } +DECLARE_OOXMLIMPORT_TEST(testTdf131801, "tdf131801.docx") +{ + CPPUNIT_ASSERT_EQUAL(1, getPages()); + + xmlDocUniquePtr pDump = parseLayoutDump(); + // "1." is red + CPPUNIT_ASSERT_EQUAL(OUString("1."), getXPath(pDump, "//page[1]/body/txt[1]/Special", "rText")); + CPPUNIT_ASSERT_EQUAL(OUString("00ff0000"), getXPath(pDump, "//page[1]/body/txt[1]/Special/SwFont", "color")); + // "2." is red + CPPUNIT_ASSERT_EQUAL(OUString("2."), getXPath(pDump, "//page[1]/body/txt[2]/Special", "rText")); + CPPUNIT_ASSERT_EQUAL(OUString("00ff0000"), getXPath(pDump, "//page[1]/body/txt[2]/Special/SwFont", "color")); + // "3." is black + CPPUNIT_ASSERT_EQUAL(OUString("3."), getXPath(pDump, "//page[1]/body/txt[3]/Special", "rText")); + CPPUNIT_ASSERT_EQUAL(OUString("ffffffff"), getXPath(pDump, "//page[1]/body/txt[3]/Special/SwFont", "color")); + // "4." is black + CPPUNIT_ASSERT_EQUAL(OUString("4."), getXPath(pDump, "//page[1]/body/txt[4]/Special", "rText")); + CPPUNIT_ASSERT_EQUAL(OUString("ffffffff"), getXPath(pDump, "//page[1]/body/txt[4]/Special/SwFont", "color")); + // "5." is red + CPPUNIT_ASSERT_EQUAL(OUString("5."), getXPath(pDump, "//page[1]/body/txt[5]/Special", "rText")); + CPPUNIT_ASSERT_EQUAL(OUString("00ff0000"), getXPath(pDump, "//page[1]/body/txt[5]/Special/SwFont", "color")); + // "6." is red + CPPUNIT_ASSERT_EQUAL(OUString("6."), getXPath(pDump, "//page[1]/body/txt[6]/Special", "rText")); + CPPUNIT_ASSERT_EQUAL(OUString("00ff0000"), getXPath(pDump, "//page[1]/body/txt[6]/Special/SwFont", "color")); + // "7." is black + CPPUNIT_ASSERT_EQUAL(OUString("7."), getXPath(pDump, "//page[1]/body/txt[7]/Special", "rText")); + CPPUNIT_ASSERT_EQUAL(OUString("ffffffff"), getXPath(pDump, "//page[1]/body/txt[7]/Special/SwFont", "color")); + // "8." is black + CPPUNIT_ASSERT_EQUAL(OUString("8."), getXPath(pDump, "//page[1]/body/txt[8]/Special[1]", "rText")); + CPPUNIT_ASSERT_EQUAL(OUString("ffffffff"), getXPath(pDump, "//page[1]/body/txt[8]/Special[1]/SwFont", "color")); + + xmlDocUniquePtr pXmlDocument = parseExport("word/document.xml"); + if (!pXmlDocument) + return; + + assertXPath(pXmlDocument, "/w:document/w:body/w:p[1]/w:pPr/w:rPr/w:rStyle", + "val", "Emphasis"); + assertXPath(pXmlDocument, "/w:document/w:body/w:p[2]/w:pPr/w:rPr/w:rStyle", + "val", "Emphasis"); + assertXPath(pXmlDocument, "/w:document/w:body/w:p[3]/w:pPr/w:rPr/w:rStyle", 0); + assertXPath(pXmlDocument, "/w:document/w:body/w:p[4]/w:pPr/w:rPr/w:rStyle", 0); + assertXPath(pXmlDocument, "/w:document/w:body/w:p[5]/w:pPr/w:rPr/w:rStyle", + "val", "Emphasis"); + assertXPath(pXmlDocument, "/w:document/w:body/w:p[5]/w:pPr/w:rPr/w:sz", + "val", "32"); + assertXPath(pXmlDocument, "/w:document/w:body/w:p[6]/w:pPr/w:rPr/w:rStyle", + "val", "Emphasis"); + assertXPath(pXmlDocument, "/w:document/w:body/w:p[6]/w:pPr/w:rPr/w:sz", + "val", "32"); + assertXPath(pXmlDocument, "/w:document/w:body/w:p[7]/w:pPr/w:rPr/w:rStyle", 0); + assertXPath(pXmlDocument, "/w:document/w:body/w:p[8]/w:pPr/w:rPr/w:rStyle", 0); +} DECLARE_OOXMLEXPORT_TEST(testTdf133334_followPgStyle, "tdf133334_followPgStyle.odt") { diff --git a/sw/source/core/attr/swatrset.cxx b/sw/source/core/attr/swatrset.cxx index d62df7e94719..aa6d9f1ad088 100644 --- a/sw/source/core/attr/swatrset.cxx +++ b/sw/source/core/attr/swatrset.cxx @@ -21,6 +21,7 @@ #include <cellatr.hxx> #include <charfmt.hxx> +#include <fchrfmt.hxx> #include <doc.hxx> #include <IDocumentListsAccess.hxx> #include <editeng/editeng.hxx> @@ -404,6 +405,15 @@ void SwAttrSet::CopyToModify( SwModify& rMod ) const SfxItemSet const& rAutoStyle(*static_cast<SwFormatAutoFormat const&>(*pItem).GetStyleHandle()); std::shared_ptr<SfxItemSet> const pNewSet( rAutoStyle.SfxItemSet::Clone(true, &pDstDoc->GetAttrPool())); + + // fix up character style, it contains pointers to pSrcDoc + if (SfxItemState::SET == pNewSet->GetItemState(RES_TXTATR_CHARFMT, false, &pItem)) + { + auto const* pChar(static_cast<SwFormatCharFormat const*>(pItem)); + SwCharFormat *const pCopy(pDstDoc->CopyCharFormat(*pChar->GetCharFormat())); + const_cast<SwFormatCharFormat*>(pChar)->SetCharFormat(pCopy); + } + SwFormatAutoFormat item(RES_PARATR_LIST_AUTOFMT); // TODO: for ODF export we'd need to add it to the autostyle pool item.SetStyleHandle(pNewSet); diff --git a/sw/source/core/text/txtfld.cxx b/sw/source/core/text/txtfld.cxx index 18cd5e627286..7e7aa65f3c43 100644 --- a/sw/source/core/text/txtfld.cxx +++ b/sw/source/core/text/txtfld.cxx @@ -53,6 +53,7 @@ #include <redline.hxx> #include <sfx2/docfile.hxx> #include <svl/itemiter.hxx> +#include <svl/whiter.hxx> #include <editeng/colritem.hxx> #include <editeng/udlnitem.hxx> #include <editeng/crossedoutitem.hxx> @@ -462,9 +463,34 @@ static void checkApplyParagraphMarkFormatToNumbering(SwFont* pNumFnt, SwTextForm std::unique_ptr<SfxItemSet> const pCleanedSet = pSet->Clone(); + if (pCleanedSet->HasItem(RES_TXTATR_CHARFMT)) + { + // Insert attributes of referenced char format into current set + const SwFormatCharFormat& rCharFormat = pCleanedSet->Get(RES_TXTATR_CHARFMT); + const SwAttrSet& rStyleAttrs = static_cast<const SwCharFormat *>(rCharFormat.GetRegisteredIn())->GetAttrSet(); + SfxWhichIter aIter(rStyleAttrs); + sal_uInt16 nWhich = aIter.FirstWhich(); + while (nWhich) + { + if (!SwTextNode::IsIgnoredCharFormatForNumbering(nWhich) + && !pCleanedSet->HasItem(nWhich) + && !(pFormat && pFormat->HasItem(nWhich)) ) + { + // Copy from parent sets only allowed items which will not overwrite + // values explicitly defined in current set (pCleanedSet) or in pFormat + const SfxPoolItem* pItem = rStyleAttrs.GetItem(nWhich, true); + pCleanedSet->Put(*pItem); + } + nWhich = aIter.NextWhich(); + } + + // It is not required here anymore, all referenced items are inserted + pCleanedSet->ClearItem(RES_TXTATR_CHARFMT); + }; + SfxItemIter aIter(*pSet); const SfxPoolItem* pItem = aIter.GetCurItem(); - do + while (pItem) { if (pItem->Which() != RES_CHRATR_BACKGROUND) { @@ -473,9 +499,8 @@ static void checkApplyParagraphMarkFormatToNumbering(SwFont* pNumFnt, SwTextForm else if (pFormat && pFormat->HasItem(pItem->Which())) pCleanedSet->ClearItem(pItem->Which()); } - pItem = aIter.NextItem(); - } while (pItem); + }; pNumFnt->SetDiffFnt(pCleanedSet.get(), pIDSA); } diff --git a/sw/source/core/unocore/unoobj.cxx b/sw/source/core/unocore/unoobj.cxx index 66bf10f7bd82..01d777dccd4b 100644 --- a/sw/source/core/unocore/unoobj.cxx +++ b/sw/source/core/unocore/unoobj.cxx @@ -519,7 +519,10 @@ SwUnoCursorHelper::SetCursorPropertyValue( // TODO create own map for this, it contains UNO_NAME_DISPLAY_NAME? or make property readable so ODF export can map it to a automatic style? SfxItemPropertySet const& rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_CHAR_AUTO_STYLE)); SfxItemPropertyMap const& rMap(rPropSet.getPropertyMap()); - SfxItemSet items{rPam.GetDoc()->GetAttrPool(), aCharAutoFormatSetRange}; + SfxItemSet items( rPam.GetDoc()->GetAttrPool(), + svl::Items<RES_CHRATR_BEGIN, RES_CHRATR_END-1, + RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT, + RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1>{} ); for (beans::NamedValue const & prop : std::as_const(props)) { @@ -527,6 +530,11 @@ SwUnoCursorHelper::SetCursorPropertyValue( rMap.getByName(prop.Name); if (!pEntry) { + if (prop.Name == "CharStyleName") + { + lcl_setCharStyle(rPam.GetDoc(), prop.Value, items); + continue; + } throw beans::UnknownPropertyException( "Unknown property: " + prop.Name); } @@ -540,6 +548,7 @@ SwUnoCursorHelper::SetCursorPropertyValue( SwFormatAutoFormat item(RES_PARATR_LIST_AUTOFMT); // TODO: for ODF export we'd need to add it to the autostyle pool + // note: paragraph auto styles have ParaStyleName property for the parent style; character auto styles currently do not because there's a separate hint, but for this it would be a good way to add it in order to export it as style:parent-style-name, see XMLTextParagraphExport::Add() item.SetStyleHandle(std::make_shared<SfxItemSet>(items)); pTextNd->SetAttr(item); } diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx index 560a6065a373..da882d0cd4c6 100644 --- a/sw/source/filter/ww8/wrtw8nds.cxx +++ b/sw/source/filter/ww8/wrtw8nds.cxx @@ -3088,9 +3088,8 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode ) { aParagraphMarkerProperties.Put(*pSet); bCharFormatOnly = false; - // TODO: still need to check for a RES_TXTATR_CHARFMT hint... } - if (const SwpHints* pTextAttrs = rNode.GetpSwpHints()) + else if (const SwpHints* pTextAttrs = rNode.GetpSwpHints()) { for( size_t i = 0; i < pTextAttrs->Count(); ++i ) { diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index e699aa51b0ff..0347453d6704 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -1628,9 +1628,7 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap, con { // this condition isn't ideal but as it happens all // RES_CHRATR_* have names that start with "Char" - if (it->Name.startsWith("Char") -// TODO testParagraphMark *wants* this but it's some effort to create a real SwFormatCharFormat... - && !it->Name.startsWith("CharStyleName")) + if (it->Name.startsWith("Char")) { charProperties.emplace_back(it->Name, it->Value); // as testN793262 demonstrates, font size in rPr must _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
