[Libreoffice-commits] .: Branch 'libreoffice-3-5' - 5 commits - sc/inc sc/qa sc/source
Kohei Yoshida
kohei at kemper.freedesktop.org
Thu Jan 12 18:53:04 PST 2012
sc/inc/dpcachetable.hxx | 1
sc/inc/dpobject.hxx | 25 ++
sc/inc/dpsdbtab.hxx | 5
sc/inc/dptablecache.hxx | 10 +
sc/qa/unit/ucalc.cxx | 43 +++-
sc/source/core/data/documen2.cxx | 6
sc/source/core/data/dpcachetable.cxx | 10 -
sc/source/core/data/dpobject.cxx | 311 ++++++++++++++++++++++++++++-------
sc/source/core/data/dpsdbtab.cxx | 15 -
sc/source/core/data/dpshttab.cxx | 7
sc/source/core/data/dptablecache.cxx | 18 ++
sc/source/ui/unoobj/dapiuno.cxx | 10 -
sc/source/ui/view/dbfunc3.cxx | 11 +
13 files changed, 381 insertions(+), 91 deletions(-)
New commits:
commit 6d7fcd016e661c07b664b6c9b454c42c02537f10
Author: Kohei Yoshida <kohei.yoshida at suse.com>
Date: Thu Jan 12 21:49:24 2012 -0500
Test the new logic of our pivot data cache life cycle.
diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx
index 685f7d2..47c1999 100644
--- a/sc/inc/dpobject.hxx
+++ b/sc/inc/dpobject.hxx
@@ -271,6 +271,7 @@ public:
SheetCaches(ScDocument* pDoc);
bool hasCache(const ScRange& rRange) const;
const ScDPCache* getCache(const ScRange& rRange);
+ size_t size() const;
void updateReference(
UpdateRefMode eMode, const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz);
@@ -294,6 +295,7 @@ public:
NameCaches(ScDocument* pDoc);
bool hasCache(const rtl::OUString& rName) const;
const ScDPCache* getCache(const ::rtl::OUString& rName, const ScRange& rRange);
+ size_t size() const;
private:
void updateCache(const rtl::OUString& rName, const ScRange& rRange, std::set<ScDPObject*>& rRefs);
void removeCache(const ::rtl::OUString& rName);
@@ -329,6 +331,8 @@ public:
public:
DBCaches(ScDocument* pDoc);
const ScDPCache* getCache(sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand);
+ size_t size() const;
+
private:
com::sun::star::uno::Reference<com::sun::star::sdbc::XRowSet> createRowSet(
sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand);
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index d2ebcc2..9b86275 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -1323,6 +1323,7 @@ void Test::testDataPilot()
bSuccess = checkDPTableOutput<5>(m_pDoc, aOutRange, aOutputCheck, "DataPilot table output");
CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
}
+ CPPUNIT_ASSERT_MESSAGE("There should be only one data cache.", pDPs->GetSheetCaches().size() == 1);
// Update the cell values.
double aData2[] = { 100, 200, 300, 400, 500, 600 };
@@ -1361,15 +1362,22 @@ void Test::testDataPilot()
CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
}
+ CPPUNIT_ASSERT_MESSAGE("There should be only one data cache.", pDPs->GetSheetCaches().size() == 1);
+
// Free the first datapilot object after the 2nd one gets reloaded, to
// prevent the data cache from being deleted before the reload.
pDPs->FreeTable(pDPObj);
+ CPPUNIT_ASSERT_MESSAGE("There should be only one data cache.", pDPs->GetSheetCaches().size() == 1);
+
// This time clear the cache to refresh the data from the source range.
CPPUNIT_ASSERT_MESSAGE("This datapilot should be based on sheet data.", pDPObj2->IsSheetData());
std::set<ScDPObject*> aRefs;
sal_uLong nErrId = pDPs->ReloadCache(pDPObj2, aRefs);
- CPPUNIT_ASSERT_MESSAGE("Cache removal failed.", nErrId == 0);
+ CPPUNIT_ASSERT_MESSAGE("Cache reload failed.", nErrId == 0);
+ CPPUNIT_ASSERT_MESSAGE("Reloading a cache shouldn't remove any cache.",
+ pDPs->GetSheetCaches().size() == 1);
+
pDPObj2->ClearSource();
pDPObj2->Output(aOutRange.aStart);
@@ -1395,6 +1403,8 @@ void Test::testDataPilot()
// Swap the two sheets.
m_pDoc->MoveTab(1, 0);
+ CPPUNIT_ASSERT_MESSAGE("Swapping the sheets shouldn't remove the cache.",
+ pDPs->GetSheetCaches().size() == 1);
CPPUNIT_ASSERT_MESSAGE("Cache should have moved.", !pDPs->GetSheetCaches().hasCache(aSrcRange));
aSrcRange.aStart.SetTab(1);
aSrcRange.aEnd.SetTab(1);
@@ -1404,6 +1414,9 @@ void Test::testDataPilot()
CPPUNIT_ASSERT_MESSAGE("There shouldn't be any data pilot table stored with the document.",
pDPs->GetCount() == 0);
+ CPPUNIT_ASSERT_MESSAGE("There shouldn't be any more data cache.",
+ pDPs->GetSheetCaches().size() == 0);
+
m_pDoc->DeleteTab(1);
m_pDoc->DeleteTab(0);
}
@@ -1673,6 +1686,9 @@ void Test::testDataPilotNamedSource()
CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
}
+ CPPUNIT_ASSERT_MESSAGE("There should be one named range data cache.",
+ pDPs->GetNameCaches().size() == 1 && pDPs->GetSheetCaches().size() == 0);
+
// Move the table with pivot table to the left of the source data sheet.
m_pDoc->MoveTab(1, 0);
rtl::OUString aTabName;
@@ -1680,14 +1696,21 @@ void Test::testDataPilotNamedSource()
CPPUNIT_ASSERT_MESSAGE("Wrong sheet name.", aTabName.equalsAscii("Table"));
CPPUNIT_ASSERT_MESSAGE("Pivot table output is on the wrong sheet!",
pDPObj->GetOutRange().aStart.Tab() == 0);
+
+ CPPUNIT_ASSERT_MESSAGE("Moving the pivot table to another sheet shouldn't have changed the cache state.",
+ pDPs->GetNameCaches().size() == 1 && pDPs->GetSheetCaches().size() == 0);
+
const ScSheetSourceDesc* pDesc = pDPObj->GetSheetDesc();
CPPUNIT_ASSERT_MESSAGE("Sheet source description doesn't exist.", pDesc);
CPPUNIT_ASSERT_MESSAGE("Named source range has been altered unexpectedly!",
pDesc->GetRangeName().equals(aRangeName));
CPPUNIT_ASSERT_MESSAGE("Cache should exist.", pDPs->GetNameCaches().hasCache(aRangeName));
+
pDPs->FreeTable(pDPObj);
CPPUNIT_ASSERT_MESSAGE("There should be no more tables.", pDPs->GetCount() == 0);
+ CPPUNIT_ASSERT_MESSAGE("There shouldn't be any more cache stored.",
+ pDPs->GetNameCaches().size() == 0);
pNames->clear();
m_pDoc->DeleteTab(1);
diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx
index bc26c48..3113f1b 100644
--- a/sc/source/core/data/dpobject.cxx
+++ b/sc/source/core/data/dpobject.cxx
@@ -2499,8 +2499,10 @@ const ScDPCache* ScDPCollection::SheetCaches::getCache(const ScRange& rRange)
size_t nIndex = std::distance(maRanges.begin(), it);
CachesType::iterator itCache = maCaches.find(nIndex);
if (itCache == maCaches.end())
- // cache pool and index pool out-of-sync !!!
+ {
+ OSL_FAIL("Cache pool and index pool out-of-sync !!!");
return NULL;
+ }
return itCache->second;
}
@@ -2532,6 +2534,11 @@ const ScDPCache* ScDPCollection::SheetCaches::getCache(const ScRange& rRange)
return p;
}
+size_t ScDPCollection::SheetCaches::size() const
+{
+ return maCaches.size();
+}
+
void ScDPCollection::SheetCaches::updateReference(
UpdateRefMode eMode, const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz)
{
@@ -2579,7 +2586,7 @@ void ScDPCollection::SheetCaches::updateCache(const ScRange& rRange, std::set<Sc
CachesType::iterator itCache = maCaches.find(nIndex);
if (itCache == maCaches.end())
{
- // Cache pool and index pool out-of-sync !!!
+ OSL_FAIL("Cache pool and index pool out-of-sync !!!");
rRefs.clear();
return;
}
@@ -2600,8 +2607,10 @@ void ScDPCollection::SheetCaches::removeCache(const ScRange& rRange)
size_t nIndex = std::distance(maRanges.begin(), it);
CachesType::iterator itCache = maCaches.find(nIndex);
if (itCache == maCaches.end())
- // Cache pool and index pool out-of-sync !!!
+ {
+ OSL_FAIL("Cache pool and index pool out-of-sync !!!");
return;
+ }
it->SetInvalid(); // Make this slot available for future caches.
maCaches.erase(itCache);
@@ -2646,6 +2655,11 @@ const ScDPCache* ScDPCollection::NameCaches::getCache(const OUString& rName, con
return p;
}
+size_t ScDPCollection::NameCaches::size() const
+{
+ return maCaches.size();
+}
+
void ScDPCollection::NameCaches::updateCache(const OUString& rName, const ScRange& rRange, std::set<ScDPObject*>& rRefs)
{
CachesType::iterator itr = maCaches.find(rName);
@@ -2715,6 +2729,11 @@ const ScDPCache* ScDPCollection::DBCaches::getCache(sal_Int32 nSdbType, const OU
return p;
}
+size_t ScDPCollection::DBCaches::size() const
+{
+ return maCaches.size();
+}
+
uno::Reference<sdbc::XRowSet> ScDPCollection::DBCaches::createRowSet(
sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand)
{
commit 65d58adcec970306ac641f49f56404b6be0e1462
Author: Kohei Yoshida <kohei.yoshida at suse.com>
Date: Thu Jan 12 21:19:05 2012 -0500
fdo#43077: Finally, remove data cache when nobody references it.
Also, removed unnecessary reloading of the whole table data when
reference is updated.
diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx
index 5010e69..685f7d2 100644
--- a/sc/inc/dpobject.hxx
+++ b/sc/inc/dpobject.hxx
@@ -253,6 +253,7 @@ public:
class ScDPCollection
{
+ friend class ScDPCache;
public:
/**
@@ -277,6 +278,7 @@ public:
private:
void updateCache(const ScRange& rRange, std::set<ScDPObject*>& rRefs);
void removeCache(const ScRange& rRange);
+ bool remove(const ScDPCache* p);
};
/**
@@ -295,6 +297,7 @@ public:
private:
void updateCache(const rtl::OUString& rName, const ScRange& rRange, std::set<ScDPObject*>& rRefs);
void removeCache(const ::rtl::OUString& rName);
+ bool remove(const ScDPCache* p);
};
/**
@@ -333,6 +336,7 @@ public:
void updateCache(sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand,
std::set<ScDPObject*>& rRefs);
void removeCache(sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand);
+ bool remove(const ScDPCache* p);
};
ScDPCollection(ScDocument* pDocument);
@@ -375,6 +379,10 @@ public:
DBCaches& GetDBCaches();
private:
+ /** Only to be called from ScDPCache::RemoveReference(). */
+ void RemoveCache(const ScDPCache* pCache);
+
+private:
typedef ::boost::ptr_vector<ScDPObject> TablesType;
ScDocument* pDoc;
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 0a08c8f..d2ebcc2 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -1125,6 +1125,7 @@ ScRange insertDPSourceData(ScDocument* pDoc, DPFieldDef aFields[], size_t nField
template<size_t _Size>
bool checkDPTableOutput(ScDocument* pDoc, const ScRange& aOutRange, const char* aOutputCheck[][_Size], const char* pCaption)
{
+ bool bResult = true;
const ScAddress& s = aOutRange.aStart;
const ScAddress& e = aOutRange.aEnd;
SheetPrinter printer(e.Row() - s.Row() + 1, e.Col() - s.Col() + 1);
@@ -1145,18 +1146,18 @@ bool checkDPTableOutput(ScDocument* pDoc, const ScRange& aOutRange, const char*
if (!bEqual)
{
cerr << "Expected: " << aCheckVal << " Actual: " << aVal << endl;
- return false;
+ bResult = false;
}
}
else if (!aVal.isEmpty())
{
cerr << "Empty cell expected" << endl;
- return false;
+ bResult = false;
}
}
}
printer.print(pCaption);
- return true;
+ return bResult;
}
ScDPObject* createDPFromSourceDesc(
@@ -1334,10 +1335,9 @@ void Test::testDataPilot()
printRange(m_pDoc, ScRange(nCol1, nRow1, 0, nCol2, nRow2, 0), "Data sheet content (modified)");
// Now, create a copy of the datapilot object for the updated table, but
- // don't clear the cache which should force the copy to use the old data
+ // don't reload the cache which should force the copy to use the old data
// from the cache.
ScDPObject* pDPObj2 = new ScDPObject(*pDPObj);
- pDPs->FreeTable(pDPObj);
pDPs->InsertNewTable(pDPObj2);
aOutRange = pDPObj2->GetOutRange();
@@ -1361,6 +1361,10 @@ void Test::testDataPilot()
CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
}
+ // Free the first datapilot object after the 2nd one gets reloaded, to
+ // prevent the data cache from being deleted before the reload.
+ pDPs->FreeTable(pDPObj);
+
// This time clear the cache to refresh the data from the source range.
CPPUNIT_ASSERT_MESSAGE("This datapilot should be based on sheet data.", pDPObj2->IsSheetData());
std::set<ScDPObject*> aRefs;
@@ -1396,7 +1400,6 @@ void Test::testDataPilot()
aSrcRange.aEnd.SetTab(1);
CPPUNIT_ASSERT_MESSAGE("Cache should be here.", pDPs->GetSheetCaches().hasCache(aSrcRange));
-
pDPs->FreeTable(pDPObj2);
CPPUNIT_ASSERT_MESSAGE("There shouldn't be any data pilot table stored with the document.",
pDPs->GetCount() == 0);
diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx
index 3332ec9..bc26c48 100644
--- a/sc/source/core/data/dpobject.cxx
+++ b/sc/source/core/data/dpobject.cxx
@@ -774,11 +774,8 @@ void ScDPObject::UpdateReference( UpdateRefMode eUpdateRefMode,
nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
if ( eRes != UR_NOTHING )
{
- ScSheetSourceDesc aNewDesc(pDoc);
- aNewDesc.SetSourceRange(ScRange(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2));
-
- SCsCOL nDiffX = nCol1 - (SCsCOL) pSheetDesc->GetSourceRange().aStart.Col();
- SCsROW nDiffY = nRow1 - (SCsROW) pSheetDesc->GetSourceRange().aStart.Row();
+ SCsCOL nDiffX = nCol1 - pSheetDesc->GetSourceRange().aStart.Col();
+ SCsROW nDiffY = nRow1 - pSheetDesc->GetSourceRange().aStart.Row();
ScQueryParam aParam = pSheetDesc->GetQueryParam();
aParam.nCol1 = sal::static_int_cast<SCCOL>( aParam.nCol1 + nDiffX );
@@ -790,8 +787,8 @@ void ScDPObject::UpdateReference( UpdateRefMode eUpdateRefMode,
if (aParam.GetEntry(i).bDoQuery)
aParam.GetEntry(i).nField += nDiffX;
- aNewDesc.SetQueryParam(aParam);
- SetSheetDesc( aNewDesc ); // allocates new pSheetDesc
+ pSheetDesc->SetQueryParam(aParam);
+ pSheetDesc->SetSourceRange(ScRange(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2));
}
}
}
@@ -2610,6 +2607,22 @@ void ScDPCollection::SheetCaches::removeCache(const ScRange& rRange)
maCaches.erase(itCache);
}
+bool ScDPCollection::SheetCaches::remove(const ScDPCache* p)
+{
+ CachesType::iterator it = maCaches.begin(), itEnd = maCaches.end();
+ for (; it != itEnd; ++it)
+ {
+ if (it->second == p)
+ {
+ size_t idx = it->first;
+ maCaches.erase(it);
+ maRanges[idx].SetInvalid();
+ return true;
+ }
+ }
+ return false;
+}
+
ScDPCollection::NameCaches::NameCaches(ScDocument* pDoc) : mpDoc(pDoc) {}
bool ScDPCollection::NameCaches::hasCache(const OUString& rName) const
@@ -2655,6 +2668,20 @@ void ScDPCollection::NameCaches::removeCache(const OUString& rName)
maCaches.erase(itr);
}
+bool ScDPCollection::NameCaches::remove(const ScDPCache* p)
+{
+ CachesType::iterator it = maCaches.begin(), itEnd = maCaches.end();
+ for (; it != itEnd; ++it)
+ {
+ if (it->second == p)
+ {
+ maCaches.erase(it);
+ return true;
+ }
+ }
+ return false;
+}
+
ScDPCollection::DBType::DBType(sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand) :
mnSdbType(nSdbType), maDBName(rDBName), maCommand(rCommand) {}
@@ -2794,6 +2821,20 @@ void ScDPCollection::DBCaches::removeCache(sal_Int32 nSdbType, const OUString& r
maCaches.erase(itr);
}
+bool ScDPCollection::DBCaches::remove(const ScDPCache* p)
+{
+ CachesType::iterator it = maCaches.begin(), itEnd = maCaches.end();
+ for (; it != itEnd; ++it)
+ {
+ if (it->second == p)
+ {
+ maCaches.erase(it);
+ return true;
+ }
+ }
+ return false;
+}
+
ScDPCollection::ScDPCollection(ScDocument* pDocument) :
pDoc( pDocument ),
maSheetCaches(pDocument),
@@ -3080,6 +3121,21 @@ ScDPCollection::DBCaches& ScDPCollection::GetDBCaches()
return maDBCaches;
}
+void ScDPCollection::RemoveCache(const ScDPCache* pCache)
+{
+ if (maSheetCaches.remove(pCache))
+ // sheet cache removed.
+ return;
+
+ if (maNameCaches.remove(pCache))
+ // named range cache removed.
+ return;
+
+ if (maDBCaches.remove(pCache))
+ // database cache removed.
+ return;
+}
+
bool operator<(const ScDPCollection::DBType& left, const ScDPCollection::DBType& right)
{
if (left.mnSdbType != right.mnSdbType)
diff --git a/sc/source/core/data/dptablecache.cxx b/sc/source/core/data/dptablecache.cxx
index 4ce5195..57f6ce1 100644
--- a/sc/source/core/data/dptablecache.cxx
+++ b/sc/source/core/data/dptablecache.cxx
@@ -37,6 +37,7 @@
#include "queryparam.hxx"
#include "dpglobal.hxx"
#include "dptabdat.hxx"
+#include "dpobject.hxx"
#include "docoptio.hxx"
#include <unotools/textsearch.hxx>
@@ -993,6 +994,8 @@ void ScDPCache::AddReference(ScDPObject* pObj) const
void ScDPCache::RemoveReference(ScDPObject* pObj) const
{
maRefObjects.erase(pObj);
+ if (maRefObjects.empty())
+ mpDoc->GetDPCollection()->RemoveCache(this);
}
const ScDPCache::ObjectSetType& ScDPCache::GetAllReferences() const
commit e6392d2a17c0bee792cfd0060d177e5c6a71f346
Author: Kohei Yoshida <kohei.yoshida at suse.com>
Date: Thu Jan 12 15:22:32 2012 -0500
fdo#43077: Now, refreshing a table should refresh all linked tables.
For efficiency reasons. Otherwise, refreshing n tables individually
would require reloading the same data cache n times.
diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx
index 769e0ac..5010e69 100644
--- a/sc/inc/dpobject.hxx
+++ b/sc/inc/dpobject.hxx
@@ -37,6 +37,8 @@
#include "pivot.hxx"
#include <com/sun/star/sheet/XDimensionsSupplier.hpp>
+#include <set>
+
#include <boost/ptr_container/ptr_list.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/ptr_container/ptr_map.hpp>
@@ -273,6 +275,7 @@ public:
UpdateRefMode eMode, const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz);
private:
+ void updateCache(const ScRange& rRange, std::set<ScDPObject*>& rRefs);
void removeCache(const ScRange& rRange);
};
@@ -290,6 +293,7 @@ public:
bool hasCache(const rtl::OUString& rName) const;
const ScDPCache* getCache(const ::rtl::OUString& rName, const ScRange& rRange);
private:
+ void updateCache(const rtl::OUString& rName, const ScRange& rRange, std::set<ScDPObject*>& rRefs);
void removeCache(const ::rtl::OUString& rName);
};
@@ -323,6 +327,11 @@ public:
DBCaches(ScDocument* pDoc);
const ScDPCache* getCache(sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand);
private:
+ com::sun::star::uno::Reference<com::sun::star::sdbc::XRowSet> createRowSet(
+ sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand);
+
+ void updateCache(sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand,
+ std::set<ScDPObject*>& rRefs);
void removeCache(sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand);
};
@@ -330,7 +339,7 @@ public:
ScDPCollection(const ScDPCollection& r);
~ScDPCollection();
- sal_uLong ClearCache(ScDPObject* pDPObj);
+ sal_uLong ReloadCache(ScDPObject* pDPObj, std::set<ScDPObject*>& rRefs);
SC_DLLPUBLIC size_t GetCount() const;
SC_DLLPUBLIC ScDPObject* operator[](size_t nIndex);
diff --git a/sc/inc/dptablecache.hxx b/sc/inc/dptablecache.hxx
index a67103d..882f422 100644
--- a/sc/inc/dptablecache.hxx
+++ b/sc/inc/dptablecache.hxx
@@ -50,10 +50,10 @@ class SC_DLLPUBLIC ScDPCache
{
public:
typedef ::boost::ptr_vector<ScDPItemData> DataListType;
+ typedef std::set<ScDPObject*> ObjectSetType;
private:
typedef ::boost::ptr_vector<DataListType> DataGridType;
typedef ::boost::ptr_vector< ::std::vector<SCROW> > RowGridType;
- typedef std::set<ScDPObject*> ObjectSetType;
ScDocument* mpDoc;
long mnColumnCount;
@@ -96,6 +96,7 @@ private:
public:
void AddReference(ScDPObject* pObj) const;
void RemoveReference(ScDPObject* pObj) const;
+ const ObjectSetType& GetAllReferences() const;
SCROW GetIdByItemData( long nDim, const String& sItemData ) const;
SCROW GetIdByItemData( long nDim, const ScDPItemData& rData ) const;
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 419ce63..0a08c8f 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -1363,7 +1363,8 @@ void Test::testDataPilot()
// This time clear the cache to refresh the data from the source range.
CPPUNIT_ASSERT_MESSAGE("This datapilot should be based on sheet data.", pDPObj2->IsSheetData());
- sal_uLong nErrId = pDPs->ClearCache(pDPObj2);
+ std::set<ScDPObject*> aRefs;
+ sal_uLong nErrId = pDPs->ReloadCache(pDPObj2, aRefs);
CPPUNIT_ASSERT_MESSAGE("Cache removal failed.", nErrId == 0);
pDPObj2->ClearSource();
pDPObj2->Output(aOutRange.aStart);
diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx
index 3999d55..3332ec9 100644
--- a/sc/source/core/data/dpobject.cxx
+++ b/sc/source/core/data/dpobject.cxx
@@ -2568,6 +2568,31 @@ void ScDPCollection::SheetCaches::updateReference(
}
}
+void ScDPCollection::SheetCaches::updateCache(const ScRange& rRange, std::set<ScDPObject*>& rRefs)
+{
+ RangeIndexType::iterator it = std::find(maRanges.begin(), maRanges.end(), rRange);
+ if (it == maRanges.end())
+ {
+ // Not cached. Nothing to do.
+ rRefs.clear();
+ return;
+ }
+
+ size_t nIndex = std::distance(maRanges.begin(), it);
+ CachesType::iterator itCache = maCaches.find(nIndex);
+ if (itCache == maCaches.end())
+ {
+ // Cache pool and index pool out-of-sync !!!
+ rRefs.clear();
+ return;
+ }
+
+ ScDPCache& rCache = *itCache->second;
+ rCache.InitFromDoc(mpDoc, rRange);
+ std::set<ScDPObject*> aRefs(rCache.GetAllReferences());
+ rRefs.swap(aRefs);
+}
+
void ScDPCollection::SheetCaches::removeCache(const ScRange& rRange)
{
RangeIndexType::iterator it = std::find(maRanges.begin(), maRanges.end(), rRange);
@@ -2608,6 +2633,21 @@ const ScDPCache* ScDPCollection::NameCaches::getCache(const OUString& rName, con
return p;
}
+void ScDPCollection::NameCaches::updateCache(const OUString& rName, const ScRange& rRange, std::set<ScDPObject*>& rRefs)
+{
+ CachesType::iterator itr = maCaches.find(rName);
+ if (itr == maCaches.end())
+ {
+ rRefs.clear();
+ return;
+ }
+
+ ScDPCache& rCache = *itr->second;
+ rCache.InitFromDoc(mpDoc, rRange);
+ std::set<ScDPObject*> aRefs(rCache.GetAllReferences());
+ rRefs.swap(aRefs);
+}
+
void ScDPCollection::NameCaches::removeCache(const OUString& rName)
{
CachesType::iterator itr = maCaches.find(rName);
@@ -2633,68 +2673,117 @@ const ScDPCache* ScDPCollection::DBCaches::getCache(sal_Int32 nSdbType, const OU
// already cached.
return itr->second;
- uno::Reference<sdbc::XRowSet> xRowSet ;
+ uno::Reference<sdbc::XRowSet> xRowSet = createRowSet(nSdbType, rDBName, rCommand);
+ if (!xRowSet.is())
+ return NULL;
+
+ SAL_WNODEPRECATED_DECLARATIONS_PUSH
+ ::std::auto_ptr<ScDPCache> pCache(new ScDPCache(mpDoc));
+ SAL_WNODEPRECATED_DECLARATIONS_POP
+ SvNumberFormatter aFormat(mpDoc->GetServiceManager(), ScGlobal::eLnge);
+ pCache->InitFromDataBase(xRowSet, *aFormat.GetNullDate());
+ ::comphelper::disposeComponent(xRowSet);
+ const ScDPCache* p = pCache.get();
+ maCaches.insert(aType, pCache);
+ return p;
+}
+
+uno::Reference<sdbc::XRowSet> ScDPCollection::DBCaches::createRowSet(
+ sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand)
+{
+ uno::Reference<sdbc::XRowSet> xRowSet;
try
{
xRowSet = uno::Reference<sdbc::XRowSet>(
comphelper::getProcessServiceFactory()->createInstance(
- rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_SERVICE_ROWSET )) ),
- uno::UNO_QUERY);
- uno::Reference<beans::XPropertySet> xRowProp( xRowSet, uno::UNO_QUERY );
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_SERVICE_ROWSET))),
+ UNO_QUERY);
+
+ uno::Reference<beans::XPropertySet> xRowProp(xRowSet, UNO_QUERY);
OSL_ENSURE( xRowProp.is(), "can't get RowSet" );
- if ( xRowProp.is() )
+ if (!xRowProp.is())
{
- //
- // set source parameters
- //
- uno::Any aAny;
- aAny <<= rDBName;
- xRowProp->setPropertyValue(
- rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_DBPROP_DATASOURCENAME)), aAny );
-
- aAny <<= rCommand;
- xRowProp->setPropertyValue(
- rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_DBPROP_COMMAND)), aAny );
-
- aAny <<= nSdbType;
- xRowProp->setPropertyValue(
- rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_DBPROP_COMMANDTYPE)), aAny );
-
- uno::Reference<sdb::XCompletedExecution> xExecute( xRowSet, uno::UNO_QUERY );
- if ( xExecute.is() )
- {
- uno::Reference<task::XInteractionHandler> xHandler(
- comphelper::getProcessServiceFactory()->createInstance(
- rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_SERVICE_INTHANDLER )) ),
- uno::UNO_QUERY);
- xExecute->executeWithCompletion( xHandler );
- }
- else
- xRowSet->execute();
+ xRowSet.set(NULL);
+ return xRowSet;
+ }
+
+ //
+ // set source parameters
+ //
+ uno::Any aAny;
+ aAny <<= rDBName;
+ xRowProp->setPropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_DBPROP_DATASOURCENAME)), aAny );
+
+ aAny <<= rCommand;
+ xRowProp->setPropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_DBPROP_COMMAND)), aAny );
+
+ aAny <<= nSdbType;
+ xRowProp->setPropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_DBPROP_COMMANDTYPE)), aAny );
+
+ uno::Reference<sdb::XCompletedExecution> xExecute( xRowSet, uno::UNO_QUERY );
+ if ( xExecute.is() )
+ {
+ uno::Reference<task::XInteractionHandler> xHandler(
+ comphelper::getProcessServiceFactory()->createInstance(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_SERVICE_INTHANDLER )) ),
+ uno::UNO_QUERY);
+ xExecute->executeWithCompletion( xHandler );
}
+ else
+ xRowSet->execute();
+
+ return xRowSet;
}
catch ( const sdbc::SQLException& rError )
{
//! store error message
InfoBox aInfoBox( 0, String(rError.Message) );
aInfoBox.Execute();
- return NULL;
}
catch ( uno::Exception& )
{
OSL_FAIL("Unexpected exception in database");
- return NULL;
}
- SAL_WNODEPRECATED_DECLARATIONS_PUSH
- ::std::auto_ptr<ScDPCache> pCache(new ScDPCache(mpDoc));
- SAL_WNODEPRECATED_DECLARATIONS_POP
+ xRowSet.set(NULL);
+ return xRowSet;
+}
+
+void ScDPCollection::DBCaches::updateCache(
+ sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand, std::set<ScDPObject*>& rRefs)
+{
+ DBType aType(nSdbType, rDBName, rCommand);
+ CachesType::iterator it = maCaches.find(aType);
+ if (it == maCaches.end())
+ {
+ // not cached.
+ rRefs.clear();
+ return;
+ }
+
+ ScDPCache& rCache = *it->second;
+
+ uno::Reference<sdbc::XRowSet> xRowSet = createRowSet(nSdbType, rDBName, rCommand);
+ if (!xRowSet.is())
+ {
+ rRefs.clear();
+ return;
+ }
+
SvNumberFormatter aFormat(mpDoc->GetServiceManager(), ScGlobal::eLnge);
- pCache->InitFromDataBase(xRowSet, *aFormat.GetNullDate());
- ::comphelper::disposeComponent(xRowSet);
- const ScDPCache* p = pCache.get();
- maCaches.insert(aType, pCache);
- return p;
+ if (!rCache.InitFromDataBase(xRowSet, *aFormat.GetNullDate()))
+ {
+ // initialization failed.
+ rRefs.clear();
+ return;
+ }
+
+ comphelper::disposeComponent(xRowSet);
+ std::set<ScDPObject*> aRefs(rCache.GetAllReferences());
+ aRefs.swap(rRefs);
}
void ScDPCollection::DBCaches::removeCache(sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand)
@@ -2745,7 +2834,7 @@ public:
}
-sal_uLong ScDPCollection::ClearCache(ScDPObject* pDPObj)
+sal_uLong ScDPCollection::ReloadCache(ScDPObject* pDPObj, std::set<ScDPObject*>& rRefs)
{
if (pDPObj->IsSheetData())
{
@@ -2762,13 +2851,13 @@ sal_uLong ScDPCollection::ClearCache(ScDPObject* pDPObj)
{
// cache by named range
ScDPCollection::NameCaches& rCaches = GetNameCaches();
- rCaches.removeCache(pDesc->GetRangeName());
+ rCaches.updateCache(pDesc->GetRangeName(), pDesc->GetSourceRange(), rRefs);
}
else
{
// cache by cell range
ScDPCollection::SheetCaches& rCaches = GetSheetCaches();
- rCaches.removeCache(pDesc->GetSourceRange());
+ rCaches.updateCache(pDesc->GetSourceRange(), rRefs);
}
}
else if (pDPObj->IsImportData())
@@ -2779,7 +2868,8 @@ sal_uLong ScDPCollection::ClearCache(ScDPObject* pDPObj)
return STR_ERR_DATAPILOTSOURCE;
ScDPCollection::DBCaches& rCaches = GetDBCaches();
- rCaches.removeCache(pDesc->GetCommandType(), pDesc->aDBName, pDesc->aObject);
+ rCaches.updateCache(
+ pDesc->GetCommandType(), pDesc->aDBName, pDesc->aObject, rRefs);
}
return 0;
}
diff --git a/sc/source/core/data/dptablecache.cxx b/sc/source/core/data/dptablecache.cxx
index 683a875..4ce5195 100644
--- a/sc/source/core/data/dptablecache.cxx
+++ b/sc/source/core/data/dptablecache.cxx
@@ -995,6 +995,11 @@ void ScDPCache::RemoveReference(ScDPObject* pObj) const
maRefObjects.erase(pObj);
}
+const ScDPCache::ObjectSetType& ScDPCache::GetAllReferences() const
+{
+ return maRefObjects;
+}
+
SCROW ScDPCache::GetIdByItemData(long nDim, const String& sItemData ) const
{
if ( nDim < mnColumnCount && nDim >=0 )
diff --git a/sc/source/ui/unoobj/dapiuno.cxx b/sc/source/ui/unoobj/dapiuno.cxx
index 5a5bed3..e67f1ab 100644
--- a/sc/source/ui/unoobj/dapiuno.cxx
+++ b/sc/source/ui/unoobj/dapiuno.cxx
@@ -1276,8 +1276,14 @@ void SAL_CALL ScDataPilotTableObj::refresh() throw(RuntimeException)
if (pDPObj)
{
ScDBDocFunc aFunc(*GetDocShell());
- GetDocShell()->GetDocument()->GetDPCollection()->ClearCache(pDPObj);
- aFunc.DataPilotUpdate( pDPObj, pDPObj, true, true );
+ std::set<ScDPObject*> aRefs;
+ GetDocShell()->GetDocument()->GetDPCollection()->ReloadCache(pDPObj, aRefs);
+ std::set<ScDPObject*>::iterator it = aRefs.begin(), itEnd = aRefs.end();
+ for (; it != itEnd; ++it)
+ {
+ ScDPObject* pObj = *it;
+ aFunc.DataPilotUpdate(pObj, pObj, true, true);
+ }
}
}
diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx
index 0d4de94..b717742 100644
--- a/sc/source/ui/view/dbfunc3.cxx
+++ b/sc/source/ui/view/dbfunc3.cxx
@@ -707,7 +707,8 @@ void ScDBFunc::RecalcPivotTable()
{
// Remove existing data cache for the data that this datapilot uses,
// to force re-build data cache.
- sal_uLong nErrId = pDPs->ClearCache(pDPObj);
+ std::set<ScDPObject*> aRefs;
+ sal_uLong nErrId = pDPs->ReloadCache(pDPObj, aRefs);
if (nErrId)
{
ErrorMessage(nErrId);
@@ -715,7 +716,13 @@ void ScDBFunc::RecalcPivotTable()
}
ScDBDocFunc aFunc( *pDocSh );
- aFunc.DataPilotUpdate( pDPObj, pDPObj, true, false );
+ std::set<ScDPObject*>::iterator it = aRefs.begin(), itEnd = aRefs.end();
+ for (; it != itEnd; ++it)
+ {
+ ScDPObject* pObj = *it;
+ aFunc.DataPilotUpdate(pObj, pObj, true, false);
+ }
+
CursorPosChanged(); // shells may be switched
}
else
commit 29cfe42f6473fa2e7351f98d5f3480ffbd9904fe
Author: Kohei Yoshida <kohei.yoshida at suse.com>
Date: Thu Jan 12 14:09:32 2012 -0500
fdo#43077: Have cache instance keep track of who is referencing it.
With this change, ScDPCacheTable should never clear pointer to the
data cache instance; it should keep the same data cache instance that
it is instantiated with.
diff --git a/sc/inc/dpcachetable.hxx b/sc/inc/dpcachetable.hxx
index 62efc84..695586f 100644
--- a/sc/inc/dpcachetable.hxx
+++ b/sc/inc/dpcachetable.hxx
@@ -175,7 +175,6 @@ public:
SCROW getOrder(long nDim, SCROW nIndex) const;
void clear();
bool empty() const;
- void setCache(const ScDPCache* p);
bool hasCache() const;
private:
diff --git a/sc/inc/dpsdbtab.hxx b/sc/inc/dpsdbtab.hxx
index 87c3ccd..8be0cb9 100644
--- a/sc/inc/dpsdbtab.hxx
+++ b/sc/inc/dpsdbtab.hxx
@@ -38,6 +38,7 @@
class ScDPCacheTable;
class ScDocument;
+class ScDPCache;
struct ScImportSourceDesc
{
@@ -69,8 +70,8 @@ private:
const ScImportSourceDesc& mrImport;
ScDPCacheTable aCacheTable;
public:
- ScDatabaseDPData(ScDocument* pDoc, const ScImportSourceDesc& rImport);
- virtual ~ScDatabaseDPData();
+ ScDatabaseDPData(ScDocument* pDoc, const ScImportSourceDesc& rImport, const ScDPCache* pCache);
+ virtual ~ScDatabaseDPData();
virtual long GetColumnCount();
virtual String getDimensionName(long nColumn);
diff --git a/sc/inc/dptablecache.hxx b/sc/inc/dptablecache.hxx
index 950cc54..a67103d 100644
--- a/sc/inc/dptablecache.hxx
+++ b/sc/inc/dptablecache.hxx
@@ -53,11 +53,17 @@ public:
private:
typedef ::boost::ptr_vector<DataListType> DataGridType;
typedef ::boost::ptr_vector< ::std::vector<SCROW> > RowGridType;
+ typedef std::set<ScDPObject*> ObjectSetType;
ScDocument* mpDoc;
long mnColumnCount;
/**
+ * All pivot table objects that references this cache.
+ */
+ mutable ObjectSetType maRefObjects;
+
+ /**
* This container stores only the unique instances of item data in each
* column. Duplicates are not allowed.
*/
@@ -88,6 +94,9 @@ private:
mutable ScDPItemDataPool maAdditionalData;
public:
+ void AddReference(ScDPObject* pObj) const;
+ void RemoveReference(ScDPObject* pObj) const;
+
SCROW GetIdByItemData( long nDim, const String& sItemData ) const;
SCROW GetIdByItemData( long nDim, const ScDPItemData& rData ) const;
diff --git a/sc/source/core/data/dpcachetable.cxx b/sc/source/core/data/dpcachetable.cxx
index adc3cff..ae9ca76 100644
--- a/sc/source/core/data/dpcachetable.cxx
+++ b/sc/source/core/data/dpcachetable.cxx
@@ -414,24 +414,18 @@ void ScDPCacheTable::filterTable(const vector<Criterion>& rCriteria, Sequence< S
SCROW ScDPCacheTable::getOrder(long nDim, SCROW nIndex) const
{
- return mpCache ? getCache()->GetOrder(nDim, nIndex) : 0;
+ return mpCache->GetOrder(nDim, nIndex);
}
void ScDPCacheTable::clear()
{
maFieldEntries.clear();
maRowFlags.clear();
- mpCache = NULL;
}
bool ScDPCacheTable::empty() const
{
- return mpCache == NULL || maFieldEntries.empty();
-}
-
-void ScDPCacheTable::setCache(const ScDPCache* p)
-{
- mpCache = p;
+ return maFieldEntries.empty();
}
bool ScDPCacheTable::hasCache() const
diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx
index a6f48db..3999d55 100644
--- a/sc/source/core/data/dpobject.cxx
+++ b/sc/source/core/data/dpobject.cxx
@@ -460,7 +460,12 @@ ScDPTableData* ScDPObject::GetTableData()
if ( pImpDesc )
{
// database data
- pData.reset(new ScDatabaseDPData(pDoc, *pImpDesc));
+ const ScDPCache* pCache = pImpDesc->CreateCache();
+ if (pCache)
+ {
+ pCache->AddReference(this);
+ pData.reset(new ScDatabaseDPData(pDoc, *pImpDesc, pCache));
+ }
}
else
{
@@ -478,7 +483,10 @@ ScDPTableData* ScDPObject::GetTableData()
DisableGetPivotData aSwitch(*this, mbEnableGetPivotData);
const ScDPCache* pCache = pSheetDesc->CreateCache();
if (pCache)
+ {
+ pCache->AddReference(this);
pData.reset(new ScSheetDPData(pDoc, *pSheetDesc, pCache));
+ }
}
}
@@ -572,6 +580,8 @@ void ScDPObject::ClearSource()
}
}
xSource = NULL;
+ if (mpTableData)
+ mpTableData->GetCacheTable().getCache()->RemoveReference(this);
mpTableData.reset();
}
diff --git a/sc/source/core/data/dpsdbtab.cxx b/sc/source/core/data/dpsdbtab.cxx
index 0f410e1..1cfa2f8 100644
--- a/sc/source/core/data/dpsdbtab.cxx
+++ b/sc/source/core/data/dpsdbtab.cxx
@@ -77,10 +77,11 @@ const ScDPCache* ScImportSourceDesc::CreateCache() const
return rCaches.getCache(nSdbType, aDBName, aObject);
}
-ScDatabaseDPData::ScDatabaseDPData(ScDocument* pDoc, const ScImportSourceDesc& rImport) :
+ScDatabaseDPData::ScDatabaseDPData(
+ ScDocument* pDoc, const ScImportSourceDesc& rImport, const ScDPCache* pCache) :
ScDPTableData(pDoc),
mrImport(rImport),
- aCacheTable(rImport.CreateCache())
+ aCacheTable(pCache)
{
}
@@ -139,12 +140,10 @@ void ScDatabaseDPData::CreateCacheTable()
if (!aCacheTable.hasCache())
{
- const ScDPCache* pCache = mrImport.CreateCache();
- if (!pCache)
- // Cache creation failed. Perhaps invalid database connection.
- return;
-
- aCacheTable.setCache(pCache);
+ fprintf(stdout, "ScDatabaseDPData::CreateCacheTable: NOT GOOD!\n");
+ // This better not happen!! Cache table should be created with a live
+ // data cache instance at all times.
+ return;
}
aCacheTable.fillTable();
diff --git a/sc/source/core/data/dpshttab.cxx b/sc/source/core/data/dpshttab.cxx
index a04bb5a..14a6f7b 100644
--- a/sc/source/core/data/dpshttab.cxx
+++ b/sc/source/core/data/dpshttab.cxx
@@ -191,7 +191,12 @@ void ScSheetDPData::CreateCacheTable()
return;
if (!aCacheTable.hasCache())
- aCacheTable.setCache(mrDesc.CreateCache());
+ {
+ fprintf(stdout, "ScSheetDPData::CreateCacheTable: NOT GOOD!!!\n");
+ // This better not happen!! The cache table should be created with a
+ // live data cache at all times.
+ return;
+ }
aCacheTable.fillTable(aQuery, bIgnoreEmptyRows, bRepeatIfEmpty);
}
diff --git a/sc/source/core/data/dptablecache.cxx b/sc/source/core/data/dptablecache.cxx
index d0ca15c..683a875 100644
--- a/sc/source/core/data/dptablecache.cxx
+++ b/sc/source/core/data/dptablecache.cxx
@@ -985,6 +985,16 @@ SCCOL ScDPCache::GetDimensionIndex(String sName) const
return -1;
}
+void ScDPCache::AddReference(ScDPObject* pObj) const
+{
+ maRefObjects.insert(pObj);
+}
+
+void ScDPCache::RemoveReference(ScDPObject* pObj) const
+{
+ maRefObjects.erase(pObj);
+}
+
SCROW ScDPCache::GetIdByItemData(long nDim, const String& sItemData ) const
{
if ( nDim < mnColumnCount && nDim >=0 )
commit 659d0ebda52cb7252590d9b11ebe0ef461df89a9
Author: Kohei Yoshida <kohei.yoshida at suse.com>
Date: Thu Jan 12 00:01:23 2012 -0500
fdo#43077: Copy pivot tables when a sheet is copied.
diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx
index dc20944..769e0ac 100644
--- a/sc/inc/dpobject.hxx
+++ b/sc/inc/dpobject.hxx
@@ -341,7 +341,7 @@ public:
void DeleteOnTab( SCTAB nTab );
void UpdateReference( UpdateRefMode eUpdateRefMode,
const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
-
+ void CopyToTab( SCTAB nOld, SCTAB nNew );
bool RefsEqual( const ScDPCollection& r ) const;
void WriteRefsTo( ScDPCollection& r ) const;
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index aa99070..40a10ba 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -823,7 +823,8 @@ bool ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyM
{
if (nNewPos >= static_cast<SCTAB>(maTabs.size()))
{
- maTabs.push_back( new ScTable(this, static_cast<SCTAB>(maTabs.size()), aName) );
+ nNewPos = static_cast<SCTAB>(maTabs.size());
+ maTabs.push_back(new ScTable(this, nNewPos, aName));
}
else
{
@@ -904,6 +905,9 @@ bool ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyM
if (pDrawLayer)
DrawCopyPage( static_cast<sal_uInt16>(nOldPos), static_cast<sal_uInt16>(nNewPos) );
+ if (pDPCollection)
+ pDPCollection->CopyToTab(nOldPos, nNewPos);
+
maTabs[nNewPos]->SetPageStyle( maTabs[nOldPos]->GetPageStyle() );
maTabs[nNewPos]->SetPendingRowHeights( maTabs[nOldPos]->IsPendingRowHeights() );
diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx
index 063c02a..a6f48db 100644
--- a/sc/source/core/data/dpobject.cxx
+++ b/sc/source/core/data/dpobject.cxx
@@ -2790,6 +2790,30 @@ void ScDPCollection::UpdateReference( UpdateRefMode eUpdateRefMode,
maSheetCaches.updateReference(eUpdateRefMode, r, nDx, nDy, nDz);
}
+void ScDPCollection::CopyToTab( SCTAB nOld, SCTAB nNew )
+{
+ TablesType aAdded;
+ TablesType::const_iterator it = maTables.begin(), itEnd = maTables.end();
+ for (; it != itEnd; ++it)
+ {
+ const ScDPObject& rObj = *it;
+ ScRange aOutRange = rObj.GetOutRange();
+ if (aOutRange.aStart.Tab() != nOld)
+ continue;
+
+ ScAddress& s = aOutRange.aStart;
+ ScAddress& e = aOutRange.aEnd;
+ s.SetTab(nNew);
+ e.SetTab(nNew);
+ std::auto_ptr<ScDPObject> pNew(new ScDPObject(rObj));
+ pNew->SetOutRange(aOutRange);
+ pDoc->ApplyFlagsTab(s.Col(), s.Row(), e.Col(), e.Row(), s.Tab(), SC_MF_DP_TABLE);
+ aAdded.push_back(pNew);
+ }
+
+ maTables.transfer(maTables.end(), aAdded.begin(), aAdded.end(), aAdded);
+}
+
bool ScDPCollection::RefsEqual( const ScDPCollection& r ) const
{
if (maTables.size() != r.maTables.size())
More information about the Libreoffice-commits
mailing list