diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2024-05-03 12:12:24 +0200 |
---|---|---|
committer | Michael Stahl <michael.stahl@allotropia.de> | 2024-05-06 17:52:47 +0200 |
commit | ab1697cb4c17fd7a2fbf8d374ac95fc03b4d00be (patch) | |
tree | 24400c7fcd9ea13b62a304c2ce6edf853418fef2 /sw/source | |
parent | dd3953f705cc19aad4b0fcec7fd2961246b659e3 (diff) |
tdf#160402 filter,writerfilter: import locale-dependent STYLEREF names
* Handle STYLEREF style the same way as TOC style on import.
* Word 2013 does not uppercase the first letter
("Überschrift 1" -> "berschrift1") and there doesn't
appear to be any justification why the code does that.
* The style that's applied is actually the display style name
so convert from source's m_sConvertedStyleName.
* Change the logic in DomainMapper_Impl::ConvertTOCStyleName() to
explicitly check and clone only known built-in Word styles, which are
the ones that are translated.
* This requires some refactoring, and to add the built-in styles in the
bugdoc to the "StyleNameMap", which is probably still incomplete...
* Exporting to DOCX appears to work without changes.
* Somehow this causes the testFDO77715 to have an outlinelevel of 1 on
the TOC paragraphs now, but that turns out to be a bugfix.
Change-Id: I73bc1d1819e5cecbba2fef9cd6d290682a02a638
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167097
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
Tested-by: Jenkins
Diffstat (limited to 'sw/source')
4 files changed, 43 insertions, 50 deletions
diff --git a/sw/source/writerfilter/dmapper/DomainMapper.cxx b/sw/source/writerfilter/dmapper/DomainMapper.cxx index 7d48b265f079..57712a349681 100644 --- a/sw/source/writerfilter/dmapper/DomainMapper.cxx +++ b/sw/source/writerfilter/dmapper/DomainMapper.cxx @@ -2645,7 +2645,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext ) case NS_ooxml::LN_CT_PPrBase_pStyle: { StyleSheetTablePtr pStyleTable = m_pImpl->GetStyleSheetTable(); - const OUString sConvertedStyleName = pStyleTable->ConvertStyleName( sStringValue, true ); + const OUString sConvertedStyleName = pStyleTable->ConvertStyleNameExt(sStringValue); m_pImpl->SetCurrentParaStyleName( sConvertedStyleName ); if (m_pImpl->GetTopContext() && m_pImpl->GetTopContextType() != CONTEXT_SECTION) m_pImpl->GetTopContext()->Insert( PROP_PARA_STYLE_NAME, uno::Any( sConvertedStyleName )); @@ -2653,7 +2653,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext ) break; case NS_ooxml::LN_EG_RPrBase_rStyle: { - OUString sConvertedName( m_pImpl->GetStyleSheetTable()->ConvertStyleName( sStringValue, true ) ); + OUString const sConvertedName(m_pImpl->GetStyleSheetTable()->ConvertStyleNameExt(sStringValue)); if (m_pImpl->CheckFootnoteStyle() && m_pImpl->GetFootnoteContext()) m_pImpl->SetHasFootnoteStyle(m_pImpl->GetFootnoteContext()->GetFootnoteStyle() == sConvertedName); diff --git a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx index a26c517064ec..ebb636e1ab36 100644 --- a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx +++ b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx @@ -6970,21 +6970,18 @@ static OUString UnquoteFieldText(std::u16string_view s) OUString DomainMapper_Impl::ConvertTOCStyleName(OUString const& rTOCStyleName) { assert(!rTOCStyleName.isEmpty()); - if (auto const pStyle = GetStyleSheetTable()->FindStyleSheetByISTD(rTOCStyleName)) - { // theoretical case: what OOXML says - return pStyle->m_sStyleName; - } - auto const pStyle = GetStyleSheetTable()->FindStyleSheetByISTD(FilterChars(rTOCStyleName)); - if (pStyle && m_bIsNewDoc) - { // practical case: Word wrote i18n name to TOC field, but it doesn't - // exist in styles.xml; tdf#153083 clone it for best roundtrip - SAL_INFO("writerfilter.dmapper", "cloning TOC paragraph style (presumed built-in) " << rTOCStyleName << " from " << pStyle->m_sStyleName); - return GetStyleSheetTable()->CloneTOCStyle(GetFontTable(), pStyle, rTOCStyleName); - } - else + if (auto const pStyle = GetStyleSheetTable()->FindStyleSheetByISTD(FilterChars(rTOCStyleName))) { - return GetStyleSheetTable()->ConvertStyleName(rTOCStyleName); + auto const [convertedStyleName, isBuiltIn] = StyleSheetTable::ConvertStyleName(pStyle->m_sStyleName); + if (isBuiltIn && m_bIsNewDoc) + { // practical case: Word wrote i18n name to TOC field, but it doesn't + // exist in styles.xml; tdf#153083 clone it for best roundtrip + assert(convertedStyleName == pStyle->m_sConvertedStyleName); + return GetStyleSheetTable()->CloneTOCStyle(GetFontTable(), pStyle, rTOCStyleName); + } } + // theoretical case: what OOXML says + return StyleSheetTable::ConvertStyleName(rTOCStyleName).first; } void DomainMapper_Impl::handleToc @@ -8052,27 +8049,8 @@ void DomainMapper_Impl::CloseFieldCommand() getPropertyName(PROP_REFERENCE_FIELD_SOURCE), uno::Any(sal_Int16(text::ReferenceFieldSource::STYLE))); - OUString sStyleSheetName - = GetStyleSheetTable()->ConvertStyleName(sFirstParam, true); - uno::Any aStyleDisplayName; - - uno::Reference<container::XNameAccess> xStyleFamilies - = GetTextDocument()->getStyleFamilies(); - uno::Reference<container::XNameAccess> xStyles; - xStyleFamilies->getByName(getPropertyName(PROP_PARAGRAPH_STYLES)) - >>= xStyles; - uno::Reference<css::beans::XPropertySet> xStyle; - - try - { - xStyles->getByName(sStyleSheetName) >>= xStyle; - aStyleDisplayName = xStyle->getPropertyValue("DisplayName"); - } - catch (css::container::NoSuchElementException) - { - aStyleDisplayName <<= sStyleSheetName; - } + aStyleDisplayName <<= ConvertTOCStyleName(sFirstParam); xFieldProperties->setPropertyValue( getPropertyName(PROP_SOURCE_NAME), aStyleDisplayName); diff --git a/sw/source/writerfilter/dmapper/StyleSheetTable.cxx b/sw/source/writerfilter/dmapper/StyleSheetTable.cxx index 51bb40ddbc8c..2d8ff27fd206 100644 --- a/sw/source/writerfilter/dmapper/StyleSheetTable.cxx +++ b/sw/source/writerfilter/dmapper/StyleSheetTable.cxx @@ -815,7 +815,7 @@ void StyleSheetTable::lcl_entry(const writerfilter::Reference<Properties>::Point m_pImpl->m_rDMapper.PopStyleSheetProperties(); if( !m_pImpl->m_rDMapper.IsOOXMLImport() || !m_pImpl->m_pCurrentEntry->m_sStyleName.isEmpty()) { - m_pImpl->m_pCurrentEntry->m_sConvertedStyleName = ConvertStyleName( m_pImpl->m_pCurrentEntry->m_sStyleName ); + m_pImpl->m_pCurrentEntry->m_sConvertedStyleName = ConvertStyleName(m_pImpl->m_pCurrentEntry->m_sStyleName).first; m_pImpl->m_aStyleSheetEntries.push_back( m_pImpl->m_pCurrentEntry ); m_pImpl->m_aStyleSheetEntriesMap.emplace( m_pImpl->m_pCurrentEntry->m_sStyleIdentifierD, m_pImpl->m_pCurrentEntry ); } @@ -922,7 +922,7 @@ void StyleSheetTable::ApplyNumberingStyleNameToParaStyles() if (pStyleSheetProperties->props().GetListId() > -1) { uno::Reference< style::XStyle > xStyle; - xParaStyles->getByName( ConvertStyleName(pEntry->m_sStyleName) ) >>= xStyle; + xParaStyles->getByName(ConvertStyleName(pEntry->m_sStyleName).first) >>= xStyle; if ( !xStyle.is() ) break; @@ -1077,14 +1077,19 @@ void StyleSheetTable::ApplyClonedTOCStyles() OUString StyleSheetTable::CloneTOCStyle(FontTablePtr const& rFontTable, StyleSheetEntryPtr const pStyle, OUString const& rNewName) { + auto const it = m_pImpl->m_ClonedTOCStylesMap.find(pStyle->m_sConvertedStyleName); + if (it != m_pImpl->m_ClonedTOCStylesMap.end()) + { + return it->second; + } + SAL_INFO("writerfilter.dmapper", "cloning TOC paragraph style (presumed built-in) " << rNewName << " from " << pStyle->m_sStyleName); StyleSheetEntryPtr const pClone(new StyleSheetEntry(*pStyle)); pClone->m_sStyleIdentifierD = rNewName; pClone->m_sStyleName = rNewName; - pClone->m_sConvertedStyleName = ConvertStyleName(rNewName); + pClone->m_sConvertedStyleName = ConvertStyleName(rNewName).first; m_pImpl->m_aStyleSheetEntries.push_back(pClone); - // add it so it will be found if referenced from another TOC - m_pImpl->m_aStyleSheetEntriesMap.emplace(rNewName, pClone); - m_pImpl->m_ClonedTOCStylesMap.emplace(pStyle->m_sStyleName, pClone->m_sConvertedStyleName); + // the old converted name is what is applied to paragraphs + m_pImpl->m_ClonedTOCStylesMap.emplace(pStyle->m_sConvertedStyleName, pClone->m_sConvertedStyleName); std::vector<StyleSheetEntryPtr> const styles{ pClone }; ApplyStyleSheetsImpl(rFontTable, styles); return pClone->m_sConvertedStyleName; @@ -1128,7 +1133,7 @@ void StyleSheetTable::ApplyStyleSheetsImpl(const FontTablePtr& rFontTable, std:: bool bInsert = false; uno::Reference< container::XNameContainer > xStyles = bParaStyle ? xParaStyles : (bListStyle ? xNumberingStyles : xCharStyles); uno::Reference< style::XStyle > xStyle; - const OUString sConvertedStyleName = ConvertStyleName( pEntry->m_sStyleName ); + const OUString sConvertedStyleName(ConvertStyleName(pEntry->m_sStyleName).first); if(xStyles->hasByName( sConvertedStyleName )) { @@ -1196,7 +1201,7 @@ void StyleSheetTable::ApplyStyleSheetsImpl(const FontTablePtr& rFontTable, std:: // Writer core doesn't support numbering styles having a parent style, it seems if (pParent && !bListStyle) { - const OUString sParentStyleName = ConvertStyleName( pParent->m_sStyleName ); + const OUString sParentStyleName(ConvertStyleName(pParent->m_sStyleName).first); if ( !sParentStyleName.isEmpty() && !xStyles->hasByName( sParentStyleName ) ) aMissingParent.emplace_back( sParentStyleName, xStyle ); else @@ -1256,7 +1261,7 @@ void StyleSheetTable::ApplyStyleSheetsImpl(const FontTablePtr& rFontTable, std:: StyleSheetEntryPtr pLinkStyle = FindStyleSheetByISTD(pEntry->m_sLinkStyleIdentifier); if (pLinkStyle && !pLinkStyle->m_sStyleName.isEmpty()) - aMissingLink.emplace_back(ConvertStyleName(pLinkStyle->m_sStyleName), + aMissingLink.emplace_back(ConvertStyleName(pLinkStyle->m_sStyleName).first, xStyle); } } @@ -1268,7 +1273,7 @@ void StyleSheetTable::ApplyStyleSheetsImpl(const FontTablePtr& rFontTable, std:: { StyleSheetEntryPtr pFollowStyle = FindStyleSheetByISTD( pEntry->m_sNextStyleIdentifier ); if ( pFollowStyle && !pFollowStyle->m_sStyleName.isEmpty() ) - aMissingFollow.emplace_back( ConvertStyleName( pFollowStyle->m_sStyleName ), xStyle ); + aMissingFollow.emplace_back(ConvertStyleName(pFollowStyle->m_sStyleName).first, xStyle); } // Set the outline levels @@ -1515,10 +1520,9 @@ const StyleSheetEntryPtr & StyleSheetTable::GetCurrentEntry() const return m_pImpl->m_pCurrentEntry; } -OUString StyleSheetTable::ConvertStyleName( const OUString& rWWName, bool bExtendedSearch) +OUString StyleSheetTable::ConvertStyleNameExt(const OUString& rWWName) { OUString sRet( rWWName ); - if( bExtendedSearch ) { //search for the rWWName in the IdentifierD of the existing styles and convert the sStyleName member auto findIt = m_pImpl->m_aStyleSheetEntriesMap.find(rWWName); @@ -1530,6 +1534,14 @@ OUString StyleSheetTable::ConvertStyleName( const OUString& rWWName, bool bExten } } + return ConvertStyleName(sRet).first; +} + +std::pair<OUString, bool> +StyleSheetTable::ConvertStyleName(const OUString& rWWName) +{ + OUString sRet(rWWName); + // create a map only once // This maps Word's special style manes to Writer's (the opposite to what MSWordStyles::GetWWId // and ww::GetEnglishNameFromSti do on export). The mapping gives a Writer's style name, which @@ -1657,6 +1669,7 @@ OUString StyleSheetTable::ConvertStyleName( const OUString& rWWName, bool bExten // { "Message Header", "" }, { "Subtitle", "Subtitle" }, // RES_POOLCOLL_DOC_SUBTITLE { "Salutation", "Salutation" }, // RES_POOLCOLL_GREETING + { "Intense Quote", "Intense Quote" }, // N/A // { "Date", "" }, { "Body Text First Indent", "First line indent" }, // RES_POOLCOLL_TEXT_IDENT // { "Body Text First Indent 2", "" }, @@ -1668,6 +1681,7 @@ OUString StyleSheetTable::ConvertStyleName( const OUString& rWWName, bool bExten // { "Block Text", "" }, { "Hyperlink", "Internet link" }, // RES_POOLCHR_INET_NORMAL { "FollowedHyperlink", "Visited Internet Link" }, // RES_POOLCHR_INET_VISIT + { "Intense Emphasis", "Intense Emphasis" }, // N/A { "Strong", "Strong Emphasis" }, // RES_POOLCHR_HTML_STRONG { "Emphasis", "Emphasis" }, // RES_POOLCHR_HTML_EMPHASIS // { "Document Map", "" }, @@ -1684,6 +1698,7 @@ OUString StyleSheetTable::ConvertStyleName( const OUString& rWWName, bool bExten if (const auto aIt = StyleNameMap.find(sRet); aIt != StyleNameMap.end()) { sRet = aIt->second; + return { sRet, true }; } else { @@ -1705,9 +1720,8 @@ OUString StyleSheetTable::ConvertStyleName( const OUString& rWWName, bool bExten // the UI names of built-in styles. if (ReservedStyleNames.find(sRet) != ReservedStyleNames.end() || sRet.endsWith(" (WW)")) sRet += " (WW)"; + return { sRet, false }; } - - return sRet; } void StyleSheetTable::applyDefaults(bool bParaProperties) diff --git a/sw/source/writerfilter/dmapper/StyleSheetTable.hxx b/sw/source/writerfilter/dmapper/StyleSheetTable.hxx index 4980619fd469..d388032cdb46 100644 --- a/sw/source/writerfilter/dmapper/StyleSheetTable.hxx +++ b/sw/source/writerfilter/dmapper/StyleSheetTable.hxx @@ -100,7 +100,8 @@ public: StyleSheetEntryPtr FindStyleSheetByConvertedStyleName(std::u16string_view rIndex); StyleSheetEntryPtr FindDefaultParaStyle(); - OUString ConvertStyleName( const OUString& rWWName, bool bExtendedSearch = false ); + OUString ConvertStyleNameExt(const OUString& rWWName); + static std::pair<OUString, bool> ConvertStyleName(const OUString& rWWName); OUString CloneTOCStyle(FontTablePtr const& rFontTable, StyleSheetEntryPtr const pStyle, OUString const& rName); void ApplyClonedTOCStyles(); |