summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2014-03-09 18:40:13 -0400
committerEike Rathke <erack@redhat.com>2014-03-10 17:17:23 -0500
commite42ada4ec31142f907513fac6f9bca76dffa09de (patch)
treef40764bc6d28a713e3e6895f7ed823631c51aa5b
parent1b2cf579105d8a1e44b5e2a8aafb79c274fc8455 (diff)
fdo#75960: Process pivot tables after named ranges are all set.
Especially for those pivot tables that reference named ranges as their data sources, it's critical that we process them after named ranges are set. Else things would start to fail. Change-Id: I4bf8aa1a844aae3953f2dfbeba0e4d2542a7e53f (cherry picked from commit 057d269c5d1faf45c4c935b2f8120c45e646de65) (cherry picked from commit 98bd1911420f46380aa5373a92de6a748ced080d) Reviewed-on: https://gerrit.libreoffice.org/8507 Reviewed-by: Eike Rathke <erack@redhat.com> Tested-by: Eike Rathke <erack@redhat.com>
-rw-r--r--sc/Library_sc.mk1
-rw-r--r--sc/source/filter/xml/pivotsource.cxx121
-rw-r--r--sc/source/filter/xml/pivotsource.hxx90
-rw-r--r--sc/source/filter/xml/xmldpimp.cxx45
-rw-r--r--sc/source/filter/xml/xmldpimp.hxx2
-rw-r--r--sc/source/filter/xml/xmlimprt.cxx12
-rw-r--r--sc/source/filter/xml/xmlimprt.hxx5
7 files changed, 242 insertions, 34 deletions
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index 58d8048e86dd..296761e5cd0b 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -302,6 +302,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
sc/source/filter/xml/celltextparacontext \
sc/source/filter/xml/editattributemap \
sc/source/filter/xml/importcontext \
+ sc/source/filter/xml/pivotsource \
sc/source/filter/xml/sheetdata \
sc/source/filter/xml/xmlannoi \
sc/source/filter/xml/xmlbodyi \
diff --git a/sc/source/filter/xml/pivotsource.cxx b/sc/source/filter/xml/pivotsource.cxx
new file mode 100644
index 000000000000..43b5a4d0faeb
--- /dev/null
+++ b/sc/source/filter/xml/pivotsource.cxx
@@ -0,0 +1,121 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "pivotsource.hxx"
+
+#include <dpsave.hxx>
+
+namespace sc {
+
+PivotTableSources::SelectedPages::SelectedPages( ScDPObject* pObj, const SelectedPagesType& rSelected ) :
+ mpDP(pObj), maSelectedPages(rSelected) {}
+
+PivotTableSources::SheetSource::SheetSource( ScDPObject* pObj, const ScSheetSourceDesc& rDesc ) :
+ mpDP(pObj), maDesc(rDesc) {}
+
+PivotTableSources::DBSource::DBSource( ScDPObject* pObj, const ScImportSourceDesc& rDesc ) :
+ mpDP(pObj), maDesc(rDesc) {}
+
+PivotTableSources::ServiceSource::ServiceSource( ScDPObject* pObj, const ScDPServiceDesc& rDesc ) :
+ mpDP(pObj), maDesc(rDesc) {}
+
+PivotTableSources::PivotTableSources() {}
+
+void PivotTableSources::appendSheetSource( ScDPObject* pObj, const ScSheetSourceDesc& rDesc )
+{
+ maSheetSources.push_back(SheetSource(pObj, rDesc));
+}
+
+void PivotTableSources::appendDBSource( ScDPObject* pObj, const ScImportSourceDesc& rDesc )
+{
+ maDBSources.push_back(DBSource(pObj, rDesc));
+}
+
+void PivotTableSources::appendServiceSource( ScDPObject* pObj, const ScDPServiceDesc& rDesc )
+{
+ maServiceSources.push_back(ServiceSource(pObj, rDesc));
+}
+
+void PivotTableSources::appendSelectedPages( ScDPObject* pObj, const SelectedPagesType& rSelected )
+{
+ if (rSelected.empty())
+ return;
+
+ maSelectedPagesList.push_back(SelectedPages(pObj, rSelected));
+}
+
+namespace {
+
+struct SelectedPageProcessor : std::unary_function<PivotTableSources::SelectedPages, void>
+{
+ void operator() ( PivotTableSources::SelectedPages& rItem )
+ {
+ // Set selected pages after building all dimension members.
+ if (!rItem.mpDP)
+ return;
+
+ rItem.mpDP->BuildAllDimensionMembers();
+ ScDPSaveData* pSaveData = rItem.mpDP->GetSaveData();
+ if (!pSaveData)
+ return;
+
+ PivotTableSources::SelectedPagesType::const_iterator it = rItem.maSelectedPages.begin(), itEnd = rItem.maSelectedPages.end();
+ for (; it != itEnd; ++it)
+ {
+ const OUString& rDimName = it->first;
+ const OUString& rSelected = it->second;
+ ScDPSaveDimension* pDim = pSaveData->GetExistingDimensionByName(rDimName);
+ if (!pDim)
+ continue;
+
+ pDim->SetCurrentPage(&rSelected);
+ }
+ }
+};
+
+struct PivotSheetDescSetter : std::unary_function<sc::PivotTableSources::SheetSource, void>
+{
+ void operator() ( sc::PivotTableSources::SheetSource& rSrc )
+ {
+ ScDPObject* pObj = rSrc.mpDP;
+ pObj->SetSheetDesc(rSrc.maDesc);
+ }
+};
+
+struct PivotDBDescSetter : std::unary_function<sc::PivotTableSources::DBSource, void>
+{
+ void operator() ( sc::PivotTableSources::DBSource& rSrc )
+ {
+ ScDPObject* pObj = rSrc.mpDP;
+ pObj->SetImportDesc(rSrc.maDesc);
+ }
+};
+
+struct PivotServiceDataSetter : std::unary_function<sc::PivotTableSources::ServiceSource, void>
+{
+ void operator() ( sc::PivotTableSources::ServiceSource& rSrc )
+ {
+ ScDPObject* pObj = rSrc.mpDP;
+ pObj->SetServiceData(rSrc.maDesc);
+ }
+};
+
+}
+
+void PivotTableSources::process()
+{
+ std::for_each(maSheetSources.begin(), maSheetSources.end(), PivotSheetDescSetter());
+ std::for_each(maDBSources.begin(), maDBSources.end(), PivotDBDescSetter());
+ std::for_each(maServiceSources.begin(), maServiceSources.end(), PivotServiceDataSetter());
+ std::for_each(maSelectedPagesList.begin(), maSelectedPagesList.end(), SelectedPageProcessor());
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/pivotsource.hxx b/sc/source/filter/xml/pivotsource.hxx
new file mode 100644
index 000000000000..c50e3972335a
--- /dev/null
+++ b/sc/source/filter/xml/pivotsource.hxx
@@ -0,0 +1,90 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef SC_FILER_XML_PIVOTSOURCE_HXX
+#define SC_FILER_XML_PIVOTSOURCE_HXX
+
+#include <dpshttab.hxx>
+#include <dpsdbtab.hxx>
+#include <dpobject.hxx>
+
+#include <vector>
+#include <boost/unordered_map.hpp>
+
+namespace sc {
+
+/**
+ * Store pivot table data that need to be post-processeed at the end of the
+ * import.
+ */
+struct PivotTableSources
+{
+ typedef boost::unordered_map<OUString, OUString, OUStringHash> SelectedPagesType;
+ typedef boost::unordered_map<ScDPObject*, SelectedPagesType> SelectedPagesMapType;
+
+ struct SelectedPages
+ {
+ ScDPObject* mpDP;
+ SelectedPagesType maSelectedPages;
+
+ SelectedPages( ScDPObject* pObj, const SelectedPagesType& rSelected );
+ };
+
+ struct SheetSource
+ {
+ ScDPObject* mpDP;
+ ScSheetSourceDesc maDesc;
+
+ SheetSource( ScDPObject* pObj, const ScSheetSourceDesc& rDesc );
+ };
+
+ struct DBSource
+ {
+ ScDPObject* mpDP;
+ ScImportSourceDesc maDesc;
+
+ DBSource( ScDPObject* pObj, const ScImportSourceDesc& rDesc );
+ };
+
+ struct ServiceSource
+ {
+ ScDPObject* mpDP;
+ ScDPServiceDesc maDesc;
+
+ ServiceSource( ScDPObject* pObj, const ScDPServiceDesc& rDesc );
+ };
+
+ typedef std::vector<SelectedPages> SelectedPagesListType;
+
+ typedef std::vector<SheetSource> SheetSourcesType;
+ typedef std::vector<DBSource> DBSourcesType;
+ typedef std::vector<ServiceSource> ServiceSourcesType;
+
+ SelectedPagesListType maSelectedPagesList;
+
+ SheetSourcesType maSheetSources;
+ DBSourcesType maDBSources;
+ ServiceSourcesType maServiceSources;
+
+ PivotTableSources();
+
+ void appendSheetSource( ScDPObject* pObj, const ScSheetSourceDesc& rDesc );
+ void appendDBSource( ScDPObject* pObj, const ScImportSourceDesc& rDesc );
+ void appendServiceSource( ScDPObject* pObj, const ScDPServiceDesc& rDesc );
+
+ void appendSelectedPages( ScDPObject* pObj, const SelectedPagesType& rSelected );
+
+ void process();
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmldpimp.cxx b/sc/source/filter/xml/xmldpimp.cxx
index 88750ddb0bf0..6ec52ef37f32 100644
--- a/sc/source/filter/xml/xmldpimp.cxx
+++ b/sc/source/filter/xml/xmldpimp.cxx
@@ -32,6 +32,8 @@
#include "rangeutl.hxx"
#include "dpoutputgeometry.hxx"
+#include "pivotsource.hxx"
+
#include <xmloff/xmltkmap.hxx>
#include <xmloff/nmspmap.hxx>
#include <xmloff/xmltoken.hxx>
@@ -477,6 +479,9 @@ void ScXMLDataPilotTableContext::EndElement()
pDPObject->SetTag(sApplicationData);
pDPObject->SetOutRange(aTargetRangeAddress);
pDPObject->SetHeaderLayout(bHeaderGridLayout);
+
+ sc::PivotTableSources& rPivotSources = GetScImport().GetPivotTableSources();
+
switch (nSourceType)
{
case SQL :
@@ -486,7 +491,7 @@ void ScXMLDataPilotTableContext::EndElement()
aImportDesc.aObject = sSourceObject;
aImportDesc.nType = sheet::DataImportMode_SQL;
aImportDesc.bNative = bIsNative;
- pDPObject->SetImportDesc(aImportDesc);
+ rPivotSources.appendDBSource(pDPObject, aImportDesc);
}
break;
case TABLE :
@@ -495,7 +500,7 @@ void ScXMLDataPilotTableContext::EndElement()
aImportDesc.aDBName = sDatabaseName;
aImportDesc.aObject = sSourceObject;
aImportDesc.nType = sheet::DataImportMode_TABLE;
- pDPObject->SetImportDesc(aImportDesc);
+ rPivotSources.appendDBSource(pDPObject, aImportDesc);
}
break;
case QUERY :
@@ -504,14 +509,14 @@ void ScXMLDataPilotTableContext::EndElement()
aImportDesc.aDBName = sDatabaseName;
aImportDesc.aObject = sSourceObject;
aImportDesc.nType = sheet::DataImportMode_QUERY;
- pDPObject->SetImportDesc(aImportDesc);
+ rPivotSources.appendDBSource(pDPObject, aImportDesc);
}
break;
case SERVICE :
{
- ScDPServiceDesc aServiceDesk(sServiceName, sServiceSourceName, sServiceSourceObject,
+ ScDPServiceDesc aServiceDesc(sServiceName, sServiceSourceName, sServiceSourceObject,
sServiceUsername, sServicePassword);
- pDPObject->SetServiceData(aServiceDesk);
+ rPivotSources.appendServiceSource(pDPObject, aServiceDesc);
}
break;
case CELLRANGE :
@@ -525,12 +530,14 @@ void ScXMLDataPilotTableContext::EndElement()
else
aSheetDesc.SetSourceRange(aSourceCellRangeAddress);
aSheetDesc.SetQueryParam(aSourceQueryParam);
- pDPObject->SetSheetDesc(aSheetDesc);
+ rPivotSources.appendSheetSource(pDPObject, aSheetDesc);
}
}
break;
}
+ rPivotSources.appendSelectedPages(pDPObject, maSelectedPages);
+
pDPSave->SetRowGrand(maRowGrandTotal.mbVisible);
pDPSave->SetColumnGrand(maColGrandTotal.mbVisible);
if (!maRowGrandTotal.maDisplayName.isEmpty())
@@ -553,36 +560,10 @@ void ScXMLDataPilotTableContext::EndElement()
if ( pDPCollection->GetByName(pDPObject->GetName()) )
pDPObject->SetName( OUString() ); // ignore the invalid name, create a new name in AfterXMLLoading
- ProcessSelectedPages();
-
pDPCollection->InsertNewTable(pDPObject);
SetButtons();
}
-void ScXMLDataPilotTableContext::ProcessSelectedPages()
-{
- // Set selected pages after building all dimension members.
- if (!pDPObject)
- return;
-
- pDPObject->BuildAllDimensionMembers();
- ScDPSaveData* pSaveData = pDPObject->GetSaveData();
- if (!pSaveData)
- return;
-
- SelectedPagesType::const_iterator it = maSelectedPages.begin(), itEnd = maSelectedPages.end();
- for (; it != itEnd; ++it)
- {
- const OUString& rDimName = it->first;
- const OUString& rSelected = it->second;
- ScDPSaveDimension* pDim = pSaveData->GetExistingDimensionByName(rDimName);
- if (!pDim)
- continue;
-
- pDim->SetCurrentPage(&rSelected);
- }
-}
-
void ScXMLDataPilotTableContext::SetGrandTotal(
XMLTokenEnum eOrientation, bool bVisible, const OUString& rDisplayName)
{
diff --git a/sc/source/filter/xml/xmldpimp.hxx b/sc/source/filter/xml/xmldpimp.hxx
index 32f878dee541..d5a84fa29ad0 100644
--- a/sc/source/filter/xml/xmldpimp.hxx
+++ b/sc/source/filter/xml/xmldpimp.hxx
@@ -121,8 +121,6 @@ class ScXMLDataPilotTableContext : public SvXMLImportContext
const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
- void ProcessSelectedPages();
-
public:
ScXMLDataPilotTableContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx
index 1f02083e63b3..5c5a761aea97 100644
--- a/sc/source/filter/xml/xmlimprt.cxx
+++ b/sc/source/filter/xml/xmlimprt.cxx
@@ -67,6 +67,7 @@
#include "editutil.hxx"
#include "editattributemap.hxx"
#include "documentimport.hxx"
+#include "pivotsource.hxx"
#include <comphelper/extract.hxx>
@@ -1961,6 +1962,14 @@ sc::ImportPostProcessData* ScXMLImport::GetPostProcessData()
return mpPostProcessData;
}
+sc::PivotTableSources& ScXMLImport::GetPivotTableSources()
+{
+ if (!mpPivotSources)
+ mpPivotSources.reset(new sc::PivotTableSources);
+
+ return *mpPivotSources;
+}
+
SvXMLImportContext *ScXMLImport::CreateContext( sal_uInt16 nPrefix,
const OUString& rLocalName,
const uno::Reference<xml::sax::XAttributeList>& xAttrList )
@@ -3243,6 +3252,9 @@ throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeE
SetLabelRanges();
SetNamedRanges();
SetSheetNamedRanges();
+ if (mpPivotSources)
+ // Process pivot table sources after the named ranges have been set.
+ mpPivotSources->process();
}
GetProgressBarHelper()->End(); // make room for subsequent SfxProgressBars
if (pDoc)
diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx
index bf2d9ae5ea36..584b3de7ca96 100644
--- a/sc/source/filter/xml/xmlimprt.hxx
+++ b/sc/source/filter/xml/xmlimprt.hxx
@@ -58,6 +58,7 @@ class ScDocumentImport;
namespace sc {
struct ImportPostProcessData;
+struct PivotTableSources;
}
@@ -827,6 +828,8 @@ class ScXMLImport: public SvXMLImport, boost::noncopyable
boost::scoped_ptr<ScDocumentImport> mpDocImport;
boost::scoped_ptr<ScCompiler> mpComp; // For error-checking of cached string cell values.
boost::scoped_ptr<ScEditEngineDefaulter> mpEditEngine;
+ boost::scoped_ptr<sc::PivotTableSources> mpPivotSources;
+
mutable boost::scoped_ptr<ScXMLEditAttributeMap> mpEditAttrMap;
ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
ScMyViewContextList aViewContextList;
@@ -1105,6 +1108,8 @@ public:
void SetPostProcessData( sc::ImportPostProcessData* p );
sc::ImportPostProcessData* GetPostProcessData();
+ sc::PivotTableSources& GetPivotTableSources();
+
void AddNamedExpression(ScMyNamedExpression* pMyNamedExpression)
{
if (!pMyNamedExpressions)