sc/inc/document.hxx | 12 +++++++++++- sc/inc/rangenam.hxx | 20 ++++++++++++++++++++ sc/qa/unit/ucalc_formula.cxx | 16 ++++++++++++++++ sc/source/core/data/documen2.cxx | 18 +++++++++++++++++- sc/source/core/data/document10.cxx | 7 +++++-- sc/source/core/data/formulacell.cxx | 2 +- sc/source/core/tool/rangenam.cxx | 16 ++++++++++++++++ 7 files changed, 86 insertions(+), 5 deletions(-)
New commits: commit 02a8589553b5ce0e57a7ee9e66327376125b4378 Author: Eike Rathke <er...@redhat.com> Date: Fri Apr 29 22:05:05 2016 +0200 Resolves: tdf#76523 copy used names or pointing to sheet to other document Change-Id: I767ed1f212c257741fd982e8bbd0882a29d439c1 diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index a38279f..05b93f3 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -628,11 +628,21 @@ public: position of the existing name adjusted for Tab. rOldPos.nTab MUST point to the old sheet copied from. + @param bGlobalNamesToLocal + If TRUE, affected global names are copied to sheet-local names. + If FALSE, global names are copied to global names in another document. + + @param bUsedByFormula + If TRUE, forces a global name to be affected/used. + If FALSE, a global name is only affected if it evaluates to be + referencing the sheet. + @return TRUE if copied and caller may need to evaluate rpRangeData and rSheet and rIndex. FALSE if nothing to be done. */ bool CopyAdjustRangeName( SCTAB& rSheet, sal_uInt16& rIndex, ScRangeData*& rpRangeData, ScDocument& rNewDoc, - const ScAddress& rNewPos, const ScAddress& rOldPos, const bool bGlobalNamesToLocal) const; + const ScAddress& rNewPos, const ScAddress& rOldPos, const bool bGlobalNamesToLocal, + const bool bUsedByFormula ) const; /** * Call this immediately before updating all named ranges. diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx index a393463..e92b6a8 100644 --- a/sc/source/core/data/documen2.cxx +++ b/sc/source/core/data/documen2.cxx @@ -987,6 +987,14 @@ sal_uLong ScDocument::TransferTab( ScDocument* pSrcDoc, SCTAB nSrcPos, nDestPos = std::min(nDestPos, (SCTAB)(GetTableCount() - 1)); { // scope for bulk broadcast ScBulkBroadcast aBulkBroadcast( pBASM); + if (!bResultsOnly) + { + const bool bGlobalNamesToLocal = false; + const ScRangeName* pNames = pSrcDoc->GetRangeName( nSrcPos); + if (pNames) + pNames->CopyUsedNames( nSrcPos, nSrcPos, nDestPos, *pSrcDoc, *this, bGlobalNamesToLocal); + pSrcDoc->GetRangeName()->CopyUsedNames( -1, nSrcPos, nDestPos, *pSrcDoc, *this, bGlobalNamesToLocal); + } pSrcDoc->maTabs[nSrcPos]->CopyToTable(aCxt, 0, 0, MAXCOL, MAXROW, ( bResultsOnly ? InsertDeleteFlags::ALL & ~InsertDeleteFlags::FORMULA : InsertDeleteFlags::ALL), false, maTabs[nDestPos] ); diff --git a/sc/source/core/data/document10.cxx b/sc/source/core/data/document10.cxx index f7ed6e8..4690f9b 100644 --- a/sc/source/core/data/document10.cxx +++ b/sc/source/core/data/document10.cxx @@ -656,7 +656,8 @@ ScRangeData* copyRangeNames( SheetIndexMap& rSheetIndexMap, std::vector<ScRangeD } // namespace bool ScDocument::CopyAdjustRangeName( SCTAB& rSheet, sal_uInt16& rIndex, ScRangeData*& rpRangeData, - ScDocument& rNewDoc, const ScAddress& rNewPos, const ScAddress& rOldPos, const bool bGlobalNamesToLocal) const + ScDocument& rNewDoc, const ScAddress& rNewPos, const ScAddress& rOldPos, const bool bGlobalNamesToLocal, + const bool bUsedByFormula ) const { const bool bSameDoc = (rNewDoc.GetPool() == const_cast<ScDocument*>(this)->GetPool()); if (bSameDoc && ((rSheet < 0 && !bGlobalNamesToLocal) || (rSheet >= 0 && rSheet != rOldPos.Tab()))) @@ -725,7 +726,9 @@ bool ScDocument::CopyAdjustRangeName( SCTAB& rSheet, sal_uInt16& rIndex, ScRange // If no range name was found copy it. if (!rpRangeData) { - bool bEarlyBailOut = (nOldSheet < 0 && bSameDoc); + // Do not copy global name if it doesn't reference sheet or is not used + // by a formula copied to another document. + bool bEarlyBailOut = (nOldSheet < 0 && (bSameDoc || !bUsedByFormula)); MightReferenceSheet eMightReference = mightRangeNameReferenceSheet( pOldRangeData, nOldTab); if (bEarlyBailOut && eMightReference == MightReferenceSheet::NONE) return false; diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx index b61d89c..6e3bbca 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -430,7 +430,7 @@ void adjustRangeName(formula::FormulaToken* pToken, ScDocument& rNewDoc, const S ScRangeData* pRangeData = nullptr; SCTAB nSheet = pToken->GetSheet(); sal_uInt16 nIndex = pToken->GetIndex(); - if (!pOldDoc->CopyAdjustRangeName( nSheet, nIndex, pRangeData, rNewDoc, rNewPos, rOldPos, bGlobalNamesToLocal)) + if (!pOldDoc->CopyAdjustRangeName( nSheet, nIndex, pRangeData, rNewDoc, rNewPos, rOldPos, bGlobalNamesToLocal, true)) return; // nothing to do if (!pRangeData) diff --git a/sc/source/core/tool/rangenam.cxx b/sc/source/core/tool/rangenam.cxx index 89500ac..62b90c7 100644 --- a/sc/source/core/tool/rangenam.cxx +++ b/sc/source/core/tool/rangenam.cxx @@ -797,7 +797,7 @@ void ScRangeName::CopyUsedNames( const SCTAB nLocalTab, const SCTAB nOldTab, con ScAddress aNewPos( aOldPos); aNewPos.SetTab( nNewTab); ScRangeData* pRangeData = nullptr; - rOldDoc.CopyAdjustRangeName( nSheet, nIndex, pRangeData, rNewDoc, aNewPos, aOldPos, bGlobalNamesToLocal); + rOldDoc.CopyAdjustRangeName( nSheet, nIndex, pRangeData, rNewDoc, aNewPos, aOldPos, bGlobalNamesToLocal, false); } } commit 8162cf2a005be68262525c2a11947fa0e10d15ed Author: Eike Rathke <er...@redhat.com> Date: Fri Apr 29 21:55:51 2016 +0200 unit test for copying names not used in formulas during sheet-copy ... but global or local name references copied sheet, or all local names. Change-Id: I84b22f444b72b032a339d5826989ad934cc10981 diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx index a58ec4d..d47ea6a 100644 --- a/sc/qa/unit/ucalc_formula.cxx +++ b/sc/qa/unit/ucalc_formula.cxx @@ -3045,10 +3045,18 @@ void Test::testFormulaRefUpdateNameCopySheet() CPPUNIT_ASSERT(bInserted); bInserted = m_pDoc->InsertNewRangeName( "global_local", aPos, "local*1000"); CPPUNIT_ASSERT(bInserted); + bInserted = m_pDoc->InsertNewRangeName( "global_unused", aPos, "$Test2.$A$1"); + CPPUNIT_ASSERT(bInserted); + bInserted = m_pDoc->InsertNewRangeName( "global_unused_noref", aPos, "42"); + CPPUNIT_ASSERT(bInserted); bInserted = m_pDoc->InsertNewRangeName( aPos.Tab(), "local_global", aPos, "global*10000"); CPPUNIT_ASSERT(bInserted); bInserted = m_pDoc->InsertNewRangeName( aPos.Tab(), "local_local", aPos, "local*100000"); CPPUNIT_ASSERT(bInserted); + bInserted = m_pDoc->InsertNewRangeName( aPos.Tab(), "local_unused", aPos, "$Test2.$A$2"); + CPPUNIT_ASSERT(bInserted); + bInserted = m_pDoc->InsertNewRangeName( aPos.Tab(), "local_unused_noref", aPos, "23"); + CPPUNIT_ASSERT(bInserted); m_pDoc->SetString(aPos, "=SHEET()"); aPos.IncRow(); @@ -3093,10 +3101,18 @@ void Test::testFormulaRefUpdateNameCopySheetCheckTab( SCTAB nTab, bool bCheckNam CPPUNIT_ASSERT_MESSAGE("Sheet-local name GLOBAL_GLOBAL should exist", pName); pName = m_pDoc->GetRangeName(nTab)->findByUpperName("GLOBAL_LOCAL"); CPPUNIT_ASSERT_MESSAGE("Sheet-local name GLOBAL_LOCAL should exist", pName); + pName = m_pDoc->GetRangeName(nTab)->findByUpperName("GLOBAL_UNUSED"); + CPPUNIT_ASSERT_MESSAGE("Sheet-local name GLOBAL_UNUSED should exist", pName); + pName = m_pDoc->GetRangeName(nTab)->findByUpperName("GLOBAL_UNUSED_NOREF"); + CPPUNIT_ASSERT_MESSAGE("Sheet-local name GLOBAL_UNUSED_NOREF should not exist", !pName); pName = m_pDoc->GetRangeName(nTab)->findByUpperName("LOCAL_GLOBAL"); CPPUNIT_ASSERT_MESSAGE("Sheet-local name LOCAL_GLOBAL should exist", pName); pName = m_pDoc->GetRangeName(nTab)->findByUpperName("LOCAL_LOCAL"); CPPUNIT_ASSERT_MESSAGE("Sheet-local name LOCAL_LOCAL should exist", pName); + pName = m_pDoc->GetRangeName(nTab)->findByUpperName("LOCAL_UNUSED"); + CPPUNIT_ASSERT_MESSAGE("Sheet-local name LOCAL_UNUSED should exist", pName); + pName = m_pDoc->GetRangeName(nTab)->findByUpperName("LOCAL_UNUSED_NOREF"); + CPPUNIT_ASSERT_MESSAGE("Sheet-local name LOCAL_UNUSED_NOREF should exist", pName); } ScAddress aPos(0,0,0); commit 043df58d1acf247f6ea85985b0531de41906bd4f Author: Eike Rathke <er...@redhat.com> Date: Fri Apr 29 20:17:56 2016 +0200 during copying sheet copy all global and sheet-local names pointing to it ... not just names that are used by formula cells copied along. Change-Id: Ibe7d0e4b45c8e4c68dbaa1f570903e942be85087 diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx index 0d7b311..a393463 100644 --- a/sc/source/core/data/documen2.cxx +++ b/sc/source/core/data/documen2.cxx @@ -873,10 +873,18 @@ bool ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyM if (bValid) { SetNoListening( true ); // noch nicht bei CopyToTable/Insert + + const bool bGlobalNamesToLocal = true; + const SCTAB nRealOldPos = (nNewPos < nOldPos) ? nOldPos - 1 : nOldPos; + const ScRangeName* pNames = GetRangeName( nOldPos); + if (pNames) + pNames->CopyUsedNames( nOldPos, nRealOldPos, nNewPos, *this, *this, bGlobalNamesToLocal); + GetRangeName()->CopyUsedNames( -1, nRealOldPos, nNewPos, *this, *this, bGlobalNamesToLocal); + sc::CopyToDocContext aCopyDocCxt(*this); maTabs[nOldPos]->CopyToTable(aCopyDocCxt, 0, 0, MAXCOL, MAXROW, InsertDeleteFlags::ALL, (pOnlyMarked != nullptr), maTabs[nNewPos], pOnlyMarked, - false /*bAsLink*/, true /*bColRowFlags*/, true /*bGlobalNamesToLocal*/ ); + false /*bAsLink*/, true /*bColRowFlags*/, bGlobalNamesToLocal ); maTabs[nNewPos]->SetTabBgColor(maTabs[nOldPos]->GetTabBgColor()); SCTAB nDz = nNewPos - nOldPos; commit 450a10d5fb193ec2a7d85ae604790b9dda1e3602 Author: Eike Rathke <er...@redhat.com> Date: Fri Apr 29 15:56:24 2016 +0200 introduce ScRangeName::CopyUsedNames() Change-Id: I2f3e88f70e5d7b9b4728f5bdd0a8237c7bcc7dcb diff --git a/sc/inc/rangenam.hxx b/sc/inc/rangenam.hxx index c3fff07..a7a5aa8 100644 --- a/sc/inc/rangenam.hxx +++ b/sc/inc/rangenam.hxx @@ -213,6 +213,26 @@ public: */ void CompileUnresolvedXML( sc::CompileFormulaContext& rCxt ); + /** Copy names while copying a sheet if they reference the sheet to be copied. + + Assumes that new sheet was already inserted, global names have been + updated/adjusted, but sheet-local names on nOldTab are not, as is the + case in ScDocument::CopyTab() + + @param nLocalTab + -1 when operating on global names, else sheet/tab of + sheet-local name scope. The already adjusted tab on which to + find the name. + + @param nOldTab + The original unadjusted tab position. + + @param nNewTab + The new tab position. + */ + void CopyUsedNames( const SCTAB nLocalTab, const SCTAB nOldTab, const SCTAB nNewTab, + const ScDocument& rOldDoc, ScDocument& rNewDoc, const bool bGlobalNamesToLocal ) const; + SC_DLLPUBLIC const_iterator begin() const; SC_DLLPUBLIC const_iterator end() const; SC_DLLPUBLIC iterator begin(); diff --git a/sc/source/core/tool/rangenam.cxx b/sc/source/core/tool/rangenam.cxx index a9ab515..89500ac 100644 --- a/sc/source/core/tool/rangenam.cxx +++ b/sc/source/core/tool/rangenam.cxx @@ -785,6 +785,22 @@ void ScRangeName::CompileUnresolvedXML( sc::CompileFormulaContext& rCxt ) } } +void ScRangeName::CopyUsedNames( const SCTAB nLocalTab, const SCTAB nOldTab, const SCTAB nNewTab, + const ScDocument& rOldDoc, ScDocument& rNewDoc, const bool bGlobalNamesToLocal ) const +{ + for (auto const& itr : m_Data) + { + SCTAB nSheet = (nLocalTab < 0) ? nLocalTab : nOldTab; + sal_uInt16 nIndex = itr.second->GetIndex(); + ScAddress aOldPos( itr.second->GetPos()); + aOldPos.SetTab( nOldTab); + ScAddress aNewPos( aOldPos); + aNewPos.SetTab( nNewTab); + ScRangeData* pRangeData = nullptr; + rOldDoc.CopyAdjustRangeName( nSheet, nIndex, pRangeData, rNewDoc, aNewPos, aOldPos, bGlobalNamesToLocal); + } +} + ScRangeName::const_iterator ScRangeName::begin() const { return m_Data.begin(); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits