Kaydet (Commit) 057d269c authored tarafından Kohei Yoshida's avatar Kohei Yoshida

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
üst 93e4276a
...@@ -305,6 +305,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\ ...@@ -305,6 +305,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
sc/source/filter/xml/celltextparacontext \ sc/source/filter/xml/celltextparacontext \
sc/source/filter/xml/editattributemap \ sc/source/filter/xml/editattributemap \
sc/source/filter/xml/importcontext \ sc/source/filter/xml/importcontext \
sc/source/filter/xml/pivotsource \
sc/source/filter/xml/sheetdata \ sc/source/filter/xml/sheetdata \
sc/source/filter/xml/xmlannoi \ sc/source/filter/xml/xmlannoi \
sc/source/filter/xml/xmlbodyi \ sc/source/filter/xml/xmlbodyi \
......
/* -*- 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: */
/* -*- 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: */
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include "rangeutl.hxx" #include "rangeutl.hxx"
#include "dpoutputgeometry.hxx" #include "dpoutputgeometry.hxx"
#include "pivotsource.hxx"
#include <xmloff/xmltkmap.hxx> #include <xmloff/xmltkmap.hxx>
#include <xmloff/nmspmap.hxx> #include <xmloff/nmspmap.hxx>
#include <xmloff/xmltoken.hxx> #include <xmloff/xmltoken.hxx>
...@@ -477,6 +479,9 @@ void ScXMLDataPilotTableContext::EndElement() ...@@ -477,6 +479,9 @@ void ScXMLDataPilotTableContext::EndElement()
pDPObject->SetTag(sApplicationData); pDPObject->SetTag(sApplicationData);
pDPObject->SetOutRange(aTargetRangeAddress); pDPObject->SetOutRange(aTargetRangeAddress);
pDPObject->SetHeaderLayout(bHeaderGridLayout); pDPObject->SetHeaderLayout(bHeaderGridLayout);
sc::PivotTableSources& rPivotSources = GetScImport().GetPivotTableSources();
switch (nSourceType) switch (nSourceType)
{ {
case SQL : case SQL :
...@@ -486,7 +491,7 @@ void ScXMLDataPilotTableContext::EndElement() ...@@ -486,7 +491,7 @@ void ScXMLDataPilotTableContext::EndElement()
aImportDesc.aObject = sSourceObject; aImportDesc.aObject = sSourceObject;
aImportDesc.nType = sheet::DataImportMode_SQL; aImportDesc.nType = sheet::DataImportMode_SQL;
aImportDesc.bNative = bIsNative; aImportDesc.bNative = bIsNative;
pDPObject->SetImportDesc(aImportDesc); rPivotSources.appendDBSource(pDPObject, aImportDesc);
} }
break; break;
case TABLE : case TABLE :
...@@ -495,7 +500,7 @@ void ScXMLDataPilotTableContext::EndElement() ...@@ -495,7 +500,7 @@ void ScXMLDataPilotTableContext::EndElement()
aImportDesc.aDBName = sDatabaseName; aImportDesc.aDBName = sDatabaseName;
aImportDesc.aObject = sSourceObject; aImportDesc.aObject = sSourceObject;
aImportDesc.nType = sheet::DataImportMode_TABLE; aImportDesc.nType = sheet::DataImportMode_TABLE;
pDPObject->SetImportDesc(aImportDesc); rPivotSources.appendDBSource(pDPObject, aImportDesc);
} }
break; break;
case QUERY : case QUERY :
...@@ -504,14 +509,14 @@ void ScXMLDataPilotTableContext::EndElement() ...@@ -504,14 +509,14 @@ void ScXMLDataPilotTableContext::EndElement()
aImportDesc.aDBName = sDatabaseName; aImportDesc.aDBName = sDatabaseName;
aImportDesc.aObject = sSourceObject; aImportDesc.aObject = sSourceObject;
aImportDesc.nType = sheet::DataImportMode_QUERY; aImportDesc.nType = sheet::DataImportMode_QUERY;
pDPObject->SetImportDesc(aImportDesc); rPivotSources.appendDBSource(pDPObject, aImportDesc);
} }
break; break;
case SERVICE : case SERVICE :
{ {
ScDPServiceDesc aServiceDesk(sServiceName, sServiceSourceName, sServiceSourceObject, ScDPServiceDesc aServiceDesc(sServiceName, sServiceSourceName, sServiceSourceObject,
sServiceUsername, sServicePassword); sServiceUsername, sServicePassword);
pDPObject->SetServiceData(aServiceDesk); rPivotSources.appendServiceSource(pDPObject, aServiceDesc);
} }
break; break;
case CELLRANGE : case CELLRANGE :
...@@ -525,12 +530,14 @@ void ScXMLDataPilotTableContext::EndElement() ...@@ -525,12 +530,14 @@ void ScXMLDataPilotTableContext::EndElement()
else else
aSheetDesc.SetSourceRange(aSourceCellRangeAddress); aSheetDesc.SetSourceRange(aSourceCellRangeAddress);
aSheetDesc.SetQueryParam(aSourceQueryParam); aSheetDesc.SetQueryParam(aSourceQueryParam);
pDPObject->SetSheetDesc(aSheetDesc); rPivotSources.appendSheetSource(pDPObject, aSheetDesc);
} }
} }
break; break;
} }
rPivotSources.appendSelectedPages(pDPObject, maSelectedPages);
pDPSave->SetRowGrand(maRowGrandTotal.mbVisible); pDPSave->SetRowGrand(maRowGrandTotal.mbVisible);
pDPSave->SetColumnGrand(maColGrandTotal.mbVisible); pDPSave->SetColumnGrand(maColGrandTotal.mbVisible);
if (!maRowGrandTotal.maDisplayName.isEmpty()) if (!maRowGrandTotal.maDisplayName.isEmpty())
...@@ -553,36 +560,10 @@ void ScXMLDataPilotTableContext::EndElement() ...@@ -553,36 +560,10 @@ void ScXMLDataPilotTableContext::EndElement()
if ( pDPCollection->GetByName(pDPObject->GetName()) ) if ( pDPCollection->GetByName(pDPObject->GetName()) )
pDPObject->SetName( OUString() ); // ignore the invalid name, create a new name in AfterXMLLoading pDPObject->SetName( OUString() ); // ignore the invalid name, create a new name in AfterXMLLoading
ProcessSelectedPages();
pDPCollection->InsertNewTable(pDPObject); pDPCollection->InsertNewTable(pDPObject);
SetButtons(); 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( void ScXMLDataPilotTableContext::SetGrandTotal(
XMLTokenEnum eOrientation, bool bVisible, const OUString& rDisplayName) XMLTokenEnum eOrientation, bool bVisible, const OUString& rDisplayName)
{ {
......
...@@ -121,8 +121,6 @@ class ScXMLDataPilotTableContext : public SvXMLImportContext ...@@ -121,8 +121,6 @@ class ScXMLDataPilotTableContext : public SvXMLImportContext
const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
void ProcessSelectedPages();
public: public:
ScXMLDataPilotTableContext( ScXMLImport& rImport, sal_uInt16 nPrfx, ScXMLDataPilotTableContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
......
...@@ -67,6 +67,7 @@ ...@@ -67,6 +67,7 @@
#include "editutil.hxx" #include "editutil.hxx"
#include "editattributemap.hxx" #include "editattributemap.hxx"
#include "documentimport.hxx" #include "documentimport.hxx"
#include "pivotsource.hxx"
#include <comphelper/extract.hxx> #include <comphelper/extract.hxx>
...@@ -1961,6 +1962,14 @@ sc::ImportPostProcessData* ScXMLImport::GetPostProcessData() ...@@ -1961,6 +1962,14 @@ sc::ImportPostProcessData* ScXMLImport::GetPostProcessData()
return mpPostProcessData; return mpPostProcessData;
} }
sc::PivotTableSources& ScXMLImport::GetPivotTableSources()
{
if (!mpPivotSources)
mpPivotSources.reset(new sc::PivotTableSources);
return *mpPivotSources;
}
SvXMLImportContext *ScXMLImport::CreateContext( sal_uInt16 nPrefix, SvXMLImportContext *ScXMLImport::CreateContext( sal_uInt16 nPrefix,
const OUString& rLocalName, const OUString& rLocalName,
const uno::Reference<xml::sax::XAttributeList>& xAttrList ) const uno::Reference<xml::sax::XAttributeList>& xAttrList )
...@@ -3223,6 +3232,7 @@ void SAL_CALL ScXMLImport::endDocument() ...@@ -3223,6 +3232,7 @@ void SAL_CALL ScXMLImport::endDocument()
SetLabelRanges(); SetLabelRanges();
SetNamedRanges(); SetNamedRanges();
SetSheetNamedRanges(); SetSheetNamedRanges();
GetPivotTableSources().process();
} }
GetProgressBarHelper()->End(); // make room for subsequent SfxProgressBars GetProgressBarHelper()->End(); // make room for subsequent SfxProgressBars
if (pDoc) if (pDoc)
......
...@@ -58,6 +58,7 @@ class ScDocumentImport; ...@@ -58,6 +58,7 @@ class ScDocumentImport;
namespace sc { namespace sc {
struct ImportPostProcessData; struct ImportPostProcessData;
struct PivotTableSources;
} }
...@@ -827,6 +828,8 @@ class ScXMLImport: public SvXMLImport, boost::noncopyable ...@@ -827,6 +828,8 @@ class ScXMLImport: public SvXMLImport, boost::noncopyable
boost::scoped_ptr<ScDocumentImport> mpDocImport; boost::scoped_ptr<ScDocumentImport> mpDocImport;
boost::scoped_ptr<ScCompiler> mpComp; // For error-checking of cached string cell values. boost::scoped_ptr<ScCompiler> mpComp; // For error-checking of cached string cell values.
boost::scoped_ptr<ScEditEngineDefaulter> mpEditEngine; boost::scoped_ptr<ScEditEngineDefaulter> mpEditEngine;
boost::scoped_ptr<sc::PivotTableSources> mpPivotSources;
mutable boost::scoped_ptr<ScXMLEditAttributeMap> mpEditAttrMap; mutable boost::scoped_ptr<ScXMLEditAttributeMap> mpEditAttrMap;
ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper; ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
ScMyViewContextList aViewContextList; ScMyViewContextList aViewContextList;
...@@ -1105,6 +1108,8 @@ public: ...@@ -1105,6 +1108,8 @@ public:
void SetPostProcessData( sc::ImportPostProcessData* p ); void SetPostProcessData( sc::ImportPostProcessData* p );
sc::ImportPostProcessData* GetPostProcessData(); sc::ImportPostProcessData* GetPostProcessData();
sc::PivotTableSources& GetPivotTableSources();
void AddNamedExpression(ScMyNamedExpression* pMyNamedExpression) void AddNamedExpression(ScMyNamedExpression* pMyNamedExpression)
{ {
if (!pMyNamedExpressions) if (!pMyNamedExpressions)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment