[Libreoffice-commits] core.git: 2 commits - sc/source sw/inc sw/source

Noel Grandin (via logerrit) logerrit at kemper.freedesktop.org
Fri May 10 16:41:14 UTC 2019


 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.grandin at collabora.co.uk>
AuthorDate: Fri May 10 15:40:02 2019 +0200
Commit:     Noel Grandin <noel.grandin at 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.grandin at 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.Stahl at cib.de>
AuthorDate: Fri May 10 11:45:27 2019 +0200
Commit:     Michael Stahl <Michael.Stahl at 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.Stahl at 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);


More information about the Libreoffice-commits mailing list