[Libreoffice-commits] core.git: 2 commits - sw/source writerfilter/source
Michael Stahl (via logerrit)
logerrit at kemper.freedesktop.org
Mon Sep 23 11:36:07 UTC 2019
sw/source/filter/ww8/wrtw8num.cxx | 37 ++++++++++++++++++++--
sw/source/filter/ww8/wrtww8.hxx | 10 +++++
sw/source/filter/ww8/ww8atr.cxx | 13 ++++++-
writerfilter/source/dmapper/DomainMapper_Impl.cxx | 16 +++++++--
writerfilter/source/dmapper/NumberingManager.cxx | 25 +++++++++++---
writerfilter/source/dmapper/NumberingManager.hxx | 7 +++-
6 files changed, 93 insertions(+), 15 deletions(-)
New commits:
commit 1db6fb0f831e92ac3902af9c58e33f49ede5532b
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Sep 20 19:42:16 2019 +0200
Commit: Michael Stahl <michael.stahl at cib.de>
CommitDate: Mon Sep 23 13:35:19 2019 +0200
writerfilter: fix assert importing fdo77404-1.docx
The problem is that StyleSheetTable::ApplyStyleSheets() inserts a
SwNumRule with name "WW8Num1" and then ListDef::CreateNumberingRule()
also wants to insert a SwNumRule with name "WW8Num1" but gets an
exception instead, leaving ListDef::m_xNumRules null, and then
finishParagraph thinks it's numbered but there's no ListId.
Try to avoid collisions of the generated names in
ListDef::GetStyleName(), by checking what styles actually exist in the
document (which works better in the Insert->File case), and
on the assumption that the initialising call always happens before
the using calls.
(regression from 7992bd73a2307edce96a145e954f8e4c3ab9f57d)
Change-Id: I91c98aa897c12778fb214e9690da0bae99550b93
Reviewed-on: https://gerrit.libreoffice.org/79312
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl at cib.de>
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 192b5ab70130..81acdf59ebce 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -1237,9 +1237,10 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap, con
{
bool bNumberingFromBaseStyle = false;
sal_Int32 nListId = pEntry ? lcl_getListId(pEntry, GetStyleSheetTable(), bNumberingFromBaseStyle) : -1;
- if (nListId >= 0 && !pParaContext->isSet(PROP_NUMBERING_STYLE_NAME))
+ auto const pList(GetListTable()->GetList(nListId));
+ if (pList && nListId >= 0 && !pParaContext->isSet(PROP_NUMBERING_STYLE_NAME))
{
- pParaContext->Insert( PROP_NUMBERING_STYLE_NAME, uno::makeAny( ListDef::GetStyleName( nListId ) ), false);
+ pParaContext->Insert( PROP_NUMBERING_STYLE_NAME, uno::makeAny( pList->GetStyleName(nListId) ), false);
isNumberingViaStyle = true;
// Indent properties from the paragraph style have priority
@@ -6075,7 +6076,12 @@ uno::Reference<container::XIndexAccess> DomainMapper_Impl::GetCurrentNumberingRu
*pListLevel = pStyleSheetProperties->GetListLevel();
// So we are in a paragraph style and it has numbering. Look up the relevant numbering rules.
- OUString aListName = ListDef::GetStyleName(nListId);
+ auto const pList(GetListTable()->GetList(nListId));
+ OUString aListName;
+ if (pList)
+ {
+ aListName = pList->GetStyleName(nListId);
+ }
uno::Reference< style::XStyleFamiliesSupplier > xStylesSupplier(GetTextDocument(), uno::UNO_QUERY_THROW);
uno::Reference< container::XNameAccess > xStyleFamilies = xStylesSupplier->getStyleFamilies();
uno::Reference<container::XNameAccess> xNumberingStyles;
@@ -6190,7 +6196,9 @@ sal_Int32 DomainMapper_Impl::getNumberingProperty(const sal_Int32 nListId, sal_I
if (nNumberingLevel < 0) // It seems it's valid to omit numbering level, and in that case it means zero.
nNumberingLevel = 0;
- const OUString aListName = ListDef::GetStyleName(nListId);
+ auto const pList(GetListTable()->GetList(nListId));
+ assert(pList);
+ const OUString aListName = pList->GetStyleName(nListId);
const uno::Reference< style::XStyleFamiliesSupplier > xStylesSupplier(GetTextDocument(), uno::UNO_QUERY_THROW);
const uno::Reference< container::XNameAccess > xStyleFamilies = xStylesSupplier->getStyleFamilies();
uno::Reference<container::XNameAccess> xNumberingStyles;
diff --git a/writerfilter/source/dmapper/NumberingManager.cxx b/writerfilter/source/dmapper/NumberingManager.cxx
index 1b8a8b283f99..8f7d05e5f4d0 100644
--- a/writerfilter/source/dmapper/NumberingManager.cxx
+++ b/writerfilter/source/dmapper/NumberingManager.cxx
@@ -447,12 +447,27 @@ ListDef::~ListDef( )
{
}
-OUString ListDef::GetStyleName( sal_Int32 nId )
+OUString ListDef::GetStyleName(sal_Int32 const nId,
+ uno::Reference<container::XNameContainer> const& xStyles)
{
- OUString sStyleName( "WWNum" );
- sStyleName += OUString::number( nId );
+ if (xStyles.is())
+ {
+ OUString sStyleName( "WWNum" );
+ sStyleName += OUString::number( nId );
+
+ while (xStyles.is() && xStyles->hasByName(sStyleName)) // unique
+ {
+ sStyleName += "a";
+ }
+
+ m_StyleName = sStyleName;
+ }
+ else
+ {
+// fails in rtftok test assert(!m_StyleName.isEmpty()); // must be inited first
+ }
- return sStyleName;
+ return m_StyleName;
}
uno::Sequence<uno::Sequence<beans::PropertyValue>> ListDef::GetMergedPropertyValues()
@@ -519,7 +534,7 @@ void ListDef::CreateNumberingRules( DomainMapper& rDMapper,
xFactory->createInstance("com.sun.star.style.NumberingStyle"),
uno::UNO_QUERY_THROW );
- OUString sStyleName = GetStyleName( GetId( ) );
+ OUString sStyleName = GetStyleName(GetId(), xStyles);
xStyles->insertByName( sStyleName, makeAny( xStyle ) );
diff --git a/writerfilter/source/dmapper/NumberingManager.hxx b/writerfilter/source/dmapper/NumberingManager.hxx
index c484b7bd9803..0ba356f64f3c 100644
--- a/writerfilter/source/dmapper/NumberingManager.hxx
+++ b/writerfilter/source/dmapper/NumberingManager.hxx
@@ -170,6 +170,9 @@ private:
// Cache for the UNO numbering rules
css::uno::Reference< css::container::XIndexReplace > m_xNumRules;
+ /// mapped list style name
+ OUString m_StyleName;
+
public:
typedef tools::SvRef< ListDef > Pointer;
@@ -181,7 +184,9 @@ public:
const AbstractListDef::Pointer& GetAbstractDefinition( ) { return m_pAbstractDef; };
// Mapping functions
- static OUString GetStyleName( sal_Int32 nId );
+ OUString GetStyleName(sal_Int32 nId,
+ css::uno::Reference<css::container::XNameContainer> const& xStyles
+ = css::uno::Reference<css::container::XNameContainer>());
css::uno::Sequence< css::uno::Sequence<css::beans::PropertyValue> > GetMergedPropertyValues();
commit adceab34ca45128d4848edcc58affa220be87686
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Sep 20 17:18:41 2019 +0200
Commit: Michael Stahl <michael.stahl at cib.de>
CommitDate: Mon Sep 23 13:35:14 2019 +0200
sw: DOCX export of lists: handle multiple SwList with same SwNumRule
This can be reproduced with ODT documents, e.g. fdo45994-2.fodt.
Multiple lists use the same list style / SwNumRule - one of them will be
the default list style of the SwList - map the others to duplicated
SwNumRules, each of which will be exported to a new w:abstractNum.
(assert is regression from 1f6b7030cbdc81e8e408e3a13bfcd01fcbdd7550)
Change-Id: Ib691c7c6b0b3e6da27204d038a64f094a1bde17d
Reviewed-on: https://gerrit.libreoffice.org/79309
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl at cib.de>
diff --git a/sw/source/filter/ww8/wrtw8num.cxx b/sw/source/filter/ww8/wrtw8num.cxx
index 807c85251ed1..d9f284c3380b 100644
--- a/sw/source/filter/ww8/wrtw8num.cxx
+++ b/sw/source/filter/ww8/wrtw8num.cxx
@@ -45,9 +45,8 @@ using namespace ::com::sun::star;
using namespace sw::types;
using namespace sw::util;
-sal_uInt16 MSWordExportBase::DuplicateNumRule( const SwNumRule *pRule, sal_uInt8 nLevel, sal_uInt16 nVal )
+SwNumRule* MSWordExportBase::DuplicateNumRuleImpl(const SwNumRule *pRule)
{
- sal_uInt16 nNumId = USHRT_MAX;
const OUString sPrefix("WW8TempExport" + OUString::number( m_nUniqueList++ ));
SwNumRule* pMyNumRule =
new SwNumRule( m_pDoc->GetUniqueNumRuleName( &sPrefix ),
@@ -59,6 +58,14 @@ sal_uInt16 MSWordExportBase::DuplicateNumRule( const SwNumRule *pRule, sal_uInt8
const SwNumFormat& rSubRule = pRule->Get(i);
pMyNumRule->Set( i, rSubRule );
}
+ return pMyNumRule;
+}
+
+sal_uInt16 MSWordExportBase::DuplicateNumRule( const SwNumRule *pRule, sal_uInt8 nLevel, sal_uInt16 nVal )
+{
+ sal_uInt16 nNumId = USHRT_MAX;
+
+ SwNumRule *const pMyNumRule = DuplicateNumRuleImpl(pRule);
SwNumFormat aNumFormat( pMyNumRule->Get( nLevel ) );
aNumFormat.SetStart( nVal );
@@ -72,6 +79,26 @@ sal_uInt16 MSWordExportBase::DuplicateNumRule( const SwNumRule *pRule, sal_uInt8
return nNumId;
}
+// multiple SwList can be based on the same SwNumRule; ensure one w:abstractNum
+// per SwList
+sal_uInt16 MSWordExportBase::DuplicateAbsNum(OUString const& rListId,
+ SwNumRule const& rAbstractRule)
+{
+ auto const it(m_Lists.find(rListId));
+ if (it != m_Lists.end())
+ {
+ return it->second;
+ }
+ else
+ {
+ auto const pNewAbstractRule = DuplicateNumRuleImpl(&rAbstractRule);
+ assert(GetNumberingId(*pNewAbstractRule) == m_pUsedNumTable->size() - 1);
+ (void) pNewAbstractRule;
+ m_Lists.insert(std::make_pair(rListId, m_pUsedNumTable->size() - 1));
+ return m_pUsedNumTable->size() - 1;
+ }
+}
+
// Ideally we want to map SwList to w:abstractNum and SwNumRule to w:num
// The current approach is to keep exporting every SwNumRule to
// 1 w:abstractNum and 1 w:num, and then add extra w:num via this function
@@ -79,11 +106,14 @@ sal_uInt16 MSWordExportBase::DuplicateNumRule( const SwNumRule *pRule, sal_uInt8
// of course this will end up exporting some w:num that aren't actually used.
sal_uInt16 MSWordExportBase::OverrideNumRule(
SwNumRule const& rExistingRule,
+ OUString const& rListId,
SwNumRule const& rAbstractRule)
{
assert(&rExistingRule != &rAbstractRule);
auto const numdef = GetNumberingId(rExistingRule);
- auto const absnumdef = GetNumberingId(rAbstractRule);
+ auto const absnumdef = rListId == rAbstractRule.GetDefaultListId()
+ ? GetNumberingId(rAbstractRule)
+ : DuplicateAbsNum(rListId, rAbstractRule);
auto const mapping = std::make_pair(numdef, absnumdef);
auto it = m_OverridingNumsR.find(mapping);
@@ -91,6 +121,7 @@ sal_uInt16 MSWordExportBase::OverrideNumRule(
{
it = m_OverridingNumsR.insert(std::make_pair(mapping, m_pUsedNumTable->size())).first;
m_OverridingNums.insert(std::make_pair(m_pUsedNumTable->size(), mapping));
+
m_pUsedNumTable->push_back(nullptr); // dummy, it's unique_ptr...
++m_nUniqueList; // counter for DuplicateNumRule...
}
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index 5ca2c60fed45..13661d22e748 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -464,6 +464,9 @@ public:
std::map<size_t, std::pair<size_t, size_t>> m_OverridingNums;
/// same in reverse
std::map<std::pair<size_t, size_t>, size_t> m_OverridingNumsR;
+ /// list-id -> abstractnumdef index
+ std::map<OUString, size_t> m_Lists;
+
const SwTextNode *m_pTopNodeOfHdFtPage; ///< Top node of host page when in hd/ft
std::map< sal_uInt16, sal_uInt16 > m_aRuleDuplicates; //map to Duplicated numrules
std::stack< sal_Int32 > m_aCurrentCharPropStarts; ///< To remember the position in a run.
@@ -653,10 +656,17 @@ public:
/// completely new list based on this one and export that instead,
/// which duplicates words behaviour in this respect.
sal_uInt16 DuplicateNumRule( const SwNumRule *pRule, sal_uInt8 nLevel, sal_uInt16 nVal );
+ SwNumRule * DuplicateNumRuleImpl(const SwNumRule *pRule);
+
+ /// check if a new abstractNum is needed for this list
+ sal_uInt16 DuplicateAbsNum(OUString const& rListId,
+ SwNumRule const& rAbstractRule);
+
/// Create a overriding numbering definition (if it does not yet exist)
/// @return index of the overriding numbering definition
sal_uInt16 OverrideNumRule(SwNumRule const& rExistingRule,
+ OUString const& rListId,
SwNumRule const& rAbstractRule);
/// Access to the attribute output class.
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index 60de4f0df789..7ca8b34cb9a9 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -3561,6 +3561,7 @@ void AttributeOutputBase::ParaNumRule( const SwNumRuleItem& rNumRule )
// tdf#95848 find the abstract list definition
OUString const listId(pTextNd->GetListId());
if (!listId.isEmpty()
+ // default list id uses the 1:1 mapping
&& listId != pRule->GetDefaultListId())
{
SwList const*const pList(
@@ -3571,8 +3572,16 @@ void AttributeOutputBase::ParaNumRule( const SwNumRuleItem& rNumRule )
GetExport().m_pDoc->FindNumRulePtr(
pList->GetDefaultListStyleName()));
assert(pAbstractRule);
- nNumId = GetExport().OverrideNumRule(
- *pRule, *pAbstractRule);
+ if (pAbstractRule == pRule)
+ {
+ // different list, but no override
+ nNumId = GetExport().DuplicateAbsNum(listId, *pAbstractRule);
+ }
+ else
+ {
+ nNumId = GetExport().OverrideNumRule(
+ *pRule, listId, *pAbstractRule);
+ }
assert(nNumId != USHRT_MAX);
++nNumId;
}
More information about the Libreoffice-commits
mailing list