diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2021-01-13 11:03:17 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2021-01-15 21:46:10 +0100 |
commit | e0be320cc790856df4d9a102d15de08aa16217fa (patch) | |
tree | 777d3cc6e5edc37304d15f79f24019f2f949c7ca /sw | |
parent | 994b4232f114f8d75cb32a5b1e701b6c78fd9be4 (diff) |
tdf#135014 sw: fix crash exporting numbering to DOCX
It can happen that the default SwNumRule of a SwList isn't used by
anything directly, but there are other SwNumRule associated with that
SwList and then the DOCX export needs to export it as an abstract
numbering definition.
(regression from 632ee9aae6d5f3cf08b6d6b2789310c20db713b7)
Change-Id: I6b1851980464aaa95bf731a60b7d11ab91cec7b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/109303
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
(cherry picked from commit cd1c9f5167e797807d6726219f06190657f58372)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/109335
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/inc/SwNumberTree.hxx | 14 | ||||
-rw-r--r-- | sw/inc/doc.hxx | 2 | ||||
-rw-r--r-- | sw/inc/list.hxx | 2 | ||||
-rw-r--r-- | sw/source/core/doc/list.cxx | 19 | ||||
-rw-r--r-- | sw/source/core/doc/poolfmt.cxx | 9 | ||||
-rw-r--r-- | sw/source/filter/writer/writer.cxx | 10 | ||||
-rw-r--r-- | sw/source/filter/ww8/rtfexport.cxx | 2 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtw8num.cxx | 4 | ||||
-rw-r--r-- | sw/source/uibase/app/docstyle.cxx | 6 |
9 files changed, 52 insertions, 16 deletions
diff --git a/sw/inc/SwNumberTree.hxx b/sw/inc/SwNumberTree.hxx index 9323d3df5644..66fb1066ae63 100644 --- a/sw/inc/SwNumberTree.hxx +++ b/sw/inc/SwNumberTree.hxx @@ -333,6 +333,13 @@ public: void IsSane(bool bRecursive) const; #endif // DBG_UTIL + /** + Returns how many children this node has got. + + @return number of children + */ + tSwNumberTreeChildren::size_type GetChildCount() const; + protected: /** the children */ tSwNumberTreeChildren mChildren; @@ -354,13 +361,6 @@ protected: */ virtual bool IsNotificationEnabled() const = 0; - /** - Returns how many children this node has got. - - @return number of children - */ - tSwNumberTreeChildren::size_type GetChildCount() const; - // #i64010# - made pure virtual virtual bool HasCountedChildren() const = 0; diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx index ac257a843b92..64ba0b729917 100644 --- a/sw/inc/doc.hxx +++ b/sw/inc/doc.hxx @@ -851,7 +851,7 @@ public: bool IsUsed( const SwModify& ) const; /// Query if table style is used. bool IsUsed( const SwTableAutoFormat& ) const; - static bool IsUsed( const SwNumRule& ); + bool IsUsed( const SwNumRule& ); // Set name of newly loaded document template. size_t SetDocPattern(const OUString& rPatternName); diff --git a/sw/inc/list.hxx b/sw/inc/list.hxx index d8b3e16943ea..64d62faa9c93 100644 --- a/sw/inc/list.hxx +++ b/sw/inc/list.hxx @@ -58,6 +58,8 @@ class SwList bool IsListLevelMarked( const int nListLevel ) const; + bool HasNodes() const; + private: SwList( const SwList& ) = delete; SwList& operator=( const SwList& ) = delete; diff --git a/sw/source/core/doc/list.cxx b/sw/source/core/doc/list.cxx index a87570131e27..7cfd1f10305f 100644 --- a/sw/source/core/doc/list.cxx +++ b/sw/source/core/doc/list.cxx @@ -39,6 +39,8 @@ class SwListImpl const OUString& GetDefaultListStyleName() const { return msDefaultListStyleName;} + bool HasNodes() const; + void InsertListItem( SwNodeNum& rNodeNum, bool isHiddenRedlines, const int nLevel ); static void RemoveListItem( SwNodeNum& rNodeNum ); @@ -121,6 +123,18 @@ SwListImpl::~SwListImpl() COVERITY_NOEXCEPT_FALSE } } +bool SwListImpl::HasNodes() const +{ + for (auto const& rNumberTree : maListTrees) + { + if (rNumberTree.pRoot->GetChildCount() != 0) + { + return true; + } + } + return false; +} + void SwListImpl::InsertListItem( SwNodeNum& rNodeNum, bool const isHiddenRedlines, const int nLevel ) { @@ -224,6 +238,11 @@ SwList::~SwList() { } +bool SwList::HasNodes() const +{ + return mpListImpl->HasNodes(); +} + const OUString & SwList::GetListId() const { return mpListImpl->GetListId(); diff --git a/sw/source/core/doc/poolfmt.cxx b/sw/source/core/doc/poolfmt.cxx index 326e05eaf892..f776a75dccc8 100644 --- a/sw/source/core/doc/poolfmt.cxx +++ b/sw/source/core/doc/poolfmt.cxx @@ -25,6 +25,8 @@ #include <doc.hxx> #include <IDocumentState.hxx> #include <IDocumentStylePoolAccess.hxx> +#include <IDocumentListsAccess.hxx> +#include <list.hxx> #include <poolfmt.hxx> #include <pagedesc.hxx> #include <fmtcol.hxx> @@ -106,9 +108,14 @@ bool SwDoc::IsUsed( const SwTableAutoFormat& rTableAutoFormat) const // See if the NumRule is used bool SwDoc::IsUsed( const SwNumRule& rRule ) { + SwList const*const pList(getIDocumentListsAccess().getListByName(rRule.GetDefaultListId())); bool bUsed = rRule.GetTextNodeListSize() > 0 || rRule.GetParagraphStyleListSize() > 0 || - rRule.IsUsedByRedline(); + rRule.IsUsedByRedline() + // tdf#135014 default num rule is used if any associated num rule is used + || (pList + && pList->GetDefaultListStyleName() == rRule.GetName() + && pList->HasNodes()); return bUsed; } diff --git a/sw/source/filter/writer/writer.cxx b/sw/source/filter/writer/writer.cxx index 501bd8099059..171928f1378a 100644 --- a/sw/source/filter/writer/writer.cxx +++ b/sw/source/filter/writer/writer.cxx @@ -356,15 +356,18 @@ void Writer::PutNumFormatFontsInAttrPool() // it can be removed - it is already in the Pool SfxItemPool& rPool = m_pDoc->GetAttrPool(); const SwNumRuleTable& rListTable = m_pDoc->GetNumRuleTable(); - const SwNumRule* pRule; const SwNumFormat* pFormat; const vcl::Font* pFont; const vcl::Font* pDefFont = &numfunc::GetDefBulletFont(); bool bCheck = false; for( size_t nGet = rListTable.size(); nGet; ) - if( SwDoc::IsUsed( *(pRule = rListTable[ --nGet ] ))) + { + SwNumRule const*const pRule = rListTable[ --nGet ]; + if (m_pDoc->IsUsed(*pRule)) + { for( sal_uInt8 nLvl = 0; nLvl < MAXLEVEL; ++nLvl ) + { if( SVX_NUM_CHAR_SPECIAL == (pFormat = &pRule->Get( nLvl ))->GetNumberingType() || SVX_NUM_BITMAP == pFormat->GetNumberingType() ) { @@ -383,6 +386,9 @@ void Writer::PutNumFormatFontsInAttrPool() pFont->GetFamilyName(), pFont->GetStyleName(), pFont->GetPitch(), pFont->GetCharSet(), RES_CHRATR_FONT )); } + } + } + } } void Writer::PutEditEngFontsInAttrPool() diff --git a/sw/source/filter/ww8/rtfexport.cxx b/sw/source/filter/ww8/rtfexport.cxx index 3cea7bfb88fe..90b73ee35500 100644 --- a/sw/source/filter/ww8/rtfexport.cxx +++ b/sw/source/filter/ww8/rtfexport.cxx @@ -212,7 +212,7 @@ void RtfExport::BuildNumbering() for (auto n = rListTable.size(); n;) { SwNumRule* pRule = rListTable[--n]; - if (!SwDoc::IsUsed(*pRule)) + if (!m_pDoc->IsUsed(*pRule)) continue; if (IsExportNumRule(*pRule)) diff --git a/sw/source/filter/ww8/wrtw8num.cxx b/sw/source/filter/ww8/wrtw8num.cxx index 87a6cb68f111..8554aa46a778 100644 --- a/sw/source/filter/ww8/wrtw8num.cxx +++ b/sw/source/filter/ww8/wrtw8num.cxx @@ -91,6 +91,8 @@ sal_uInt16 MSWordExportBase::OverrideNumRule( const sal_uInt16 absnumdef = rListId == rAbstractRule.GetDefaultListId() ? GetNumberingId(rAbstractRule) : DuplicateAbsNum(rListId, rAbstractRule); + assert(numdef != USHRT_MAX); + assert(absnumdef != USHRT_MAX); auto const mapping = std::make_pair(numdef, absnumdef); auto it = m_OverridingNums.insert(std::make_pair(m_pUsedNumTable->size(), mapping)); @@ -120,7 +122,7 @@ sal_uInt16 MSWordExportBase::GetNumberingId( const SwNumRule& rNumRule ) for ( sal_uInt16 n = m_pUsedNumTable->size(); n; ) { const SwNumRule& rRule = *(*m_pUsedNumTable)[ --n ]; - if ( !SwDoc::IsUsed( rRule ) ) + if (!m_pDoc->IsUsed(rRule)) { m_pUsedNumTable->erase( m_pUsedNumTable->begin() + n ); } diff --git a/sw/source/uibase/app/docstyle.cxx b/sw/source/uibase/app/docstyle.cxx index 693ae7f20b14..92cbe33a4fc0 100644 --- a/sw/source/uibase/app/docstyle.cxx +++ b/sw/source/uibase/app/docstyle.cxx @@ -2245,7 +2245,7 @@ bool SwDocStyleSheet::IsUsed() const case SfxStyleFamily::Page : pMod = pDesc; break; case SfxStyleFamily::Pseudo: - return pNumRule && SwDoc::IsUsed( *pNumRule ); + return pNumRule && rDoc.IsUsed(*pNumRule); case SfxStyleFamily::Table: return pTableFormat && rDoc.IsUsed( *pTableFormat ); @@ -3011,7 +3011,7 @@ SfxStyleSheetBase* SwStyleSheetIterator::First() if ( nSrchMask == SfxStyleSearchBits::Hidden && !rRule.IsHidden( ) ) continue; - bool bUsed = bIsSearchUsed && ( bOrganizer || SwDoc::IsUsed(rRule) ); + bool bUsed = bIsSearchUsed && (bOrganizer || rDoc.IsUsed(rRule)); if( !bUsed ) { if( ( !bSearchHidden && rRule.IsHidden() ) || @@ -3173,7 +3173,7 @@ void SwStyleSheetIterator::AppendStyleList(const std::vector<OUString>& rList, case SwGetPoolIdFromName::NumRule: { SwNumRule* pRule = rDoc.FindNumRulePtr( i ); - bUsed = pRule && SwDoc::IsUsed( *pRule ); + bUsed = pRule && rDoc.IsUsed(*pRule); bHidden = pRule && pRule->IsHidden( ); } break; |