sc/inc/dbdata.hxx | 2 + sc/inc/document.hxx | 2 - sc/qa/unit/data/xlsx/tdf145054.xlsx |binary sc/qa/unit/subsequent_filters_test2.cxx | 18 ++++++++++++ sc/source/core/data/documen2.cxx | 1 sc/source/core/tool/dbdata.cxx | 47 ++++++++++++++++++++++++++++++++ 6 files changed, 69 insertions(+), 1 deletion(-)
New commits: commit d9472a5284fde7bb96823655efcb6eb31f405493 Author: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> AuthorDate: Thu Dec 16 11:50:01 2021 +0100 Commit: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> CommitDate: Thu Jan 27 07:32:39 2022 +0100 tdf#145054 Copy named DBs too when copying sheet Change-Id: I5bf75a7188532776e70c7af64e88371638d76335 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126916 Tested-by: Jenkins Reviewed-by: Kohei Yoshida <ko...@libreoffice.org> Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> diff --git a/sc/inc/dbdata.hxx b/sc/inc/dbdata.hxx index f12ba3fb976d..0e8d53830e53 100644 --- a/sc/inc/dbdata.hxx +++ b/sc/inc/dbdata.hxx @@ -256,6 +256,7 @@ public: ScDBData* findByIndex(sal_uInt16 nIndex); ScDBData* findByUpperName(const OUString& rName); iterator findByUpperName2(const OUString& rName); + ScDBData* findByName(const OUString& rName); /** Takes ownership of p and attempts to insert it into the collection. Deletes p if it could not be inserted, i.e. duplicate name. @@ -333,6 +334,7 @@ public: SCCOL nCol2, SCROW nRow2, SCTAB nTab2, SCCOL nDx, SCROW nDy, SCTAB nDz); void UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos ); + void CopyToTable(SCTAB nOldPos, SCTAB nNewPos); void SetRefreshHandler( const Link<Timer *, void>& rLink ) { aRefreshHandler = rLink; } diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index fa13b7b890e4..85c6829b4a54 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -957,7 +957,7 @@ public: SC_DLLPUBLIC bool RenameTab( SCTAB nTab, const OUString& rName, bool bExternalDocument = false ); bool MoveTab( SCTAB nOldPos, SCTAB nNewPos, ScProgress* pProgress = nullptr ); - bool CopyTab( SCTAB nOldPos, SCTAB nNewPos, + SC_DLLPUBLIC bool CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyMarked = nullptr ); SC_DLLPUBLIC sal_uLong TransferTab(ScDocument& rSrcDoc, SCTAB nSrcPos, SCTAB nDestPos, bool bInsertNew = true, diff --git a/sc/qa/unit/data/xlsx/tdf145054.xlsx b/sc/qa/unit/data/xlsx/tdf145054.xlsx new file mode 100644 index 000000000000..8360ec7e92be Binary files /dev/null and b/sc/qa/unit/data/xlsx/tdf145054.xlsx differ diff --git a/sc/qa/unit/subsequent_filters_test2.cxx b/sc/qa/unit/subsequent_filters_test2.cxx index 4852c1006b13..90a6a11d36d8 100644 --- a/sc/qa/unit/subsequent_filters_test2.cxx +++ b/sc/qa/unit/subsequent_filters_test2.cxx @@ -131,6 +131,7 @@ public: void testVBAUserFunctionXLSM(); void testEmbeddedImageXLS(); void testErrorOnExternalReferences(); + void testTdf145054(); void testTdf84762(); void testTdf44076(); void testEditEngStrikeThroughXLSX(); @@ -239,6 +240,7 @@ public: CPPUNIT_TEST(testVBAUserFunctionXLSM); CPPUNIT_TEST(testEmbeddedImageXLS); CPPUNIT_TEST(testErrorOnExternalReferences); + CPPUNIT_TEST(testTdf145054); CPPUNIT_TEST(testTdf84762); CPPUNIT_TEST(testTdf44076); CPPUNIT_TEST(testEditEngStrikeThroughXLSX); @@ -1047,6 +1049,22 @@ void ScFiltersTest2::testErrorOnExternalReferences() xDocSh->DoClose(); } +void ScFiltersTest2::testTdf145054() +{ + ScDocShellRef xDocSh = loadDoc(u"tdf145054.", FORMAT_XLSX); + CPPUNIT_ASSERT(xDocSh.is()); + + ScDocument& rDoc = xDocSh->GetDocument(); + + // Copy sheet + rDoc.CopyTab(0, 1); + CPPUNIT_ASSERT_EQUAL(SCTAB(2), rDoc.GetTableCount()); + + // Make sure named DB was copied + ScDBData* pDBData = rDoc.GetDBCollection()->getNamedDBs().findByName("__Anonymous_Sheet_DB__1"); + CPPUNIT_ASSERT(pDBData); +} + void ScFiltersTest2::testTdf84762() { ScDocShellRef xDocSh = loadDoc(u"blank.", FORMAT_ODS); diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx index 67f6e9d7ca41..dc23b2c3209e 100644 --- a/sc/source/core/data/documen2.cxx +++ b/sc/source/core/data/documen2.cxx @@ -855,6 +855,7 @@ bool ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyM GetRangeName()->CopyUsedNames( -1, nRealOldPos, nNewPos, *this, *this, bGlobalNamesToLocal); sc::CopyToDocContext aCopyDocCxt(*this); + pDBCollection->CopyToTable(nOldPos, nNewPos); maTabs[nOldPos]->CopyToTable(aCopyDocCxt, 0, 0, MaxCol(), MaxRow(), InsertDeleteFlags::ALL, (pOnlyMarked != nullptr), maTabs[nNewPos].get(), pOnlyMarked, false /*bAsLink*/, true /*bColRowFlags*/, bGlobalNamesToLocal, false /*bCopyCaptions*/ ); diff --git a/sc/source/core/tool/dbdata.cxx b/sc/source/core/tool/dbdata.cxx index e59cc295c7b5..b87e388e79fc 100644 --- a/sc/source/core/tool/dbdata.cxx +++ b/sc/source/core/tool/dbdata.cxx @@ -994,6 +994,20 @@ public: } }; +OUString lcl_IncrementNumberInNamedRange(ScDBCollection::NamedDBs& namedDBs, + const OUString& sOldName,bool bIsUpperName) +{ + sal_Int32 lastIndex = sOldName.lastIndexOf('_'); + sal_Int32 nOldNumber = OUString(sOldName.subView(lastIndex)).toInt32(); + OUString sNewName; + do + { + sNewName = sOldName.subView(0, lastIndex + 1) + OUString::number(++nOldNumber); + } while ((bIsUpperName ? namedDBs.findByUpperName(sNewName) : namedDBs.findByName(sNewName)) + != nullptr); + return sNewName; +} + class FindByCursor { SCCOL mnCol; @@ -1045,6 +1059,17 @@ public: } }; +class FindByName +{ + const OUString& mrName; +public: + explicit FindByName(const OUString& rName) : mrName(rName) {} + bool operator() (std::unique_ptr<ScDBData> const& p) const + { + return p->GetName() == mrName; + } +}; + class FindByPointer { const ScDBData* mpDBData; @@ -1151,6 +1176,12 @@ auto ScDBCollection::NamedDBs::findByUpperName2(const OUString& rName) -> iterat m_DBs.begin(), m_DBs.end(), FindByUpperName(rName)); } +ScDBData* ScDBCollection::NamedDBs::findByName(const OUString& rName) +{ + DBsType::iterator itr = find_if(m_DBs.begin(), m_DBs.end(), FindByName(rName)); + return itr == m_DBs.end() ? nullptr : itr->get(); +} + bool ScDBCollection::NamedDBs::insert(std::unique_ptr<ScDBData> pData) { auto p = pData.get(); @@ -1483,6 +1514,22 @@ void ScDBCollection::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos ) for_each(maAnonDBs.begin(), maAnonDBs.end(), func); } +void ScDBCollection::CopyToTable(SCTAB nOldPos, SCTAB nNewPos) +{ + for (const auto& rxNamedDB : maNamedDBs) + { + if (rxNamedDB->GetTab() != nOldPos) + return; + + OUString newName + = lcl_IncrementNumberInNamedRange(getNamedDBs(), rxNamedDB->GetName(), false); + std::unique_ptr<ScDBData> pDataCopy = std::make_unique<ScDBData>(newName, *rxNamedDB); + pDataCopy->UpdateMoveTab(nOldPos, nNewPos); + pDataCopy->SetIndex(0); + getNamedDBs().insert(std::move(pDataCopy)); + } +} + ScDBData* ScDBCollection::GetDBNearCursor(SCCOL nCol, SCROW nRow, SCTAB nTab ) { ScDBData* pNearData = nullptr;