summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Specht <oliver.specht@cib.de>2023-12-05 13:28:36 +0100
committerThorsten Behrens <thorsten.behrens@allotropia.de>2024-02-16 01:27:06 +0100
commit660f366a78ffcad429458acc429e0579d1af5495 (patch)
treec0755fd2d6b887f43fbeef03654d70311f353984
parentUpdate git submodules (diff)
downloadcore-660f366a78ffcad429458acc429e0579d1af5495.tar.gz
core-660f366a78ffcad429458acc429e0579d1af5495.zip
tdf#158044 writerfilter: handle toggle properties in import/export
DOCX has some odd properties (bold, italic, shadowed, hidden ...), which switch on/off if they are applied multiple times, e.g. with paragraph and character styles. To fix that, a hard attribute has to switch off the attribute in that occasion on import and on export a hard attribute switches it on in Word. Includes partial fix for tdf#154370. Change-Id: Ie4c317cf9b7d02efd89b9d6a9996143585d7e937 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160343 Tested-by: Jenkins Reviewed-by: Thorsten Behrens <thorsten.behrens@allotropia.de> (cherry picked from commit 9e127010a86b3521c803ac86c0b5f58dc8e2966b) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161018 (cherry picked from commit b6c4dd27acdd08fa63f8d75dd09212828e28844f) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163452
-rwxr-xr-xsw/qa/extras/ooxmlexport/data/tdf158044.odtbin0 -> 14032 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport21.cxx32
-rwxr-xr-xsw/qa/extras/ooxmlimport/data/tdf154370.docxbin0 -> 6333 bytes
-rw-r--r--sw/qa/extras/ooxmlimport/ooxmlimport2.cxx77
-rw-r--r--sw/source/filter/ww8/wrtw8nds.cxx152
-rw-r--r--sw/source/filter/ww8/wrtww8.hxx2
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx160
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.hxx4
8 files changed, 401 insertions, 26 deletions
diff --git a/sw/qa/extras/ooxmlexport/data/tdf158044.odt b/sw/qa/extras/ooxmlexport/data/tdf158044.odt
new file mode 100755
index 000000000000..ca17b6625674
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf158044.odt
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
index a6df0bff9300..a9d01670aab6 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
@@ -44,6 +44,38 @@ DECLARE_OOXMLEXPORT_TEST(testTdf153909_followTextFlow, "tdf153909_followTextFlow
CPPUNIT_ASSERT(nTableTop > nRectBottom);
}
+CPPUNIT_TEST_FIXTURE(Test, testtdf158044)
+{
+ loadAndSave("tdf158044.odt");
+ // write hard attributes to prevent multiple toggle attributes from vanishing
+ xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r[2]/w:rPr[1]/w:rStyle[1]", "val",
+ "BoldItalicCapsEmbossedStrike");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r[2]/w:rPr[1]/w:b[1]");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r[2]/w:rPr[1]/w:bCs[1]");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r[2]/w:rPr[1]/w:i[1]");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r[2]/w:rPr[1]/w:iCs[1]");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r[2]/w:rPr[1]/w:strike[1]");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r[2]/w:rPr[1]/w:emboss[1]");
+
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:r[4]/w:rPr[1]/w:rStyle[1]", "val",
+ "SmallcapsImprint");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:r[4]/w:rPr[1]/w:imprint[1]");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:r[4]/w:rPr[1]/w:smallCaps[1]");
+
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[4]/w:r[2]/w:rPr[1]/w:rStyle[1]", "val", "AllCaps");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[4]/w:r[2]/w:rPr[1]/w:caps[1]");
+
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[6]/w:r[2]/w:rPr[1]/w:rStyle[1]", "val", "Hidden");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[6]/w:r[2]/w:rPr[1]/w:vanish[1]");
+
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[8]/w:r[4]/w:rPr[1]/w:rStyle[1]", "val",
+ "OutlineShadow");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[8]/w:r[4]/w:rPr[1]/w:outline[1]");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[8]/w:r[4]/w:rPr[1]/w:shadow[1]");
+}
+
CPPUNIT_TEST_FIXTURE(Test, testTdf159207_footerFramePrBorder)
{
loadFromFile(u"tdf159207_footerFramePrBorder.docx"); // re-imports as editeng Frame/Shape
diff --git a/sw/qa/extras/ooxmlimport/data/tdf154370.docx b/sw/qa/extras/ooxmlimport/data/tdf154370.docx
new file mode 100755
index 000000000000..ba72724593b2
--- /dev/null
+++ b/sw/qa/extras/ooxmlimport/data/tdf154370.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
index 6edd873dc7ed..956d6dd3464c 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
@@ -1194,6 +1194,83 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf141969)
CPPUNIT_ASSERT_EQUAL(8.0f, getProperty<float>(xRun, "CharHeight"));
}
+CPPUNIT_TEST_FIXTURE(Test, testTdf154370)
+{
+ // Import a file with pargraph and character styles containing toggle properties applied to the end of
+ // the paragraphs. Should result in hard attributes resetting the properties
+ createSwDoc("tdf154370.docx");
+ {
+ auto xPara(getParagraph(2));
+ auto xRun = getRun(xPara, 2);
+
+ OUString rangeText = xRun->getString();
+ CPPUNIT_ASSERT_EQUAL(OUString("CharStyle BoldItalicCapsEmbossedStrike"), rangeText);
+
+ const uno::Reference<beans::XPropertyState> xRangePropState(xRun, uno::UNO_QUERY_THROW);
+ beans::PropertyState ePropertyState = xRangePropState->getPropertyState("CharWeight");
+ CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, ePropertyState);
+
+ ePropertyState = xRangePropState->getPropertyState("CharWeightComplex");
+ CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, ePropertyState);
+
+ ePropertyState = xRangePropState->getPropertyState("CharWeightAsian");
+ CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, ePropertyState);
+
+ ePropertyState = xRangePropState->getPropertyState("CharPosture");
+ CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, ePropertyState);
+
+ ePropertyState = xRangePropState->getPropertyState("CharPostureAsian");
+ CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, ePropertyState);
+
+ ePropertyState = xRangePropState->getPropertyState("CharCaseMap");
+ CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, ePropertyState);
+
+ ePropertyState = xRangePropState->getPropertyState("CharRelief");
+ CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, ePropertyState);
+
+ ePropertyState = xRangePropState->getPropertyState("CharStrikeout");
+ CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, ePropertyState);
+ }
+ {
+ auto xPara(getParagraph(3));
+ auto xRun = getRun(xPara, 2);
+
+ OUString rangeText = xRun->getString();
+ CPPUNIT_ASSERT_EQUAL(OUString("CharStyle SmallcapsImprint"), rangeText);
+
+ const uno::Reference<beans::XPropertyState> xRangePropState(xRun, uno::UNO_QUERY_THROW);
+ beans::PropertyState ePropertyState = xRangePropState->getPropertyState("CharCaseMap");
+ CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, ePropertyState);
+
+ ePropertyState = xRangePropState->getPropertyState("CharRelief");
+ CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, ePropertyState);
+ }
+ {
+ auto xPara(getParagraph(5));
+ auto xRun = getRun(xPara, 2);
+
+ OUString rangeText = xRun->getString();
+ CPPUNIT_ASSERT_EQUAL(OUString("CharStyle Hidden"), rangeText);
+
+ const uno::Reference<beans::XPropertyState> xRangePropState(xRun, uno::UNO_QUERY_THROW);
+ beans::PropertyState ePropertyState = xRangePropState->getPropertyState("CharHidden");
+ CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, ePropertyState);
+ }
+ {
+ auto xPara(getParagraph(7));
+ auto xRun = getRun(xPara, 2);
+
+ OUString rangeText = xRun->getString();
+ CPPUNIT_ASSERT_EQUAL(OUString("OutlineShadow"), rangeText);
+
+ const uno::Reference<beans::XPropertyState> xRangePropState(xRun, uno::UNO_QUERY_THROW);
+ beans::PropertyState ePropertyState = xRangePropState->getPropertyState("CharContoured");
+ CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, ePropertyState);
+
+ ePropertyState = xRangePropState->getPropertyState("CharShadowed");
+ CPPUNIT_ASSERT_EQUAL(beans::PropertyState_DIRECT_VALUE, ePropertyState);
+ }
+}
// tests should only be added to ooxmlIMPORT *if* they fail round-tripping in ooxmlEXPORT
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx
index d2e57406f8b3..e27137946ef5 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -33,12 +33,18 @@
#include <editeng/svxfont.hxx>
#include <editeng/lrspitem.hxx>
#include <editeng/brushitem.hxx>
+#include <editeng/charhiddenitem.hxx>
+#include <editeng/charreliefitem.hxx>
+#include <editeng/contouritem.hxx>
+#include <editeng/crossedoutitem.hxx>
#include <editeng/fontitem.hxx>
#include <editeng/keepitem.hxx>
#include <editeng/fhgtitem.hxx>
#include <editeng/ulspitem.hxx>
#include <editeng/formatbreakitem.hxx>
#include <editeng/frmdiritem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/shdditem.hxx>
#include <editeng/tstpitem.hxx>
#include <editeng/wghtitem.hxx>
#include <svl/grabbagitem.hxx>
@@ -77,11 +83,14 @@
#include <txtatr.hxx>
#include <cellatr.hxx>
#include <fmtrowsplt.hxx>
+#include <com/sun/star/awt/FontRelief.hpp>
+#include <com/sun/star/awt/FontStrikeout.hpp>
#include <com/sun/star/drawing/XShape.hpp>
#include <com/sun/star/i18n/BreakIterator.hpp>
#include <com/sun/star/i18n/ScriptType.hpp>
#include <com/sun/star/i18n/WordType.hpp>
#include <com/sun/star/text/RubyPosition.hpp>
+#include <com/sun/star/style/CaseMap.hpp>
#include <oox/export/vmlexport.hxx>
#include <sal/log.hxx>
#include <comphelper/propertysequence.hxx>
@@ -479,9 +488,9 @@ void SwWW8AttrIter::OutAttr(sal_Int32 nSwPos, bool bWriteCombChars)
ClearOverridesFromSet( *pCharFormatItem, aExportSet );
// check toggle properties in DOCX output
+ if (pCharFormatItem)
{
- SvxWeightItem aBoldProperty(WEIGHT_BOLD, RES_CHRATR_WEIGHT);
- handleToggleProperty(aExportSet, pCharFormatItem, RES_CHRATR_WEIGHT, &aBoldProperty);
+ handleToggleProperty(aExportSet, *pCharFormatItem);
}
// tdf#113790: AutoFormat style overwrites char style, so remove all
@@ -558,29 +567,82 @@ void SwWW8AttrIter::OutAttr(sal_Int32 nSwPos, bool bWriteCombChars)
// i.e., the effective value to be applied to the content shall be true if its effective value is true for
// an odd number of levels of the style hierarchy.
//
-// To prevent such logic inside output, it is required to write inline w:b token on content level.
-void SwWW8AttrIter::handleToggleProperty(SfxItemSet& rExportSet, const SwFormatCharFormat* pCharFormatItem,
- sal_uInt16 nWhich, const SfxPoolItem* pValue)
-{
- if (rExportSet.HasItem(nWhich) || !pValue)
+// To prevent such logic inside output, it is required to write inline attribute tokens on content level.
+void SwWW8AttrIter::handleToggleProperty(SfxItemSet& rExportSet, const SwFormatCharFormat& rCharFormatItem)
+{
+ if (rExportSet.HasItem(RES_CHRATR_WEIGHT) || rExportSet.HasItem(RES_CHRATR_POSTURE) ||
+ rExportSet.HasItem(RES_CHRATR_CTL_WEIGHT) || rExportSet.HasItem(RES_CHRATR_CTL_POSTURE) ||
+ rExportSet.HasItem(RES_CHRATR_CONTOUR) || rExportSet.HasItem(RES_CHRATR_CASEMAP) ||
+ rExportSet.HasItem(RES_CHRATR_RELIEF) || rExportSet.HasItem(RES_CHRATR_SHADOWED) ||
+ rExportSet.HasItem(RES_CHRATR_CROSSEDOUT) || rExportSet.HasItem(RES_CHRATR_HIDDEN))
return;
- bool hasPropertyInCharStyle = false;
- bool hasPropertyInParaStyle = false;
+ SvxWeightItem aBoldProperty(WEIGHT_BOLD, RES_CHRATR_WEIGHT);
+ SvxPostureItem aPostureProperty(ITALIC_NORMAL, RES_CHRATR_POSTURE);
+ SvxContourItem aContouredProperty(true, RES_CHRATR_CONTOUR);
+ SvxCaseMapItem aCaseMapCapsProperty(SvxCaseMap::Uppercase, RES_CHRATR_CASEMAP);
+ SvxCaseMapItem aCaseMapSmallProperty(SvxCaseMap::SmallCaps, RES_CHRATR_CASEMAP);
+ SvxCharReliefItem aEmbossedProperty(FontRelief::Embossed, RES_CHRATR_RELIEF);
+ SvxCharReliefItem aImprintProperty(FontRelief::Engraved, RES_CHRATR_RELIEF);
+ SvxShadowedItem aShadowedProperty(true, RES_CHRATR_SHADOWED);
+ SvxCrossedOutItem aStrikeoutProperty(STRIKEOUT_SINGLE, RES_CHRATR_CROSSEDOUT);
+ SvxCharHiddenItem aHiddenProperty(true, RES_CHRATR_HIDDEN);
- // get bold flag from specified character style
- if (pCharFormatItem)
+ bool hasWeightPropertyInCharStyle = false;
+ bool hasWeightComplexPropertyInCharStyle = false;
+ bool hasPosturePropertyInCharStyle = false;
+ bool hasPostureComplexPropertyInCharStyle = false;
+ bool bHasCapsPropertyInCharStyle = false;
+ bool bHasSmallCapsPropertyInCharStyle = false;
+ bool bHasEmbossedPropertyInCharStyle = false;
+ bool bHasImprintPropertyInCharStyle = false;
+ bool hasContouredPropertyInCharStyle = false;
+ bool hasShadowedPropertyInCharStyle = false;
+ bool hasStrikeoutPropertyInCharStyle = false;
+ bool hasHiddenPropertyInCharStyle = false;
+
+
+ // get attribute flags from specified character style
+ if (const SwCharFormat* pCharFormat = rCharFormatItem.GetCharFormat())
{
- if (const SwCharFormat* pCharFormat = pCharFormatItem->GetCharFormat())
+ if (const SfxPoolItem* pWeightItem = pCharFormat->GetAttrSet().GetItem(RES_CHRATR_WEIGHT))
+ hasWeightPropertyInCharStyle = (*pWeightItem == aBoldProperty);
+
+ if (const SfxPoolItem* pWeightComplexItem = pCharFormat->GetAttrSet().GetItem(RES_CHRATR_CTL_WEIGHT))
+ hasWeightComplexPropertyInCharStyle = (*pWeightComplexItem == aBoldProperty);
+
+ if (const SfxPoolItem* pPostureItem = pCharFormat->GetAttrSet().GetItem(RES_CHRATR_POSTURE))
+ hasPosturePropertyInCharStyle = (*pPostureItem == aPostureProperty);
+
+ if (const SfxPoolItem* pPostureComplexItem = pCharFormat->GetAttrSet().GetItem(RES_CHRATR_CTL_POSTURE))
+ hasPostureComplexPropertyInCharStyle = (*pPostureComplexItem == aPostureProperty);
+
+ if (const SfxPoolItem* pContouredItem = pCharFormat->GetAttrSet().GetItem(RES_CHRATR_CONTOUR))
+ hasContouredPropertyInCharStyle = (*pContouredItem == aContouredProperty);
+
+ if (const SfxPoolItem* pShadowedItem = pCharFormat->GetAttrSet().GetItem(RES_CHRATR_SHADOWED))
+ hasShadowedPropertyInCharStyle = (*pShadowedItem == aShadowedProperty);
+
+ if (const SfxPoolItem* pStrikeoutItem = pCharFormat->GetAttrSet().GetItem(RES_CHRATR_CROSSEDOUT))
+ hasStrikeoutPropertyInCharStyle = (*pStrikeoutItem == aStrikeoutProperty);
+
+ if (const SfxPoolItem* pHiddenItem = pCharFormat->GetAttrSet().GetItem(RES_CHRATR_HIDDEN))
+ hasHiddenPropertyInCharStyle = (*pHiddenItem == aHiddenProperty);
+
+ if (const SfxPoolItem* pCaseMapItem = pCharFormat->GetAttrSet().GetItem(RES_CHRATR_CASEMAP))
{
- if (const SfxPoolItem* pItem = pCharFormat->GetAttrSet().GetItem(nWhich))
- {
- hasPropertyInCharStyle = (*pItem == *pValue);
- }
+ bHasCapsPropertyInCharStyle = (*pCaseMapItem == aCaseMapCapsProperty);
+ bHasSmallCapsPropertyInCharStyle = (*pCaseMapItem == aCaseMapSmallProperty);
+ }
+
+ if (const SfxPoolItem* pReliefItem = pCharFormat->GetAttrSet().GetItem(RES_CHRATR_RELIEF))
+ {
+ bHasEmbossedPropertyInCharStyle = (*pReliefItem == aEmbossedProperty);
+ bHasImprintPropertyInCharStyle = (*pReliefItem == aImprintProperty);
}
}
- // get bold flag from specified paragraph style
+ // get attribute flags from specified paragraph style and apply properties if they are set in character and paragraph style
{
SwTextFormatColl& rTextColl = static_cast<SwTextFormatColl&>( m_rNode.GetAnyFormatColl() );
sal_uInt16 nStyle = m_rExport.m_pStyles->GetSlot( &rTextColl );
@@ -588,17 +650,59 @@ void SwWW8AttrIter::handleToggleProperty(SfxItemSet& rExportSet, const SwFormatC
const SwFormat* pFormat = m_rExport.m_pStyles->GetSwFormat(nStyle);
if (pFormat)
{
- if (const SfxPoolItem* pItem = pFormat->GetAttrSet().GetItem(nWhich))
+ const SfxPoolItem* pItem;
+ if (hasWeightPropertyInCharStyle && (pItem = pFormat->GetAttrSet().GetItem(RES_CHRATR_WEIGHT)) &&
+ (*pItem == aBoldProperty))
+ rExportSet.Put(aBoldProperty);
+
+ if (hasWeightComplexPropertyInCharStyle && (pItem = pFormat->GetAttrSet().GetItem(RES_CHRATR_CTL_WEIGHT)) &&
+ *pItem == aBoldProperty)
+ {
+ rExportSet.Put(aBoldProperty, RES_CHRATR_CTL_WEIGHT);
+ }
+
+ if (hasPosturePropertyInCharStyle && (pItem = pFormat->GetAttrSet().GetItem(RES_CHRATR_POSTURE)) &&
+ *pItem == aPostureProperty)
+ rExportSet.Put(aPostureProperty);
+
+ if (hasPostureComplexPropertyInCharStyle && (pItem = pFormat->GetAttrSet().GetItem(RES_CHRATR_CTL_POSTURE)) &&
+ *pItem == aPostureProperty)
{
- hasPropertyInParaStyle = (*pItem == *pValue);
+ rExportSet.Put(aPostureProperty, RES_CHRATR_CTL_POSTURE);
+ }
+
+ if (hasContouredPropertyInCharStyle && (pItem = pFormat->GetAttrSet().GetItem(RES_CHRATR_CONTOUR)) && *pItem == aContouredProperty)
+ rExportSet.Put(aContouredProperty);
+
+ if (hasShadowedPropertyInCharStyle && (pItem = pFormat->GetAttrSet().GetItem(RES_CHRATR_SHADOWED)) &&
+ *pItem == aShadowedProperty)
+ rExportSet.Put(aShadowedProperty);
+
+ if (hasStrikeoutPropertyInCharStyle && (pItem = pFormat->GetAttrSet().GetItem(RES_CHRATR_CROSSEDOUT)) &&
+ *pItem == aStrikeoutProperty)
+ rExportSet.Put(aStrikeoutProperty);
+
+ if (hasHiddenPropertyInCharStyle && (pItem = pFormat->GetAttrSet().GetItem(RES_CHRATR_HIDDEN)) &&
+ (*pItem == aHiddenProperty))
+ rExportSet.Put(aHiddenProperty);
+
+ if ((bHasCapsPropertyInCharStyle||bHasSmallCapsPropertyInCharStyle) && (pItem = pFormat->GetAttrSet().GetItem(RES_CHRATR_CASEMAP)))
+ {
+ if (bHasCapsPropertyInCharStyle && *pItem == aCaseMapCapsProperty)
+ rExportSet.Put(aCaseMapCapsProperty);
+ else if (bHasSmallCapsPropertyInCharStyle && *pItem == aCaseMapSmallProperty)
+ rExportSet.Put(aCaseMapSmallProperty);
+ }
+
+ if ((bHasEmbossedPropertyInCharStyle||bHasImprintPropertyInCharStyle) && (pItem = pFormat->GetAttrSet().GetItem(RES_CHRATR_RELIEF)))
+ {
+ if (bHasEmbossedPropertyInCharStyle && *pItem == aEmbossedProperty)
+ rExportSet.Put(aEmbossedProperty);
+ else if (bHasImprintPropertyInCharStyle && *pItem == aImprintProperty)
+ rExportSet.Put(aImprintProperty);
}
}
- }
- // add inline property
- if (hasPropertyInCharStyle && hasPropertyInParaStyle)
- {
- rExportSet.Put(*pValue);
}
}
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index 3aa39a2994b8..5726b3949077 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -1548,7 +1548,7 @@ private:
SwWW8AttrIter(const SwWW8AttrIter&) = delete;
SwWW8AttrIter& operator=(const SwWW8AttrIter&) = delete;
- void handleToggleProperty(SfxItemSet& rExportSet, const SwFormatCharFormat* pCharFormatItem, sal_uInt16 nWhich, const SfxPoolItem* pValue);
+ void handleToggleProperty(SfxItemSet& rExportSet, const SwFormatCharFormat& rCharFormatItem);
public:
SwWW8AttrIter( MSWordExportBase& rWr, const SwTextNode& rNd );
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index e1a4d04631db..5fbec2fb965d 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -37,6 +37,7 @@
#include <com/sun/star/i18n/NumberFormatMapper.hpp>
#include <com/sun/star/i18n/NumberFormatIndex.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/style/CaseMap.hpp>
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/style/LineNumberPosition.hpp>
#include <com/sun/star/style/LineSpacing.hpp>
@@ -78,6 +79,10 @@
#include <com/sun/star/text/ControlCharacter.hpp>
#include <com/sun/star/text/XTextColumns.hpp>
#include <com/sun/star/awt/CharSet.hpp>
+#include <com/sun/star/awt/FontRelief.hpp>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/awt/FontStrikeout.hpp>
+#include <com/sun/star/awt/FontWeight.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/embed/XHierarchicalStorageAccess.hpp>
#include <com/sun/star/embed/ElementModes.hpp>
@@ -503,6 +508,17 @@ uno::Reference< container::XNameContainer > const & DomainMapper_Impl::GetChara
return m_xCharacterStyles;
}
+uno::Reference<container::XNameContainer> const& DomainMapper_Impl::GetParagraphStyles()
+{
+ if (!m_xParagraphStyles.is())
+ {
+ uno::Reference<style::XStyleFamiliesSupplier> xSupplier(m_xTextDocument, uno::UNO_QUERY);
+ if (xSupplier.is())
+ xSupplier->getStyleFamilies()->getByName("ParagraphStyles") >>= m_xParagraphStyles;
+ }
+ return m_xParagraphStyles;
+}
+
OUString DomainMapper_Impl::GetUnusedCharacterStyleName()
{
static const char cListLabel[] = "ListLabel ";
@@ -2983,7 +2999,148 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap, con
}
-void DomainMapper_Impl::appendTextPortion( const OUString& rString, const PropertyMapPtr& pPropertyMap )
+void DomainMapper_Impl::applyToggleAttributes(const PropertyMapPtr& pPropertyMap)
+{
+ std::optional<PropertyMap::Property> charStyleProperty = pPropertyMap->getProperty(PROP_CHAR_STYLE_NAME);
+ if (charStyleProperty.has_value())
+ {
+ OUString sCharStyleName;
+ charStyleProperty->second >>= sCharStyleName;
+ float fCharStyleBold = css::awt::FontWeight::NORMAL;
+ float fCharStyleBoldComplex = css::awt::FontWeight::NORMAL;
+ css::awt::FontSlant eCharStylePosture = css::awt::FontSlant_NONE;
+ css::awt::FontSlant eCharStylePostureComplex = css::awt::FontSlant_NONE;
+ sal_Int16 nCharStyleCaseMap = css::style::CaseMap::NONE;
+ sal_Int16 nCharStyleRelief = css::awt::FontRelief::NONE;
+ bool bCharStyleContoured = false;//Outline;
+ bool bCharStyleShadowed = false;
+ sal_Int16 nCharStyleStrikeThrough = awt::FontStrikeout::NONE;
+ bool bCharStyleHidden = false;
+
+ uno::Reference<beans::XPropertySet> xCharStylePropertySet = GetCharacterStyles()->getByName(sCharStyleName).get<uno::Reference<beans::XPropertySet>>();
+ xCharStylePropertySet->getPropertyValue(getPropertyName(PROP_CHAR_WEIGHT)) >>= fCharStyleBold;
+ xCharStylePropertySet->getPropertyValue(getPropertyName(PROP_CHAR_WEIGHT_COMPLEX)) >>= fCharStyleBoldComplex;
+ xCharStylePropertySet->getPropertyValue(getPropertyName(PROP_CHAR_POSTURE)) >>= eCharStylePosture;
+ xCharStylePropertySet->getPropertyValue(getPropertyName(PROP_CHAR_POSTURE_COMPLEX)) >>= eCharStylePostureComplex;
+ xCharStylePropertySet->getPropertyValue(getPropertyName(PROP_CHAR_CASE_MAP)) >>= nCharStyleCaseMap;
+ xCharStylePropertySet->getPropertyValue(getPropertyName(PROP_CHAR_RELIEF)) >>= nCharStyleRelief;
+ xCharStylePropertySet->getPropertyValue(getPropertyName(PROP_CHAR_CONTOURED)) >>= bCharStyleContoured;
+ xCharStylePropertySet->getPropertyValue(getPropertyName(PROP_CHAR_SHADOWED)) >>= bCharStyleShadowed;
+ xCharStylePropertySet->getPropertyValue(getPropertyName(PROP_CHAR_STRIKEOUT)) >>= nCharStyleStrikeThrough;
+ xCharStylePropertySet->getPropertyValue(getPropertyName(PROP_CHAR_HIDDEN)) >>= bCharStyleHidden;
+ if (fCharStyleBold > css::awt::FontWeight::NORMAL || eCharStylePosture != css::awt::FontSlant_NONE|| nCharStyleCaseMap != css::style::CaseMap::NONE ||
+ nCharStyleRelief != css::awt::FontRelief::NONE || bCharStyleContoured || bCharStyleShadowed ||
+ nCharStyleStrikeThrough == awt::FontStrikeout::SINGLE || bCharStyleHidden)
+ {
+ uno::Reference<beans::XPropertySet> xParaStylePropertySet = GetParagraphStyles()->getByName(m_sCurrentParaStyleName).get<uno::Reference<beans::XPropertySet>>();
+ float fParaStyleBold = css::awt::FontWeight::NORMAL;
+ float fParaStyleBoldComplex = css::awt::FontWeight::NORMAL;
+ css::awt::FontSlant eParaStylePosture = css::awt::FontSlant_NONE;
+ css::awt::FontSlant eParaStylePostureComplex = css::awt::FontSlant_NONE;
+ sal_Int16 nParaStyleCaseMap = css::style::CaseMap::NONE;
+ sal_Int16 nParaStyleRelief = css::awt::FontRelief::NONE;
+ bool bParaStyleContoured = false;
+ bool bParaStyleShadowed = false;
+ sal_Int16 nParaStyleStrikeThrough = awt::FontStrikeout::NONE;
+ bool bParaStyleHidden = false;
+ xParaStylePropertySet->getPropertyValue(getPropertyName(PROP_CHAR_WEIGHT)) >>= fParaStyleBold;
+ xParaStylePropertySet->getPropertyValue(getPropertyName(PROP_CHAR_WEIGHT_COMPLEX)) >>= fParaStyleBoldComplex;
+ xParaStylePropertySet->getPropertyValue(getPropertyName(PROP_CHAR_POSTURE)) >>= eParaStylePosture;
+ xParaStylePropertySet->getPropertyValue(getPropertyName(PROP_CHAR_POSTURE_COMPLEX)) >>= eParaStylePostureComplex;
+ xParaStylePropertySet->getPropertyValue(getPropertyName(PROP_CHAR_CASE_MAP)) >>= nParaStyleCaseMap;
+ xParaStylePropertySet->getPropertyValue(getPropertyName(PROP_CHAR_RELIEF)) >>= nParaStyleRelief;
+ xParaStylePropertySet->getPropertyValue(getPropertyName(PROP_CHAR_SHADOWED)) >>= bParaStyleShadowed;
+ xParaStylePropertySet->getPropertyValue(getPropertyName(PROP_CHAR_CONTOURED)) >>= bParaStyleContoured;
+ xParaStylePropertySet->getPropertyValue(getPropertyName(PROP_CHAR_STRIKEOUT)) >>= nParaStyleStrikeThrough;
+ xParaStylePropertySet->getPropertyValue(getPropertyName(PROP_CHAR_HIDDEN)) >>= bParaStyleHidden;
+ if (fCharStyleBold > css::awt::FontWeight::NORMAL && fParaStyleBold > css::awt::FontWeight::NORMAL)
+ {
+ std::optional<PropertyMap::Property> charBoldProperty = pPropertyMap->getProperty(PROP_CHAR_WEIGHT);
+ if (!charBoldProperty.has_value())
+ {
+ pPropertyMap->Insert(PROP_CHAR_WEIGHT, uno::Any(css::awt::FontWeight::NORMAL));
+ }
+ }
+ if (fCharStyleBoldComplex > css::awt::FontWeight::NORMAL && fParaStyleBoldComplex > css::awt::FontWeight::NORMAL)
+ {
+ std::optional<PropertyMap::Property> charBoldPropertyComplex = pPropertyMap->getProperty(PROP_CHAR_WEIGHT_COMPLEX);
+ if (!charBoldPropertyComplex.has_value())
+ {
+ pPropertyMap->Insert(PROP_CHAR_WEIGHT_COMPLEX, uno::Any(css::awt::FontWeight::NORMAL));
+ pPropertyMap->Insert(PROP_CHAR_WEIGHT_ASIAN, uno::Any(css::awt::FontWeight::NORMAL));
+ }
+ }
+ if (eCharStylePosture != css::awt::FontSlant_NONE && eParaStylePosture != css::awt::FontSlant_NONE)
+ {
+ std::optional<PropertyMap::Property> charItalicProperty = pPropertyMap->getProperty(PROP_CHAR_POSTURE);
+ if (!charItalicProperty.has_value())
+ {
+ pPropertyMap->Insert(PROP_CHAR_POSTURE, uno::Any(css::awt::FontSlant_NONE));
+ }
+ }
+ if (eCharStylePostureComplex != css::awt::FontSlant_NONE && eParaStylePostureComplex != css::awt::FontSlant_NONE)
+ {
+ std::optional<PropertyMap::Property> charItalicPropertyComplex = pPropertyMap->getProperty(PROP_CHAR_POSTURE_COMPLEX);
+ if (!charItalicPropertyComplex.has_value())
+ {
+ pPropertyMap->Insert(PROP_CHAR_POSTURE_COMPLEX, uno::Any(css::awt::FontSlant_NONE));
+ pPropertyMap->Insert(PROP_CHAR_POSTURE_ASIAN, uno::Any(css::awt::FontSlant_NONE));
+ }
+ }
+ if (nCharStyleCaseMap == nParaStyleCaseMap && nCharStyleCaseMap != css::style::CaseMap::NONE)
+ {
+ std::optional<PropertyMap::Property> charCaseMap = pPropertyMap->getProperty(PROP_CHAR_CASE_MAP);
+ if (!charCaseMap.has_value())
+ {
+ pPropertyMap->Insert(PROP_CHAR_CASE_MAP, uno::Any(css::style::CaseMap::NONE));
+ }
+ }
+ if (nParaStyleRelief != css::awt::FontRelief::NONE && nCharStyleRelief == nParaStyleRelief)
+ {
+ std::optional<PropertyMap::Property> charRelief = pPropertyMap->getProperty(PROP_CHAR_RELIEF);
+ if (!charRelief.has_value())
+ {
+ pPropertyMap->Insert(PROP_CHAR_RELIEF, uno::Any(css::awt::FontRelief::NONE));
+ }
+ }
+ if (bParaStyleContoured && bCharStyleContoured)
+ {
+ std::optional<PropertyMap::Property> charContoured = pPropertyMap->getProperty(PROP_CHAR_CONTOURED);
+ if (!charContoured.has_value())
+ {
+ pPropertyMap->Insert(PROP_CHAR_CONTOURED, uno::Any(false));
+ }
+ }
+ if (bParaStyleShadowed && bCharStyleShadowed)
+ {
+ std::optional<PropertyMap::Property> charShadow = pPropertyMap->getProperty(PROP_CHAR_SHADOWED);
+ if (!charShadow.has_value())
+ {
+ pPropertyMap->Insert(PROP_CHAR_SHADOWED, uno::Any(false));
+ }
+ }
+ if (nParaStyleStrikeThrough == css::awt::FontStrikeout::SINGLE && nParaStyleStrikeThrough == nCharStyleStrikeThrough)
+ {
+ std::optional<PropertyMap::Property> charStrikeThrough = pPropertyMap->getProperty(PROP_CHAR_STRIKEOUT);
+ if (!charStrikeThrough.has_value())
+ {
+ pPropertyMap->Insert(PROP_CHAR_STRIKEOUT, uno::Any(css::awt::FontStrikeout::NONE));
+ }
+ }
+ if (bParaStyleHidden && bCharStyleHidden)
+ {
+ std::optional<PropertyMap::Property> charHidden = pPropertyMap->getProperty(PROP_CHAR_HIDDEN);
+ if (!charHidden.has_value())
+ {
+ pPropertyMap->Insert(PROP_CHAR_HIDDEN, uno::Any(false));
+ }
+ }
+ }
+ }
+}
+
+
+ void DomainMapper_Impl::appendTextPortion( const OUString& rString, const PropertyMapPtr& pPropertyMap )
{
if (m_bDiscardHeaderFooter)
return;
@@ -3000,6 +3157,7 @@ void DomainMapper_Impl::appendTextPortion( const OUString& rString, const Proper
try
{
+ applyToggleAttributes(pPropertyMap);
// If we are in comments, then disable CharGrabBag, comment text doesn't support that.
uno::Sequence<beans::PropertyValue> aValues = pPropertyMap->GetPropertyValues(/*bCharGrabBag=*/!IsInComments());
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 2cffecf47fb9..ee17ac183a2a 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -493,6 +493,8 @@ private:
// cache next available number, expensive to repeatedly compute
std::optional<int> m_xNextUnusedPageStyleNo;
css::uno::Reference<css::container::XNameContainer> m_xCharacterStyles;
+ css::uno::Reference<css::container::XNameContainer> m_xParagraphStyles;
+
// cache next available number, expensive to repeatedly compute
std::optional<int> m_xNextUnusedCharacterStyleNo;
css::uno::Reference<css::text::XText> m_xBodyText;
@@ -677,6 +679,7 @@ public:
css::uno::Reference<css::container::XNameContainer> const & GetPageStyles();
OUString GetUnusedPageStyleName();
css::uno::Reference<css::container::XNameContainer> const & GetCharacterStyles();
+ css::uno::Reference<css::container::XNameContainer> const& GetParagraphStyles();
OUString GetUnusedCharacterStyleName();
css::uno::Reference<css::text::XText> const & GetBodyText();
const css::uno::Reference<css::lang::XMultiServiceFactory>& GetTextFactory() const
@@ -771,6 +774,7 @@ public:
bool isParaSdtEndDeferred() const;
void finishParagraph( const PropertyMapPtr& pPropertyMap, const bool bRemove = false, const bool bNoNumbering = false);
+ void applyToggleAttributes( const PropertyMapPtr& pPropertyMap );
void appendTextPortion( const OUString& rString, const PropertyMapPtr& pPropertyMap );
void appendTextContent(const css::uno::Reference<css::text::XTextContent>&, const css::uno::Sequence<css::beans::PropertyValue>&);
void appendOLE( const OUString& rStreamName, const std::shared_ptr<OLEHandler>& pOleHandler );