sw/inc/cellatr.hxx                           |    3 +
 sw/inc/cellfml.hxx                           |    2 
 sw/inc/swtable.hxx                           |    3 -
 sw/source/core/attr/cellatr.cxx              |   55 +++++++++------------
 sw/source/core/doc/DocumentFieldsManager.cxx |    2 
 sw/source/core/docnode/ndtbl.cxx             |   23 ++-------
 sw/source/core/table/swtable.cxx             |   68 +++++++++++++++++----------
 7 files changed, 80 insertions(+), 76 deletions(-)

New commits:
commit 31690100461d42fd93b9a1a6546b1e17a8d31720
Author:     Bjoern Michaelsen <bjoern.michael...@libreoffice.org>
AuthorDate: Fri Mar 17 00:26:42 2023 +0100
Commit:     Bjoern Michaelsen <bjoern.michael...@libreoffice.org>
CommitDate: Mon Mar 27 07:15:40 2023 +0000

    refactor table split
    
    Change-Id: Ifd7e77b29205fa505ed2fe41d08b4253f50a99a8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149185
    Tested-by: Jenkins
    Reviewed-by: Bjoern Michaelsen <bjoern.michael...@libreoffice.org>

diff --git a/sw/inc/cellatr.hxx b/sw/inc/cellatr.hxx
index d1de3bbb9136..2d85015a8901 100644
--- a/sw/inc/cellatr.hxx
+++ b/sw/inc/cellatr.hxx
@@ -27,6 +27,8 @@
 #include "hintids.hxx"
 #include "cellfml.hxx"
 
