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();