summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@suse.com>2012-01-23 16:34:15 -0500
committerKohei Yoshida <kohei.yoshida@suse.com>2012-01-23 16:36:21 -0500
commit561b044d62f4701e51abb4a7c47ce3b07f788f8e (patch)
tree7a7985958e4be8e7f9844580d82a145177d665d6
parent6c0a26274629ae4f83105aa5f038d21b5c8ca7d0 (diff)
Fix refresh problem on pivot tables whose data cache have not been created.
-rw-r--r--sc/inc/dpobject.hxx7
-rw-r--r--sc/source/core/data/dpobject.cxx121
2 files changed, 124 insertions, 4 deletions
diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx
index a894833f07d0..f7126b12e421 100644
--- a/sc/inc/dpobject.hxx
+++ b/sc/inc/dpobject.hxx
@@ -328,6 +328,7 @@ public:
ScDocument* mpDoc;
public:
DBCaches(ScDocument* pDoc);
+ bool hasCache(sal_Int32 nSdbType, const rtl::OUString& rDBName, const rtl::OUString& rCommand) const;
const ScDPCache* getCache(sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand);
private:
@@ -382,6 +383,12 @@ private:
/** Only to be called from ScDPCache::RemoveReference(). */
void RemoveCache(const ScDPCache* pCache);
+ void GetAllTables(const ScRange& rSrcRange, std::set<ScDPObject*>& rRefs) const;
+ void GetAllTables(const rtl::OUString& rSrcName, std::set<ScDPObject*>& rRefs) const;
+ void GetAllTables(
+ sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand,
+ std::set<ScDPObject*>& rRefs) const;
+
private:
typedef ::boost::ptr_vector<ScDPObject> TablesType;
diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx
index 984d3de55bf1..d5ac78805b4b 100644
--- a/sc/source/core/data/dpobject.cxx
+++ b/sc/source/core/data/dpobject.cxx
@@ -2680,6 +2680,13 @@ bool ScDPCollection::DBType::less::operator() (const DBType& left, const DBType&
ScDPCollection::DBCaches::DBCaches(ScDocument* pDoc) : mpDoc(pDoc) {}
+bool ScDPCollection::DBCaches::hasCache(sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand) const
+{
+ DBType aType(nSdbType, rDBName, rCommand);
+ CachesType::const_iterator itr = maCaches.find(aType);
+ return itr != maCaches.end();
+}
+
const ScDPCache* ScDPCollection::DBCaches::getCache(sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand)
{
DBType aType(nSdbType, rDBName, rCommand);
@@ -2872,13 +2879,27 @@ sal_uLong ScDPCollection::ReloadCache(ScDPObject* pDPObj, std::set<ScDPObject*>&
{
// cache by named range
ScDPCollection::NameCaches& rCaches = GetNameCaches();
- rCaches.updateCache(pDesc->GetRangeName(), pDesc->GetSourceRange(), rRefs);
+ if (rCaches.hasCache(pDesc->GetRangeName()))
+ rCaches.updateCache(pDesc->GetRangeName(), pDesc->GetSourceRange(), rRefs);
+ else
+ {
+ // Not cached yet. Collect all tables that use this named
+ // range as data source.
+ GetAllTables(pDesc->GetRangeName(), rRefs);
+ }
}
else
{
// cache by cell range
ScDPCollection::SheetCaches& rCaches = GetSheetCaches();
- rCaches.updateCache(pDesc->GetSourceRange(), rRefs);
+ if (rCaches.hasCache(pDesc->GetSourceRange()))
+ rCaches.updateCache(pDesc->GetSourceRange(), rRefs);
+ else
+ {
+ // Not cached yet. Collect all tables that use this range as
+ // data source.
+ GetAllTables(pDesc->GetSourceRange(), rRefs);
+ }
}
}
else if (pDPObj->IsImportData())
@@ -2889,8 +2910,15 @@ sal_uLong ScDPCollection::ReloadCache(ScDPObject* pDPObj, std::set<ScDPObject*>&
return STR_ERR_DATAPILOTSOURCE;
ScDPCollection::DBCaches& rCaches = GetDBCaches();
- rCaches.updateCache(
- pDesc->GetCommandType(), pDesc->aDBName, pDesc->aObject, rRefs);
+ if (rCaches.hasCache(pDesc->GetCommandType(), pDesc->aDBName, pDesc->aObject))
+ rCaches.updateCache(
+ pDesc->GetCommandType(), pDesc->aDBName, pDesc->aObject, rRefs);
+ else
+ {
+ // Not cached yet. Collect all tables that use this range as
+ // data source.
+ GetAllTables(pDesc->GetCommandType(), pDesc->aDBName, pDesc->aObject, rRefs);
+ }
}
return 0;
}
@@ -3116,6 +3144,91 @@ void ScDPCollection::RemoveCache(const ScDPCache* pCache)
return;
}
+void ScDPCollection::GetAllTables(const ScRange& rSrcRange, std::set<ScDPObject*>& rRefs) const
+{
+ std::set<ScDPObject*> aRefs;
+ TablesType::const_iterator it = maTables.begin(), itEnd = maTables.end();
+ for (; it != itEnd; ++it)
+ {
+ const ScDPObject& rObj = *it;
+ if (!rObj.IsSheetData())
+ // Source is not a sheet range.
+ continue;
+
+ const ScSheetSourceDesc* pDesc = rObj.GetSheetDesc();
+ if (!pDesc)
+ continue;
+
+ if (pDesc->HasRangeName())
+ // This table has a range name as its source.
+ continue;
+
+ if (pDesc->GetSourceRange() != rSrcRange)
+ // Different source range.
+ continue;
+
+ aRefs.insert(const_cast<ScDPObject*>(&rObj));
+ }
+
+ rRefs.swap(aRefs);
+}
+
+void ScDPCollection::GetAllTables(const rtl::OUString& rSrcName, std::set<ScDPObject*>& rRefs) const
+{
+ std::set<ScDPObject*> aRefs;
+ TablesType::const_iterator it = maTables.begin(), itEnd = maTables.end();
+ for (; it != itEnd; ++it)
+ {
+ const ScDPObject& rObj = *it;
+ if (!rObj.IsSheetData())
+ // Source is not a sheet range.
+ continue;
+
+ const ScSheetSourceDesc* pDesc = rObj.GetSheetDesc();
+ if (!pDesc)
+ continue;
+
+ if (!pDesc->HasRangeName())
+ // This table probably has a sheet range as its source.
+ continue;
+
+ if (pDesc->GetRangeName() != rSrcName)
+ // Different source name.
+ continue;
+
+ aRefs.insert(const_cast<ScDPObject*>(&rObj));
+ }
+
+ rRefs.swap(aRefs);
+}
+
+void ScDPCollection::GetAllTables(
+ sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand,
+ std::set<ScDPObject*>& rRefs) const
+{
+ std::set<ScDPObject*> aRefs;
+ TablesType::const_iterator it = maTables.begin(), itEnd = maTables.end();
+ for (; it != itEnd; ++it)
+ {
+ const ScDPObject& rObj = *it;
+ if (!rObj.IsImportData())
+ // Source data is not a database.
+ continue;
+
+ const ScImportSourceDesc* pDesc = rObj.GetImportSourceDesc();
+ if (!pDesc)
+ continue;
+
+ if (!pDesc->aDBName.equals(rDBName) || !pDesc->aObject.equals(rCommand) || pDesc->GetCommandType() != nSdbType)
+ // Different database source.
+ continue;
+
+ aRefs.insert(const_cast<ScDPObject*>(&rObj));
+ }
+
+ rRefs.swap(aRefs);
+}
+
bool operator<(const ScDPCollection::DBType& left, const ScDPCollection::DBType& right)
{
if (left.mnSdbType != right.mnSdbType)