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;

Reply via email to