diff --git a/sw/qa/extras/ooxmlexport/data/theme-preservation.docx b/sw/qa/extras/ooxmlexport/data/theme-preservation.docx index c1d879aa05df..ff7c5700c965 100644 Binary files a/sw/qa/extras/ooxmlexport/data/theme-preservation.docx and b/sw/qa/extras/ooxmlexport/data/theme-preservation.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index c4efcfda32d8..726783889794 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -2047,7 +2047,7 @@ DECLARE_OOXMLEXPORT_TEST(testThemePreservation, "theme-preservation.docx") if (!pXmlStyles) return; assertXPath(pXmlStyles, "/w:styles/w:docDefaults/w:rPrDefault/w:rPr/w:rFonts", "asciiTheme", "minorHAnsi"); - assertXPath(pXmlStyles, "/w:styles/w:docDefaults/w:rPrDefault/w:rPr/w:rFonts", "eastAsiaTheme", "minorEastAsia"); + assertXPath(pXmlStyles, "/w:styles/w:docDefaults/w:rPrDefault/w:rPr/w:rFonts", "cstheme", "minorBidi"); // check the font theme values in style definitions assertXPath(pXmlStyles, "/w:styles/w:style[1]/w:rPr/w:rFonts", "eastAsiaTheme", "minorEastAsia"); @@ -2056,8 +2056,30 @@ DECLARE_OOXMLEXPORT_TEST(testThemePreservation, "theme-preservation.docx") xmlDocPtr pXmlDocument = parseExport("word/document.xml"); if (!pXmlDocument) return; - assertXPath(pXmlDocument, "/w:document/w:body/w:p[1]/w:r[1]/w:rPr/w:rFonts", "hAnsiTheme", "majorBidi"); - assertXPath(pXmlDocument, "/w:document/w:body/w:p[1]/w:r[1]/w:rPr/w:rFonts", "cstheme", "majorBidi"); + assertXPath(pXmlDocument, "/w:document/w:body/w:p[5]/w:r[1]/w:rPr/w:rFonts", "hAnsiTheme", "majorHAnsi"); + assertXPath(pXmlDocument, "/w:document/w:body/w:p[5]/w:r[1]/w:rPr/w:rFonts", "asciiTheme", "majorHAnsi"); + + // check the themeFontLang values in settings file + xmlDocPtr pXmlSettings = parseExport("word/settings.xml"); + if (!pXmlSettings) + return; + assertXPath(pXmlSettings, "/w:settings/w:themeFontLang", "val", "en-US"); + assertXPath(pXmlSettings, "/w:settings/w:themeFontLang", "eastAsia", "zh-CN"); + assertXPath(pXmlSettings, "/w:settings/w:themeFontLang", "bidi", "he-IL"); + + // check fonts have been applied properly + sal_Unicode fontName[2]; //represents the string "宋体" + fontName[0] = 0x5b8b; + fontName[1] = 0x4f53; + CPPUNIT_ASSERT_EQUAL(OUString(fontName, 2), getProperty(getParagraph(1), "CharFontNameAsian")); + CPPUNIT_ASSERT_EQUAL(OUString("Arial"), + getProperty(getParagraph(2), "CharFontNameComplex")); + CPPUNIT_ASSERT_EQUAL(OUString("Trebuchet MS"), + getProperty(getParagraph(3, "Default style theme font"), "CharFontName")); + CPPUNIT_ASSERT_EQUAL(OUString("Arial Black"), + getProperty(getRun(getParagraph(4, "Direct format font"), 1), "CharFontName")); + CPPUNIT_ASSERT_EQUAL(OUString("Trebuchet MS"), + getProperty(getParagraph(5, "Major theme font"), "CharFontName")); } DECLARE_OOXMLEXPORT_TEST(testcantSplit, "2_table_doc.docx") diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx index bbc367332b6d..f825819b26ee 100644 --- a/sw/source/filter/ww8/docxexport.cxx +++ b/sw/source/filter/ww8/docxexport.cxx @@ -753,6 +753,41 @@ void DocxExport::WriteSettings() if( m_pAttrOutput->HasEndnotes()) m_pAttrOutput->WriteFootnoteEndnotePr( pFS, XML_endnotePr, pDoc->GetEndNoteInfo(), XML_endnote ); + // Has themeFontLang information + uno::Reference< beans::XPropertySet > xPropSet( pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW ); + + uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo(); + OUString pName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG; + if ( xPropSetInfo->hasPropertyByName( pName ) ) + { + uno::Sequence< beans::PropertyValue > propList; + xPropSet->getPropertyValue( pName ) >>= propList; + for( sal_Int32 i=0; i < propList.getLength(); ++i ) + { + if ( propList[i].Name == "ThemeFontLangProps" ) + { + uno::Sequence< beans::PropertyValue > themeFontLangProps; + propList[i].Value >>= themeFontLangProps; + OUString aValues[3]; + for( sal_Int32 j=0; j < themeFontLangProps.getLength(); ++j ) + { + if( themeFontLangProps[j].Name == "val" ) + themeFontLangProps[j].Value >>= aValues[0]; + else if( themeFontLangProps[j].Name == "eastAsia" ) + themeFontLangProps[j].Value >>= aValues[1]; + else if( themeFontLangProps[j].Name == "bidi" ) + themeFontLangProps[j].Value >>= aValues[2]; + } + pFS->singleElementNS( XML_w, XML_themeFontLang, + FSNS( XML_w, XML_val ), OUStringToOString( aValues[0], RTL_TEXTENCODING_UTF8 ).getStr(), + FSNS( XML_w, XML_eastAsia ), OUStringToOString( aValues[1], RTL_TEXTENCODING_UTF8 ).getStr(), + FSNS( XML_w, XML_bidi ), OUStringToOString( aValues[2], RTL_TEXTENCODING_UTF8 ).getStr(), + FSEND ); + break; + } + } + } + pFS->endElementNS( XML_w, XML_settings ); } diff --git a/writerfilter/inc/dmapper/DomainMapper.hxx b/writerfilter/inc/dmapper/DomainMapper.hxx index 78067fcbe173..9775bac11010 100644 --- a/writerfilter/inc/dmapper/DomainMapper.hxx +++ b/writerfilter/inc/dmapper/DomainMapper.hxx @@ -127,6 +127,8 @@ public: /// Get the stored tokens and clear the internal storage. beans::PropertyValue getInteropGrabBag(); + uno::Sequence GetThemeFontLangProperties() const; + private: // Stream virtual void lcl_startSectionGroup(); diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index 360ac57f201b..2fcd4fbdfddb 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -4364,6 +4364,11 @@ beans::PropertyValue DomainMapper::getInteropGrabBag() return aRet; } +uno::Sequence DomainMapper::GetThemeFontLangProperties() const +{ + return m_pImpl->GetSettingsTable()->GetThemeFontLangProperties(); +} + } //namespace dmapper } //namespace writerfilter diff --git a/writerfilter/source/filter/ImportFilter.cxx b/writerfilter/source/filter/ImportFilter.cxx index cbbcd3a9b64c..708b9f7283a0 100644 --- a/writerfilter/source/filter/ImportFilter.cxx +++ b/writerfilter/source/filter/ImportFilter.cxx @@ -100,7 +100,8 @@ sal_Bool WriterFilter::filter( const uno::Sequence< beans::PropertyValue >& aDes m_sFilterName == "writer_OOXML" || m_sFilterName == "writer_OOXML_Text_Template" ) ? writerfilter::dmapper::DOCUMENT_OOXML : writerfilter::dmapper::DOCUMENT_DOC; - writerfilter::Stream::Pointer_t pStream(new writerfilter::dmapper::DomainMapper(m_xContext, xInputStream, m_xDstDoc, bRepairStorage, eType, uno::Reference())); + writerfilter::dmapper::DomainMapper* aDomainMapper = new writerfilter::dmapper::DomainMapper(m_xContext, xInputStream, m_xDstDoc, bRepairStorage, eType, uno::Reference()); + writerfilter::Stream::Pointer_t pStream(aDomainMapper); //create the tokenizer and domain mapper if( eType == writerfilter::dmapper::DOCUMENT_OOXML ) { @@ -221,6 +222,38 @@ sal_Bool WriterFilter::filter( const uno::Sequence< beans::PropertyValue >& aDes SAL_WARN("writerfilter","Failed to save ActiveX dom to documents grab bag"); } + // Adding the saved w:themeFontLang setting to the document's grab bag + if ( aDomainMapper->GetThemeFontLangProperties().hasElements() ) + try + { + uno::Reference xDocProps( m_xDstDoc, uno::UNO_QUERY ); + if (xDocProps.is()) + { + uno::Reference< beans::XPropertySetInfo > xPropsInfo = xDocProps->getPropertySetInfo(); + + const OUString aGrabBagPropName = "InteropGrabBag"; + if( xPropsInfo.is() && xPropsInfo->hasPropertyByName( aGrabBagPropName ) ) + { + uno::Sequence< beans::PropertyValue > aGrabBag; + + // We want to keep the previous items + xDocProps->getPropertyValue( aGrabBagPropName ) >>= aGrabBag; + sal_Int32 length = aGrabBag.getLength(); + aGrabBag.realloc( length+1 ); + + beans::PropertyValue* pValue = aGrabBag.getArray(); + pValue[length].Name = "ThemeFontLangProps"; + pValue[length].Value = uno::makeAny( aDomainMapper->GetThemeFontLangProperties() ); + + xDocProps->setPropertyValue( aGrabBagPropName, uno::Any( aGrabBag ) ); + } + } + } + catch(const uno::Exception&) + { + SAL_WARN("writerfilter","Failed to save themeFontLang properties to documents grab bag"); + } + writerfilter::ooxml::OOXMLStream::Pointer_t pVBAProjectStream(writerfilter::ooxml::OOXMLDocumentFactory::createStream( pDocStream, writerfilter::ooxml::OOXMLStream::VBAPROJECT )); oox::StorageRef xVbaPrjStrg( new ::oox::ole::OleStorage( m_xContext, pVBAProjectStream->getDocumentStream(), false ) ); if( xVbaPrjStrg.get() && xVbaPrjStrg->isStorage() )