sc/source/filter/excel/xestyle.cxx | 42 +++++++++++++++++++----- sc/source/filter/inc/xestyle.hxx | 4 ++ sw/inc/doc.hxx | 2 - sw/source/core/doc/doc.cxx | 14 +++----- sw/source/core/inc/SwUndoTOXChange.hxx | 10 +++-- sw/source/core/undo/SwUndoTOXChange.cxx | 56 ++++++++++++++++++-------------- sw/source/uibase/index/toxmgr.cxx | 2 - 7 files changed, 84 insertions(+), 46 deletions(-)
New commits: commit a49f9359d27bf3ca38ddff7ad0920daac8e1bb8d Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Fri May 10 15:40:02 2019 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Fri May 10 18:40:29 2019 +0200 tdf#85470 FILESAVE Very long time spent saving XLSX as XLS This takes the saving from (very long time, I lost patience), to around 2s on my machine. Change-Id: Ife28a1616c0da65070f7e604b256134156af0e9a Reviewed-on: https://gerrit.libreoffice.org/72123 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/sc/source/filter/excel/xestyle.cxx b/sc/source/filter/excel/xestyle.cxx index 6c8ba0549852..3ab025d0cb60 100644 --- a/sc/source/filter/excel/xestyle.cxx +++ b/sc/source/filter/excel/xestyle.cxx @@ -2666,17 +2666,24 @@ void XclExpXFBuffer::SaveXFXml( XclExpXmlStream& rStrm, XclExpXF& rXF ) sal_uInt32 XclExpXFBuffer::FindXF( const ScPatternAttr& rPattern, sal_uInt32 nForceScNumFmt, sal_uInt16 nForceXclFont, bool bForceLineBreak ) const { - for( size_t nPos = 0, nSize = maXFList.GetSize(); nPos < nSize; ++nPos ) + auto it = maXFFindMap.find(&rPattern.GetItemSet()); + if (it == maXFFindMap.end()) + return EXC_XFID_NOTFOUND; + for (auto const & nPos : it->second) if( maXFList.GetRecord( nPos )->Equals( rPattern, nForceScNumFmt, nForceXclFont, bForceLineBreak ) ) - return static_cast< sal_uInt32 >( nPos ); + return nPos; return EXC_XFID_NOTFOUND; } sal_uInt32 XclExpXFBuffer::FindXF( const SfxStyleSheetBase& rStyleSheet ) const { - for( size_t nPos = 0, nSize = maXFList.GetSize(); nPos < nSize; ++nPos ) + const SfxItemSet* pItemSet = &const_cast< SfxStyleSheetBase& >( rStyleSheet ).GetItemSet(); + auto it = maXFFindMap.find(pItemSet); + if (it == maXFFindMap.end()) + return EXC_XFID_NOTFOUND; + for (auto const & nPos : it->second) if( maXFList.GetRecord( nPos )->Equals( rStyleSheet ) ) - return static_cast< sal_uInt32 >( nPos ); + return nPos; return EXC_XFID_NOTFOUND; } @@ -2707,9 +2714,15 @@ sal_uInt32 XclExpXFBuffer::InsertCellXF( const ScPatternAttr* pPattern, sal_Int1 bool& rbPredefined = maBuiltInMap[ EXC_XF_DEFAULTCELL ].mbPredefined; if( rbPredefined ) { + // remove old entry in find-map + auto & rPositions = maXFFindMap[maXFList.GetRecord(EXC_XF_DEFAULTCELL)->GetItemSet()]; + auto it = std::find(rPositions.begin(), rPositions.end(), EXC_XF_DEFAULTCELL); + rPositions.erase(it); // replace default cell pattern XclExpXFRef xNewXF( new XclExpXF( GetRoot(), *pPattern, nScript ) ); maXFList.ReplaceRecord( xNewXF, EXC_XF_DEFAULTCELL ); + // and add new entry in find-map + maXFFindMap[xNewXF->GetItemSet()].push_back(EXC_XF_DEFAULTCELL); rbPredefined = false; } return GetDefCellXFId(); @@ -2721,10 +2734,12 @@ sal_uInt32 XclExpXFBuffer::InsertCellXF( const ScPatternAttr* pPattern, sal_Int1 // not found - insert new cell XF if( maXFList.GetSize() < EXC_XFLIST_HARDLIMIT ) { - maXFList.AppendNewRecord( new XclExpXF( - GetRoot(), *pPattern, nScript, nForceScNumFmt, nForceXclFont, bForceLineBreak ) ); + auto pNewExp = new XclExpXF( + GetRoot(), *pPattern, nScript, nForceScNumFmt, nForceXclFont, bForceLineBreak ); + maXFList.AppendNewRecord( pNewExp ); // do not set nXFId before the AppendNewRecord() call - it may insert 2 XFs (style+cell) nXFId = static_cast< sal_uInt32 >( maXFList.GetSize() - 1 ); + maXFFindMap[pNewExp->GetItemSet()].push_back(nXFId); } else { @@ -2759,8 +2774,15 @@ sal_uInt32 XclExpXFBuffer::InsertStyleXF( const SfxStyleSheetBase& rStyleSheet ) bool& rbPredefined = maBuiltInMap[ nXFId ].mbPredefined; if( rbPredefined ) { + // remove old entry in find-map + auto & rPositions = maXFFindMap[maXFList.GetRecord(nXFId)->GetItemSet()]; + auto it = std::find(rPositions.begin(), rPositions.end(), nXFId); + rPositions.erase(it); // replace predefined built-in style (ReplaceRecord() deletes old record) - maXFList.ReplaceRecord( std::make_shared<XclExpXF>( GetRoot(), rStyleSheet ), nXFId ); + auto pNewExp = std::make_shared<XclExpXF>( GetRoot(), rStyleSheet ); + maXFList.ReplaceRecord( pNewExp, nXFId ); + // and add new entry in find-map + maXFFindMap[pNewExp->GetItemSet()].push_back(nXFId); rbPredefined = false; } } @@ -2785,10 +2807,12 @@ sal_uInt32 XclExpXFBuffer::InsertStyleXF( const SfxStyleSheetBase& rStyleSheet ) nXFId = static_cast< sal_uInt32 >( maXFList.GetSize() ); if( nXFId < EXC_XFLIST_HARDLIMIT ) { - maXFList.AppendNewRecord( new XclExpXF( GetRoot(), rStyleSheet ) ); + auto pNewExp = new XclExpXF( GetRoot(), rStyleSheet ); + maXFList.AppendNewRecord( pNewExp ); // create the STYLE record if( !rStyleSheet.GetName().isEmpty() ) maStyleList.AppendNewRecord( new XclExpStyle( nXFId, rStyleSheet.GetName() ) ); + maXFFindMap[pNewExp->GetItemSet()].push_back(nXFId); } else // list full - fall back to default style XF @@ -2809,6 +2833,7 @@ sal_uInt32 XclExpXFBuffer::AppendBuiltInXF( XclExpXFRef const & xXF, sal_uInt8 n { sal_uInt32 nXFId = static_cast< sal_uInt32 >( maXFList.GetSize() ); maXFList.AppendRecord( xXF ); + maXFFindMap[xXF->GetItemSet()].push_back(nXFId); XclExpBuiltInInfo& rInfo = maBuiltInMap[ nXFId ]; rInfo.mnStyleId = nStyleId; rInfo.mnLevel = nLevel; @@ -2881,6 +2906,7 @@ void XclExpXFBuffer::InsertDefaultRecords() // index 15: default hard cell format, placeholder to be able to add more built-in styles maXFList.AppendNewRecord( new XclExpDefaultXF( GetRoot(), true ) ); + maXFFindMap[maXFList.GetRecord(maXFList.GetSize()-1)->GetItemSet()].push_back(maXFList.GetSize()-1); maBuiltInMap[ EXC_XF_DEFAULTCELL ].mbPredefined = true; // index 16-20: other built-in styles diff --git a/sc/source/filter/inc/xestyle.hxx b/sc/source/filter/inc/xestyle.hxx index bd805ba66147..48b1e53f4fa2 100644 --- a/sc/source/filter/inc/xestyle.hxx +++ b/sc/source/filter/inc/xestyle.hxx @@ -468,6 +468,8 @@ public: virtual void SaveXml( XclExpXmlStream& rStrm ) override; + const SfxItemSet* GetItemSet() const { return mpItemSet; } + protected: explicit XclExpXF( const XclExpRoot& rRoot, bool bCellXF ); @@ -680,6 +682,8 @@ private: typedef ::std::vector< XclExpCellArea > XclExpFillList; XclExpXFList maXFList; /// List of all XF records. + std::unordered_map<const SfxItemSet*, std::vector<sal_uInt32>> + maXFFindMap; /// map of itemset to vector of positions, to speed up find XclExpStyleList maStyleList; /// List of all STYLE records. XclExpBuiltInMap maBuiltInMap; /// Contained elements describe built-in XFs. ScfUInt16Vec maXFIndexVec; /// Maps XF IDs to XF indexes. commit eb8e03006d588f2d953c4fba4e47ced9b53ba6aa Author: Michael Stahl <michael.st...@cib.de> AuthorDate: Fri May 10 11:45:27 2019 +0200 Commit: Michael Stahl <michael.st...@cib.de> CommitDate: Fri May 10 18:40:21 2019 +0200 tdf#125164 sw: reimplement SwUndoTOXChange SwUndoTOXChange was effectively dead code since commit 60732d715698108f9c3a8284bb3e00baaa4e8124 "#i42807# clear undo stack before changing of TOX properties, update TOX after changing properties" and was resurrected by commit 4f0b568ef35353b276ae560fb43502b6f6b2bfdb. * Calling Update() from Undo is wrong, as there is no guarantee that the index was up-to-date before the change * Calling Update() from Redo is pointless, as there will be a Redo of SwUndoUpdateIndex anyway, given that the only caller of ChangeTOX, namely, SwTOXMgr::UpdateOrInsertTOX(), does that * SwUndoTOXChange cannot retain a pointer to SwTOXBase as its life-time is tied to the SwSectionNode * Repeat applying the same attributes to the same ToX is utterly pointless Change-Id: I84a9de3176d1062d1a43acbc9270c547fde7936a Reviewed-on: https://gerrit.libreoffice.org/72118 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@cib.de> diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx index fd8ab6c58fdd..1e78ee0aea40 100644 --- a/sw/inc/doc.hxx +++ b/sw/inc/doc.hxx @@ -1559,7 +1559,7 @@ public: bool bBroadcast = false); // Change a TOX undoable. - void ChangeTOX(SwTOXBase & rTOX, const SwTOXBase & rNew, SwRootFrame const& rLayout); + void ChangeTOX(SwTOXBase & rTOX, const SwTOXBase & rNew); /** Returns a textual description of a PaM. diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx index cee2e7745278..2da307cfd267 100644 --- a/sw/source/core/doc/doc.cxx +++ b/sw/source/core/doc/doc.cxx @@ -1728,22 +1728,20 @@ void SwDoc::AppendUndoForInsertFromDB( const SwPaM& rPam, bool bIsTable ) } } -void SwDoc::ChangeTOX(SwTOXBase & rTOX, const SwTOXBase & rNew, - SwRootFrame const& rLayout) +void SwDoc::ChangeTOX(SwTOXBase & rTOX, const SwTOXBase & rNew) { + assert(dynamic_cast<const SwTOXBaseSection*>(&rTOX)); + SwTOXBaseSection& rTOXSect(static_cast<SwTOXBaseSection&>(rTOX)); + if (GetIDocumentUndoRedo().DoesUndo()) { GetIDocumentUndoRedo().AppendUndo( - std::make_unique<SwUndoTOXChange>(this, &rTOX, rNew)); + std::make_unique<SwUndoTOXChange>(this, rTOXSect, rNew)); } rTOX = rNew; - if (dynamic_cast<const SwTOXBaseSection*>( &rTOX) != nullptr) - { - static_cast<SwTOXBaseSection &>(rTOX).Update(nullptr, &rLayout); - static_cast<SwTOXBaseSection &>(rTOX).UpdatePageNum(); - } + // note: do not Update the ToX here - the caller will do it, with a ViewShell! } OUString SwDoc::GetPaMDescr(const SwPaM & rPam) diff --git a/sw/source/core/inc/SwUndoTOXChange.hxx b/sw/source/core/inc/SwUndoTOXChange.hxx index d78b17e9b8bb..a593bfd6da0a 100644 --- a/sw/source/core/inc/SwUndoTOXChange.hxx +++ b/sw/source/core/inc/SwUndoTOXChange.hxx @@ -24,16 +24,18 @@ #include <tox.hxx> class SwDoc; +class SwTOXBaseSection; class SwUndoTOXChange : public SwUndo { - SwTOXBase * pTOX, aOld, aNew; +private: + SwTOXBase m_Old; + SwTOXBase m_New; - void UpdateTOXBaseSection(); - void DoImpl(); + sal_uLong const m_nNodeIndex; public: - SwUndoTOXChange(const SwDoc* pDoc, SwTOXBase * pTOX, const SwTOXBase & rNew); + SwUndoTOXChange(const SwDoc* pDoc, SwTOXBaseSection const& rTOX, const SwTOXBase & rNew); virtual ~SwUndoTOXChange() override; virtual void UndoImpl( ::sw::UndoRedoContext & ) override; diff --git a/sw/source/core/undo/SwUndoTOXChange.cxx b/sw/source/core/undo/SwUndoTOXChange.cxx index 5b69ab91abe0..4296aa23d35f 100644 --- a/sw/source/core/undo/SwUndoTOXChange.cxx +++ b/sw/source/core/undo/SwUndoTOXChange.cxx @@ -19,10 +19,17 @@ #include <SwUndoTOXChange.hxx> #include <swundo.hxx> +#include <UndoCore.hxx> #include <doctxm.hxx> +#include <doc.hxx> +#include <node.hxx> -SwUndoTOXChange::SwUndoTOXChange(const SwDoc *pDoc, SwTOXBase * _pTOX, const SwTOXBase & rNew) - : SwUndo(SwUndoId::TOXCHANGE, pDoc), pTOX(_pTOX), aOld(*_pTOX), aNew(rNew) +SwUndoTOXChange::SwUndoTOXChange(const SwDoc *pDoc, + SwTOXBaseSection const& rTOX, SwTOXBase const& rNew) + : SwUndo(SwUndoId::TOXCHANGE, pDoc) + , m_Old(rTOX) + , m_New(rNew) + , m_nNodeIndex(rTOX.GetFormat()->GetSectionNode()->GetIndex()) { } @@ -30,38 +37,39 @@ SwUndoTOXChange::~SwUndoTOXChange() { } -void SwUndoTOXChange::UpdateTOXBaseSection() +// get the current ToXBase, which is not necessarily the same instance that existed there before +static SwTOXBase & GetTOX(SwDoc & rDoc, sal_uLong const nNodeIndex) { - if ( dynamic_cast< const SwTOXBaseSection *>( pTOX ) != nullptr ) - { - SwTOXBaseSection * pTOXBase = static_cast<SwTOXBaseSection *>(pTOX); - pTOXBase->Update(); - pTOXBase->UpdatePageNum(); - } + SwSectionNode *const pNode(rDoc.GetNodes()[nNodeIndex]->GetSectionNode()); + assert(pNode); + assert(dynamic_cast<SwTOXBaseSection*>(&pNode->GetSection())); + auto & rTOX(static_cast<SwTOXBaseSection&>(pNode->GetSection())); + return rTOX; } -void SwUndoTOXChange::UndoImpl(::sw::UndoRedoContext &) +void SwUndoTOXChange::UndoImpl(::sw::UndoRedoContext & rContext) { - *pTOX = aOld; - - UpdateTOXBaseSection(); + SwDoc & rDoc(rContext.GetDoc()); + SwTOXBase & rTOX(GetTOX(rDoc, m_nNodeIndex)); + rTOX = m_Old; } -void SwUndoTOXChange::DoImpl() +void SwUndoTOXChange::RedoImpl(::sw::UndoRedoContext & rContext) { - *pTOX = aNew; - - UpdateTOXBaseSection(); + SwDoc & rDoc(rContext.GetDoc()); + SwTOXBase & rTOX(GetTOX(rDoc, m_nNodeIndex)); + rTOX = m_New; } -void SwUndoTOXChange::RedoImpl(::sw::UndoRedoContext &) +void SwUndoTOXChange::RepeatImpl(::sw::RepeatContext & rContext) { - DoImpl(); -} - -void SwUndoTOXChange::RepeatImpl(::sw::RepeatContext &) -{ - DoImpl(); + SwDoc & rDoc(rContext.GetDoc()); + SwTOXBase *const pTOX(SwDoc::GetCurTOX(*rContext.GetRepeatPaM().GetPoint())); + if (pTOX) + { + rDoc.ChangeTOX(*pTOX, m_New); + // intentionally limited to not Update because we'd need layout + } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/uibase/index/toxmgr.cxx b/sw/source/uibase/index/toxmgr.cxx index d2ed262f00b2..0c594c51e0cc 100644 --- a/sw/source/uibase/index/toxmgr.cxx +++ b/sw/source/uibase/index/toxmgr.cxx @@ -439,7 +439,7 @@ bool SwTOXMgr::UpdateOrInsertTOX(const SwTOXDescription& rDesc, pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::TOXCHANGE, nullptr); } - pDoc->ChangeTOX(*pTOX, *pNewTOX, *pSh->GetLayout()); + pDoc->ChangeTOX(*pTOX, *pNewTOX); pTOX->DisableKeepExpression(); pSh->UpdateTableOf(*pTOX, pSet); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits