summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@suse.com>2012-01-23 16:34:15 -0500
committerPetr Mladek <pmladek@suse.cz>2012-01-24 17:07:29 +0100
commita0dc477bfa4460a3091e533eed57fae93f481d5a (patch)
treef8758e64b6cfeb221f42d5bc53c1679b4637624f
parent17ccd3cfc9dd86e2911a0a31f6dcbba8d7e7950a (diff)
Fix refresh problem on pivot tables whose data cache have not been created.
Signed-off-by: Petr Mladek <pmladek@suse.cz>
-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 47c1999a005b..2d8991a32b02 100644
--- a/sc/inc/dpobject.hxx
+++ b/sc/inc/dpobject.hxx
@@ -330,6 +330,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);
size_t size() const;
@@ -386,6 +387,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 3113f1b43de6..ba7af2ef13f0 100644
--- a/sc/source/core/data/dpobject.cxx
+++ b/sc/source/core/data/dpobject.cxx
@@ -2706,6 +2706,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);
@@ -2911,13 +2918,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())
@@ -2928,8 +2949,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;
}
@@ -3155,6 +3183,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)