+class SwHistory;
+
 /** The number formatter's default locale's @ Text format.
     Not necessarily system locale, but the locale the formatter was constructed
     with. For this SvNumberFormatter::IsTextFormat() always returns true.
@@ -72,6 +74,7 @@ public:
         { return const_cast<SwTableBoxFormula*>(this)->GetTableBox(); }
 
     void TryBoxNmToPtr();
+    void ToSplitMergeBoxNmWithHistory(SwTableFormulaUpdate& rUpdate, 
SwHistory* pHistory);
     void ChangeState( const SfxPoolItem* pItem );
     void Calc( SwTableCalcPara& rCalcPara, double& rValue );
 };
diff --git a/sw/inc/cellfml.hxx b/sw/inc/cellfml.hxx
index 16ca387305b8..f99c8f87041b 100644
--- a/sw/inc/cellfml.hxx
+++ b/sw/inc/cellfml.hxx
@@ -109,7 +109,6 @@ protected:
                             *rCalcPara.m_pTable, &rCalcPara );
     }
 
-    static sal_uInt16 GetLnPosInTable( const SwTable& rTable, const 
SwTableBox* pBox );
 
 public:
 
@@ -146,6 +145,7 @@ public:
     void GetBoxesOfFormula(const SwTable& rTable, SwSelBoxes& rBoxes);
     // are all boxes valid which this formula relies on?
     bool HasValidBoxes() const;
+    static sal_uInt16 GetLnPosInTable( const SwTable& rTable, const 
SwTableBox* pBox );
 };
 
 #endif
diff --git a/sw/inc/swtable.hxx b/sw/inc/swtable.hxx
index f40059e3c986..3015223ef451 100644
--- a/sw/inc/swtable.hxx
+++ b/sw/inc/swtable.hxx
@@ -176,9 +176,9 @@ private:
     void ConvertSubtableBox(sal_uInt16 const nRow, sal_uInt16 const nBox);
     // Only used for TBL_BOXNAME and TBL_RELBOXNAME for now
     void UpdateFields(TableFormulaUpdateFlags eFlags);
+    void GatherFormulas(std::vector<SwTableBoxFormula*>& rvFormulas);
 
 public:
-
     SwHTMLTableLayout *GetHTMLTableLayout() { return m_xHTMLLayout.get(); }
     const SwHTMLTableLayout *GetHTMLTableLayout() const { return 
m_xHTMLLayout.get(); }
     void SetHTMLTableLayout(std::shared_ptr<SwHTMLTableLayout> const& r);    
//Change of property!
@@ -366,6 +366,7 @@ public:
     void SwitchFormulasToInternalRepresentation()
         { UpdateFields(TBL_BOXPTR); }
     void Merge(SwTable& rTable, SwHistory* pHistory);
+    void Split(OUString sNewTableName, sal_uInt16 nSplitLine, SwHistory* 
pHistory);
 
     void dumpAsXml(xmlTextWriterPtr pWriter) const;
 };
diff --git a/sw/source/core/attr/cellatr.cxx b/sw/source/core/attr/cellatr.cxx
index 02b2923b9f88..1c445bb03067 100644
--- a/sw/source/core/attr/cellatr.cxx
+++ b/sw/source/core/attr/cellatr.cxx
@@ -104,6 +104,28 @@ void SwTableBoxFormula::TryBoxNmToPtr()
         BoxNmToPtr(&pTableNd->GetTable());
     }
 }
+void SwTableBoxFormula::ToSplitMergeBoxNmWithHistory(SwTableFormulaUpdate& 
rUpdate, SwHistory* pHistory)
+{
+    if(!pHistory)
+    {
+        ToSplitMergeBoxNm(rUpdate);
+        return;
+    }
+    auto pNd = GetNodeOfFormula();
+    // for a history record the unchanged formula is needed
+    SwTableBoxFormula aCopy(*this);
+    rUpdate.m_bModified = false;
+    ToSplitMergeBoxNm(rUpdate);
+    if(rUpdate.m_bModified)
+    {
+        // external rendering
+        aCopy.PtrToBoxNm(&pNd->FindTableNode()->GetTable());
+        pHistory->Add(
+            &aCopy,
+            &aCopy,
+            pNd->FindTableBoxStartNode()->GetIndex());
+    }
+}
 void SwTableBoxFormula::ChangeState( const SfxPoolItem* pItem )
 {
     if( !m_pDefinedIn )
@@ -137,40 +159,9 @@ void SwTableBoxFormula::ChangeState( const SfxPoolItem* 
pItem )
     case TBL_BOXPTR:
     case TBL_RELBOXNAME:
     case TBL_BOXNAME:
-        assert(false); // PtrToBoxNm, ToRelBoxNm and BoxNmToPtr are all public 
-- use just them directly
-        break;
-
     case TBL_SPLITTBL:
-        if( &pTableNd->GetTable() == pUpdateField->m_pTable )
-        {
-            sal_uInt16 nLnPos = SwTableFormula::GetLnPosInTable(
-                                    pTableNd->GetTable(), GetTableBox() );
-            pUpdateField->m_bBehindSplitLine = USHRT_MAX != nLnPos &&
-                                        pUpdateField->m_nSplitLine <= nLnPos;
-        }
-        else
-            pUpdateField->m_bBehindSplitLine = false;
-        [[fallthrough]];
     case TBL_MERGETBL:
-        if( pUpdateField->m_pHistory )
-        {
-            // for a history record the unchanged formula is needed
-            SwTableBoxFormula aCopy( *this );
-            pUpdateField->m_bModified = false;
-            ToSplitMergeBoxNm( *pUpdateField );
-
-            if( pUpdateField->m_bModified )
-            {
-                // external rendering
-                aCopy.PtrToBoxNm( &pTableNd->GetTable() );
-                pUpdateField->m_pHistory->Add(
-                    &aCopy,
-                    &aCopy,
-                    pNd->FindTableBoxStartNode()->GetIndex());
-            }
-        }
-        else
-            ToSplitMergeBoxNm( *pUpdateField );
+        assert(false); // PtrToBoxNm, ToRelBoxNm and BoxNmToPtr are all public 
-- use just them directly
         break;
     }
 }
diff --git a/sw/source/core/doc/DocumentFieldsManager.cxx 
b/sw/source/core/doc/DocumentFieldsManager.cxx
index 3ba8c6314cea..788efe790ecb 100644
--- a/sw/source/core/doc/DocumentFieldsManager.cxx
+++ b/sw/source/core/doc/DocumentFieldsManager.cxx
@@ -602,7 +602,7 @@ void DocumentFieldsManager::UpdateTableFields( SfxPoolItem* 
pHt )
     if(pHt && RES_TABLEFML_UPDATE == pHt->Which())
         pUpdateField = static_cast<SwTableFormulaUpdate*>(pHt);
     assert(!pHt || pUpdateField);
-    assert(!pUpdateField || pUpdateField->m_eFlags == TBL_CALC || 
pUpdateField->m_eFlags == TBL_SPLITTBL);
+    assert(!pUpdateField || pUpdateField->m_eFlags == TBL_CALC);
     auto pFieldType = GetFieldType( SwFieldIds::Table, OUString(), false );
     if(pFieldType && (!pUpdateField || pUpdateField->m_eFlags == TBL_CALC))
     {
diff --git a/sw/source/core/docnode/ndtbl.cxx b/sw/source/core/docnode/ndtbl.cxx
index 4526721a3250..b7952080f68c 100644
--- a/sw/source/core/docnode/ndtbl.cxx
+++ b/sw/source/core/docnode/ndtbl.cxx
@@ -3090,33 +3090,22 @@ void SwDoc::SplitTable( const SwPosition& rPos, 
SplitTable_HeadlineOption eHdlnM
     SwTable& rTable = pTNd->GetTable();
     rTable.SetHTMLTableLayout(std::shared_ptr<SwHTMLTableLayout>()); // Delete 
HTML Layout
 
-    SwTableFormulaUpdate aMsgHint( &rTable );
-
     SwHistory aHistory;
-    if (GetIDocumentUndoRedo().DoesUndo())
-    {
-        aMsgHint.m_pHistory = &aHistory;
-    }
-
     {
         SwNodeOffset nSttIdx = pNd->FindTableBoxStartNode()->GetIndex();
-
         // Find top-level Line
-        SwTableBox* pBox = rTable.GetTableBox( nSttIdx );
-        if( pBox )
+        SwTableBox* pBox = rTable.GetTableBox(nSttIdx);
+        sal_uInt16 nSplitLine = 0;
+        if(pBox)
         {
             SwTableLine* pLine = pBox->GetUpper();
-            while( pLine->GetUpper() )
+            while(pLine->GetUpper())
                 pLine = pLine->GetUpper()->GetUpper();
 
             // pLine contains the top-level Line now
-            aMsgHint.m_nSplitLine = rTable.GetTabLines().GetPos( pLine );
+            nSplitLine = rTable.GetTabLines().GetPos(pLine);
         }
-
-        OUString sNewTableNm( GetUniqueTableName() );
-        aMsgHint.m_aData.pNewTableNm = &sNewTableNm;
-        aMsgHint.m_eFlags = TBL_SPLITTBL;
-        getIDocumentFieldsAccess().UpdateTableFields( &aMsgHint );
+        rTable.Split(GetUniqueTableName(), nSplitLine, 
GetIDocumentUndoRedo().DoesUndo() ? &aHistory : nullptr);
     }
 
     // Find Lines for the Layout update
diff --git a/sw/source/core/table/swtable.cxx b/sw/source/core/table/swtable.cxx
index 96d3b4903255..61811d546906 100644
--- a/sw/source/core/table/swtable.cxx
+++ b/sw/source/core/table/swtable.cxx
@@ -1614,40 +1614,60 @@ bool SwTable::IsDeleted() const
     return true;
 }
 
-void SwTable::Merge(SwTable& rTable, SwHistory* pHistory)
+void SwTable::GatherFormulas(std::vector<SwTableBoxFormula*>& rvFormulas)
+{
+    for(SfxPoolItem* pItem: 
GetFrameFormat()->GetDoc()->GetAttrPool().GetItemSurrogates(RES_BOXATR_FORMULA))
+    {
+        auto pBoxFormula = dynamic_cast<SwTableBoxFormula*>(pItem);
+        assert(pBoxFormula); // use StaticWhichCast instead?
+        if(!pBoxFormula->GetDefinedIn())
+            continue;
+        const SwNode* pNd = pBoxFormula->GetNodeOfFormula();
+        if(!pNd || &pNd->GetNodes() != &pNd->GetDoc().GetNodes()) // is this 
ever valid or should we assert here?
+            continue;
+        rvFormulas.push_back(pBoxFormula);
+    }
+}
+
+void SwTable::Split(OUString sNewTableName, sal_uInt16 nSplitLine, SwHistory* 
pHistory)
 {
     SwTableFormulaUpdate aHint(this);
-    aHint.m_aData.pDelTable = &rTable;
-    aHint.m_eFlags = TBL_MERGETBL;
+    aHint.m_eFlags = TBL_SPLITTBL;
+    aHint.m_aData.pNewTableNm = &sNewTableName;
+    aHint.m_nSplitLine = nSplitLine;
     aHint.m_pHistory = pHistory;
-    // process all table box formulas
-    for(SfxPoolItem* pItem : 
GetFrameFormat()->GetDoc()->GetAttrPool().GetItemSurrogates(RES_BOXATR_FORMULA))
+
+    std::vector<SwTableBoxFormula*> vFormulas;
+    GatherFormulas(vFormulas);
+    for(auto pBoxFormula: vFormulas)
     {
-        auto pBoxFormula = pItem->DynamicWhichCast(RES_BOXATR_FORMULA);
-        assert(pBoxFormula);
-        if(pBoxFormula->GetDefinedIn())
+        const SwNode* pNd = pBoxFormula->GetNodeOfFormula();
+        const SwTableNode* pTableNd = pNd->FindTableNode();
+        if(pTableNd == nullptr)
+            continue;
+        if(&pTableNd->GetTable() == this)
         {
-            const SwNode* pNd = pBoxFormula->GetNodeOfFormula();
-            // for a history record the unchanged formula is needed
-            SwTableBoxFormula aCopy(*pBoxFormula);
-            aHint.m_bModified = false;
-            pBoxFormula->ToSplitMergeBoxNm(aHint);
-
-            if(aHint.m_bModified)
-            {
-                // external rendering
-                aCopy.PtrToBoxNm(this);
-                aHint.m_pHistory->Add(
-                    &aCopy,
-                    &aCopy,
-                    pNd->FindTableBoxStartNode()->GetIndex());
-            }
+            sal_uInt16 nLnPos = SwTableFormula::GetLnPosInTable(*this, 
pBoxFormula->GetTableBox());
+            aHint.m_bBehindSplitLine = USHRT_MAX != nLnPos && 
aHint.m_nSplitLine <= nLnPos;
         }
         else
-            pBoxFormula->ToSplitMergeBoxNm(aHint);
+            aHint.m_bBehindSplitLine = false;
+        pBoxFormula->ToSplitMergeBoxNmWithHistory(aHint, pHistory);
     }
 }
 
+void SwTable::Merge(SwTable& rTable, SwHistory* pHistory)
+{
+    SwTableFormulaUpdate aHint(this);
+    aHint.m_eFlags = TBL_MERGETBL;
+    aHint.m_aData.pDelTable = &rTable;
+    aHint.m_pHistory = pHistory;
+    std::vector<SwTableBoxFormula*> vFormulas;
+    GatherFormulas(vFormulas);
+    for(auto pBoxFormula: vFormulas)
+        pBoxFormula->ToSplitMergeBoxNmWithHistory(aHint, pHistory);
+}
+
 void SwTable::UpdateFields(TableFormulaUpdateFlags eFlags)
 {
     auto pDoc = GetFrameFormat()->GetDoc();

Reply via email to