blob: e13eeced7f104da45d48b5057ef534c13b083405 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"
// INCLUDE ---------------------------------------------------------------
#include "XMLExportDataPilot.hxx"
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmlnmspe.hxx>
#include <xmloff/xmluconv.hxx>
#include <xmloff/nmspmap.hxx>
#include <rtl/math.hxx>
#include "xmlexprt.hxx"
#include "XMLConverter.hxx"
#include "document.hxx"
#include "dpobject.hxx"
#include "dociter.hxx"
#include "attrib.hxx"
#include "patattr.hxx"
#include "scitems.hxx"
#include "dpsave.hxx"
#include "dpshttab.hxx"
#include "dpsdbtab.hxx"
#include "dpdimsave.hxx"
#include "dpgroup.hxx"
#include "rangeutl.hxx"
#include <com/sun/star/sheet/DataImportMode.hpp>
#include <com/sun/star/sheet/DataPilotFieldReference.hpp>
#include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
#include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
#include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
#include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
#include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
#include <com/sun/star/sheet/DataPilotFieldShowItemsMode.hpp>
#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
#include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp>
#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
using namespace com::sun::star;
using namespace xmloff::token;
using ::rtl::OUString;
ScXMLExportDataPilot::ScXMLExportDataPilot(ScXMLExport& rTempExport)
: rExport(rTempExport),
pDoc( NULL )
{
}
ScXMLExportDataPilot::~ScXMLExportDataPilot()
{
}
rtl::OUString ScXMLExportDataPilot::getDPOperatorXML(const ScQueryOp aFilterOperator, const sal_Bool bUseRegularExpressions,
const sal_Bool bIsString, const double dVal, const String& sVal) const
{
switch (aFilterOperator)
{
case SC_EQUAL :
{
rtl::OUString sReturn;
if (bUseRegularExpressions)
sReturn = GetXMLToken(XML_MATCH);
else
sReturn = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("="));
if (!bIsString && sVal == EMPTY_STRING)
{
if (dVal == SC_EMPTYFIELDS)
sReturn = GetXMLToken(XML_EMPTY);
else if (dVal == SC_NONEMPTYFIELDS)
sReturn = GetXMLToken(XML_NOEMPTY);
}
return sReturn;
}
case SC_NOT_EQUAL :
{
if (bUseRegularExpressions)
return GetXMLToken(XML_NOMATCH);
else
return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("!="));
}
case SC_BOTPERC :
return GetXMLToken(XML_BOTTOM_PERCENT);
case SC_BOTVAL :
return GetXMLToken(XML_BOTTOM_VALUES);
case SC_GREATER :
return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">"));
case SC_GREATER_EQUAL :
return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">="));
case SC_LESS :
return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<"));
case SC_LESS_EQUAL :
return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<="));
case SC_TOPPERC :
return GetXMLToken(XML_TOP_PERCENT);
case SC_TOPVAL :
return GetXMLToken(XML_TOP_VALUES);
default:
DBG_ERROR("This FilterOperator is not supported.");
}
return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("="));
}
void ScXMLExportDataPilot::WriteDPCondition(const ScQueryEntry& aQueryEntry, sal_Bool bIsCaseSensitive, sal_Bool bUseRegularExpressions)
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, rtl::OUString::valueOf(sal_Int32(aQueryEntry.nField)));
if (bIsCaseSensitive)
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
if (aQueryEntry.bQueryByString)
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, *aQueryEntry.pStr);
}
else
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_NUMBER);
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, rtl::OUString(*aQueryEntry.pStr));
}
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_OPERATOR, getDPOperatorXML(aQueryEntry.eOp, bUseRegularExpressions,
aQueryEntry.bQueryByString, aQueryEntry.nVal, *aQueryEntry.pStr));
SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_FILTER_CONDITION, sal_True, sal_True);
}
void ScXMLExportDataPilot::WriteDPFilter(const ScQueryParam& aQueryParam)
{
SCSIZE nQueryEntryCount = aQueryParam.GetEntryCount();
if (nQueryEntryCount > 0)
{
sal_Bool bAnd(sal_False);
sal_Bool bOr(sal_False);
sal_Bool bHasEntries(sal_True);
SCSIZE nEntries(0);
SCSIZE j;
for ( j = 0; (j < nQueryEntryCount) && bHasEntries; ++j)
{
ScQueryEntry aEntry = aQueryParam.GetEntry(j);
if (aEntry.bDoQuery)
{
if (nEntries > 0)
{
if (aEntry.eConnect == SC_AND)
bAnd = sal_True;
else
bOr = sal_True;
}
++nEntries;
}
else
bHasEntries = sal_False;
}
nQueryEntryCount = nEntries;
if (nQueryEntryCount)
{
// There is never a target range in a data pilot.
/* if (!aQueryParam.bInplace)
{
ScAddress aTargetAddress(aQueryParam.nDestCol, aQueryParam.nDestRow, aQueryParam.nDestTab);
rtl::OUString sAddress;
ScXMLConverter::GetStringFromAddress( sAddress, aTargetAddress, pDoc );
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, sAddress);
}*/
if(!((aQueryParam.nCol1 == aQueryParam.nCol2) && (aQueryParam.nRow1 == aQueryParam.nRow2) &&
(static_cast<SCCOLROW>(aQueryParam.nCol1) == static_cast<SCCOLROW>(aQueryParam.nRow1)) &&
(aQueryParam.nCol1 == 0) && (aQueryParam.nTab == SCTAB_MAX)))
{
ScRange aConditionRange(aQueryParam.nCol1, aQueryParam.nRow1, aQueryParam.nTab,
aQueryParam.nCol2, aQueryParam.nRow2, aQueryParam.nTab);
rtl::OUString sConditionRange;
ScRangeStringConverter::GetStringFromRange( sConditionRange, aConditionRange, pDoc, ::formula::FormulaGrammar::CONV_OOO );
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONDITION_SOURCE_RANGE_ADDRESS, sConditionRange);
}
if (!aQueryParam.bDuplicate)
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_DUPLICATES, XML_FALSE);
SvXMLElementExport aElemDPF(rExport, XML_NAMESPACE_TABLE, XML_FILTER, sal_True, sal_True);
rExport.CheckAttrList();
if (nQueryEntryCount == 1)
{
WriteDPCondition(aQueryParam.GetEntry(0), aQueryParam.bCaseSens, aQueryParam.bRegExp);
}
else if (bOr && !bAnd)
{
SvXMLElementExport aElemOr(rExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, sal_True, sal_True);
for (j = 0; j < nQueryEntryCount; ++j)
{
WriteDPCondition(aQueryParam.GetEntry(j), aQueryParam.bCaseSens, aQueryParam.bRegExp);
}
}
else if (bAnd && !bOr)
{
SvXMLElementExport aElemAnd(rExport, XML_NAMESPACE_TABLE, XML_FILTER_AND, sal_True, sal_True);
for (j = 0; j < nQueryEntryCount; ++j)
{
WriteDPCondition(aQueryParam.GetEntry(j), aQueryParam.bCaseSens, aQueryParam.bRegExp);
}
}
else
{
SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, sal_True, sal_True);
ScQueryEntry aPrevFilterField(aQueryParam.GetEntry(0));
ScQueryConnect aConnection = aQueryParam.GetEntry(1).eConnect;
sal_Bool bOpenAndElement;
rtl::OUString aName(rExport.GetNamespaceMap().GetQNameByKey(XML_NAMESPACE_TABLE, GetXMLToken(XML_FILTER_AND)));
if (aConnection == SC_AND)
{
rExport.StartElement( aName, sal_True );
bOpenAndElement = sal_True;
}
else
bOpenAndElement = sal_False;
for (j = 1; j < nQueryEntryCount; ++j)
{
if (aConnection != aQueryParam.GetEntry(j).eConnect)
{
aConnection = aQueryParam.GetEntry(j).eConnect;
if (aQueryParam.GetEntry(j).eConnect == SC_AND)
{
rExport.StartElement( aName, sal_True );
bOpenAndElement = sal_True;
WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.bRegExp);
aPrevFilterField = aQueryParam.GetEntry(j);
if (j == nQueryEntryCount - 1)
{
WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.bRegExp);
rExport.EndElement(aName, sal_True);
bOpenAndElement = sal_False;
}
}
else
{
WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.bRegExp);
aPrevFilterField = aQueryParam.GetEntry(j);
if (bOpenAndElement)
{
rExport.EndElement(aName, sal_True);
bOpenAndElement = sal_False;
}
if (j == nQueryEntryCount - 1)
{
WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.bRegExp);
}
}
}
else
{
WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.bRegExp);
aPrevFilterField = aQueryParam.GetEntry(j);
if (j == nQueryEntryCount - 1)
WriteDPCondition(aPrevFilterField, aQueryParam.bCaseSens, aQueryParam.bRegExp);
}
}
}
}
}
}
void ScXMLExportDataPilot::WriteFieldReference(ScDPSaveDimension* pDim)
{
const sheet::DataPilotFieldReference* pRef = pDim->GetReferenceValue();
if (pRef)
{
rtl::OUString sValueStr;
switch (pRef->ReferenceType)
{
case sheet::DataPilotFieldReferenceType::NONE :
sValueStr = GetXMLToken(XML_NONE);
break;
case sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE :
sValueStr = GetXMLToken(XML_MEMBER_DIFFERENCE);
break;
case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE :
sValueStr = GetXMLToken(XML_MEMBER_PERCENTAGE);
break;
case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE :
sValueStr = GetXMLToken(XML_MEMBER_PERCENTAGE_DIFFERENCE);
break;
case sheet::DataPilotFieldReferenceType::RUNNING_TOTAL :
sValueStr = GetXMLToken(XML_RUNNING_TOTAL);
break;
case sheet::DataPilotFieldReferenceType::ROW_PERCENTAGE :
sValueStr = GetXMLToken(XML_ROW_PERCENTAGE);
break;
case sheet::DataPilotFieldReferenceType::COLUMN_PERCENTAGE :
sValueStr = GetXMLToken(XML_COLUMN_PERCENTAGE);
break;
case sheet::DataPilotFieldReferenceType::TOTAL_PERCENTAGE :
sValueStr = GetXMLToken(XML_TOTAL_PERCENTAGE);
break;
case sheet::DataPilotFieldReferenceType::INDEX :
sValueStr = GetXMLToken(XML_INDEX);
break;
}
if (sValueStr.getLength())
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, sValueStr);
if (pRef->ReferenceField.getLength())
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NAME, pRef->ReferenceField);
if (pRef->ReferenceItemType == sheet::DataPilotFieldReferenceItemType::NAMED)
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MEMBER_TYPE, XML_NAMED);
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MEMBER_NAME, pRef->ReferenceItemName);
}
else
{
sValueStr = rtl::OUString();
switch(pRef->ReferenceItemType)
{
case sheet::DataPilotFieldReferenceItemType::PREVIOUS :
sValueStr = GetXMLToken(XML_PREVIOUS);
break;
case sheet::DataPilotFieldReferenceItemType::NEXT :
sValueStr = GetXMLToken(XML_NEXT);
break;
}
if (sValueStr.getLength())
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MEMBER_TYPE, sValueStr);
}
SvXMLElementExport aElemDPFR(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_FIELD_REFERENCE, sal_True, sal_True);
}
rExport.CheckAttrList();
}
void ScXMLExportDataPilot::WriteSortInfo(ScDPSaveDimension* pDim)
{
const sheet::DataPilotFieldSortInfo* pSortInfo = pDim->GetSortInfo();
if (pSortInfo)
{
if (pSortInfo->IsAscending)
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_ASCENDING);
else
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_DESCENDING);
rtl::OUString sValueStr;
switch (pSortInfo->Mode)
{
case sheet::DataPilotFieldSortMode::NONE:
sValueStr = GetXMLToken(XML_NONE);
break;
case sheet::DataPilotFieldSortMode::MANUAL:
sValueStr = GetXMLToken(XML_MANUAL);
break;
case sheet::DataPilotFieldSortMode::NAME:
sValueStr = GetXMLToken(XML_NAME);
break;
case sheet::DataPilotFieldSortMode::DATA:
sValueStr = GetXMLToken(XML_DATA);
if (pSortInfo->Field.getLength())
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_FIELD, pSortInfo->Field);
break;
}
if (sValueStr.getLength())
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SORT_MODE, sValueStr);
SvXMLElementExport aElemDPLSI(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_SORT_INFO, sal_True, sal_True);
}
}
void ScXMLExportDataPilot::WriteAutoShowInfo(ScDPSaveDimension* pDim)
{
const sheet::DataPilotFieldAutoShowInfo* pAutoInfo = pDim->GetAutoShowInfo();
if (pAutoInfo)
{
if (pAutoInfo->IsEnabled)
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ENABLED, XML_TRUE);
else
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ENABLED, XML_FALSE);
rtl::OUString sValueStr;
switch (pAutoInfo->ShowItemsMode)
{
case sheet::DataPilotFieldShowItemsMode::FROM_TOP:
sValueStr = GetXMLToken(XML_FROM_TOP);
break;
case sheet::DataPilotFieldShowItemsMode::FROM_BOTTOM:
sValueStr = GetXMLToken(XML_FROM_BOTTOM);
break;
}
if (sValueStr.getLength())
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_MEMBER_MODE, sValueStr);
rtl::OUStringBuffer sBuffer;
SvXMLUnitConverter::convertNumber(sBuffer, pAutoInfo->ItemCount);
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MEMBER_COUNT, sBuffer.makeStringAndClear());
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_FIELD, pAutoInfo->DataField);
SvXMLElementExport aElemDPLAI(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_DISPLAY_INFO, sal_True, sal_True);
}
}
void ScXMLExportDataPilot::WriteLayoutInfo(ScDPSaveDimension* pDim)
{
const sheet::DataPilotFieldLayoutInfo* pLayoutInfo = pDim->GetLayoutInfo();
if (pLayoutInfo)
{
if (pLayoutInfo->AddEmptyLines)
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ADD_EMPTY_LINES, XML_TRUE);
else
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ADD_EMPTY_LINES, XML_FALSE);
rtl::OUString sValueStr;
switch (pLayoutInfo->LayoutMode)
{
case sheet::DataPilotFieldLayoutMode::TABULAR_LAYOUT:
sValueStr = GetXMLToken(XML_TABULAR_LAYOUT);
break;
case sheet::DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP:
sValueStr = GetXMLToken(XML_OUTLINE_SUBTOTALS_TOP);
break;
case sheet::DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM:
sValueStr = GetXMLToken(XML_OUTLINE_SUBTOTALS_BOTTOM);
break;
}
if (sValueStr.getLength())
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_LAYOUT_MODE, sValueStr);
SvXMLElementExport aElemDPLLI(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_LAYOUT_INFO, sal_True, sal_True);
}
}
void ScXMLExportDataPilot::WriteSubTotals(ScDPSaveDimension* pDim)
{
using sheet::GeneralFunction;
sal_Int32 nSubTotalCount = pDim->GetSubTotalsCount();
const OUString* pLayoutName = NULL;
if (rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST)
// Export display names only for 1.2 extended or later.
pLayoutName = pDim->GetSubtotalName();
if (nSubTotalCount > 0)
{
SvXMLElementExport aElemSTs(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_SUBTOTALS, sal_True, sal_True);
rExport.CheckAttrList();
for (sal_Int32 nSubTotal = 0; nSubTotal < nSubTotalCount; nSubTotal++)
{
rtl::OUString sFunction;
GeneralFunction nFunc = static_cast<GeneralFunction>(pDim->GetSubTotalFunc(nSubTotal));
ScXMLConverter::GetStringFromFunction( sFunction, nFunc);
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FUNCTION, sFunction);
if (pLayoutName && nFunc == sheet::GeneralFunction_AUTO)
rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pLayoutName);
SvXMLElementExport aElemST(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_SUBTOTAL, sal_True, sal_True);
}
}
}
void ScXMLExportDataPilot::WriteMembers(ScDPSaveDimension* pDim)
{
const ScDPSaveDimension::MemberList &rMembers = pDim->GetMembers();
if (rMembers.begin() != rMembers.end())
{
SvXMLElementExport aElemDPMs(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_MEMBERS, sal_True, sal_True);
rExport.CheckAttrList();
for (ScDPSaveDimension::MemberList::const_iterator i=rMembers.begin(); i != rMembers.end() ; i++)
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, rtl::OUString((*i)->GetName()));
if (rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST)
{
// Export display names only for ODF 1.2 extended or later.
const OUString* pLayoutName = (*i)->GetLayoutName();
if (pLayoutName)
rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pLayoutName);
}
rtl::OUStringBuffer sBuffer;
SvXMLUnitConverter::convertBool(sBuffer, (*i)->GetIsVisible());
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, sBuffer.makeStringAndClear());
SvXMLUnitConverter::convertBool(sBuffer, (*i)->GetShowDetails());
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SHOW_DETAILS, sBuffer.makeStringAndClear());
SvXMLElementExport aElemDPM(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_MEMBER, sal_True, sal_True);
rExport.CheckAttrList();
}
}
}
void ScXMLExportDataPilot::WriteLevels(ScDPSaveDimension* pDim)
{
// #i114202# GetShowEmpty is only valid if HasShowEmpty is true.
if (pDim->HasShowEmpty())
{
rtl::OUStringBuffer sBuffer;
SvXMLUnitConverter::convertBool(sBuffer, pDim->GetShowEmpty());
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SHOW_EMPTY, sBuffer.makeStringAndClear());
}
SvXMLElementExport aElemDPL(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_LEVEL, sal_True, sal_True);
WriteSubTotals(pDim);
WriteMembers(pDim);
WriteAutoShowInfo(pDim);
WriteSortInfo(pDim);
WriteLayoutInfo(pDim);
rExport.CheckAttrList();
}
void ScXMLExportDataPilot::WriteDatePart(sal_Int32 nPart)
{
switch(nPart)
{
case com::sun::star::sheet::DataPilotFieldGroupBy::SECONDS :
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_SECONDS);
}
break;
case com::sun::star::sheet::DataPilotFieldGroupBy::MINUTES :
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_MINUTES);
}
break;
case com::sun::star::sheet::DataPilotFieldGroupBy::HOURS :
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_HOURS);
}
break;
case com::sun::star::sheet::DataPilotFieldGroupBy::DAYS :
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_DAYS);
}
break;
case com::sun::star::sheet::DataPilotFieldGroupBy::MONTHS :
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_MONTHS);
}
break;
case com::sun::star::sheet::DataPilotFieldGroupBy::QUARTERS :
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_QUARTERS);
}
break;
case com::sun::star::sheet::DataPilotFieldGroupBy::YEARS :
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUPED_BY, XML_YEARS);
}
break;
}
}
void ScXMLExportDataPilot::WriteNumGroupInfo(const ScDPNumGroupInfo& rGroupInfo)
{
DBG_ASSERT(rGroupInfo.Enable, "group dimension should be enabled");
if (rGroupInfo.DateValues)
{
if (rGroupInfo.AutoStart)
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_START, XML_AUTO);
else
{
rtl::OUStringBuffer sDate;
rExport.GetMM100UnitConverter().convertDateTime(sDate, rGroupInfo.Start);
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_START, sDate.makeStringAndClear());
}
if (rGroupInfo.AutoEnd)
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_END, XML_AUTO);
else
{
rtl::OUStringBuffer sDate;
rExport.GetMM100UnitConverter().convertDateTime(sDate, rGroupInfo.End);
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_END, sDate.makeStringAndClear());
}
}
else
{
if (rGroupInfo.AutoStart)
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START, XML_AUTO);
else
{
rtl::OUString sValue( ::rtl::math::doubleToUString( rGroupInfo.Start,
rtl_math_StringFormat_Automatic,
rtl_math_DecimalPlaces_Max, '.', sal_True));
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START, sValue);
}
if (rGroupInfo.AutoEnd)
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END, XML_AUTO);
else
{
rtl::OUStringBuffer sDate;
rtl::OUString sValue( ::rtl::math::doubleToUString( rGroupInfo.End,
rtl_math_StringFormat_Automatic,
rtl_math_DecimalPlaces_Max, '.', sal_True));
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END, sValue);
}
}
rtl::OUString sValue( ::rtl::math::doubleToUString( rGroupInfo.Step,
rtl_math_StringFormat_Automatic,
rtl_math_DecimalPlaces_Max, '.', sal_True));
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_STEP, sValue);
}
void ScXMLExportDataPilot::WriteGroupDimAttributes(const ScDPSaveGroupDimension* pGroupDim)
{
if (pGroupDim)
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_GROUP_FIELD, XML_TRUE);
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SOURCE_FIELD_NAME, pGroupDim->GetSourceDimName());
if (pGroupDim->GetDatePart())
{
WriteDatePart(pGroupDim->GetDatePart());
WriteNumGroupInfo(pGroupDim->GetDateInfo());
}
}
}
void ScXMLExportDataPilot::WriteNumGroupDim(const ScDPSaveNumGroupDimension* pNumGroupDim)
{
if (pNumGroupDim)
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_GROUP_FIELD, XML_TRUE);
if (pNumGroupDim->GetDatePart())
{
WriteDatePart(pNumGroupDim->GetDatePart());
WriteNumGroupInfo(pNumGroupDim->GetDateInfo());
}
else
{
WriteNumGroupInfo(pNumGroupDim->GetInfo());
}
}
}
void ScXMLExportDataPilot::WriteGroupDimElements(ScDPSaveDimension* pDim, const ScDPDimensionSaveData* pDimData)
{
const ScDPSaveGroupDimension* pGroupDim = NULL;
const ScDPSaveNumGroupDimension* pNumGroupDim = NULL;
if (pDimData)
{
pGroupDim = pDimData->GetNamedGroupDim(pDim->GetName());
WriteGroupDimAttributes(pGroupDim);
pNumGroupDim = pDimData->GetNumGroupDim(pDim->GetName());
WriteNumGroupDim(pNumGroupDim);
DBG_ASSERT((!pGroupDim || !pNumGroupDim), "there should be no NumGroup and Group at the same field");
}
if (pGroupDim || pNumGroupDim)
{
SvXMLElementExport aElemDPGs(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_GROUPS, sal_True, sal_True);
if (pGroupDim)
{
if (!pGroupDim->GetDatePart())
{
sal_Int32 nCount = pGroupDim->GetGroupCount();
for (sal_Int32 i = 0; i < nCount; ++i)
{
const ScDPSaveGroupItem* pGroup = pGroupDim->GetGroupByIndex( i );
if (pGroup)
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, pGroup->GetGroupName());
SvXMLElementExport aElemDPG(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_GROUP, sal_True, sal_True);
sal_Int32 nElemCount = pGroup->GetElementCount();
for(sal_Int32 j = 0; j < nElemCount; ++j)
{
const String* pElem = pGroup->GetElementByIndex( j );
if (pElem)
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, *pElem);
SvXMLElementExport aElemDPM(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_MEMBER, sal_True, sal_True);
}
}
}
}
}
}
}
}
void ScXMLExportDataPilot::WriteDimension(ScDPSaveDimension* pDim, const ScDPDimensionSaveData* pDimData)
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SOURCE_FIELD_NAME, rtl::OUString(pDim->GetName()));
if (rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST)
{
// Export display names only for ODF 1.2 extended or later.
const OUString* pLayoutName = pDim->GetLayoutName();
if (pLayoutName)
rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pLayoutName);
}
if (pDim->IsDataLayout())
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_DATA_LAYOUT_FIELD, XML_TRUE);
rtl::OUString sValueStr;
ScXMLConverter::GetStringFromOrientation( sValueStr,
(sheet::DataPilotFieldOrientation) pDim->GetOrientation() );
if( sValueStr.getLength() )
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORIENTATION, sValueStr );
if (pDim->GetOrientation() == sheet::DataPilotFieldOrientation_PAGE)
if (pDim->HasCurrentPage())
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SELECTED_PAGE, pDim->GetCurrentPage());
if (pDim->GetUsedHierarchy() != 1)
{
rtl::OUStringBuffer sBuffer;
SvXMLUnitConverter::convertNumber(sBuffer, pDim->GetUsedHierarchy());
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_USED_HIERARCHY, sBuffer.makeStringAndClear());
}
ScXMLConverter::GetStringFromFunction( sValueStr,
(sheet::GeneralFunction) pDim->GetFunction() );
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FUNCTION, sValueStr);
SvXMLElementExport aElemDPF(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_FIELD, sal_True, sal_True);
WriteFieldReference(pDim);
WriteLevels(pDim);
if( pDim->GetOrientation() != sheet::DataPilotFieldOrientation_DATA )
WriteGroupDimElements(pDim, pDimData);
}
void ScXMLExportDataPilot::WriteDimensions(ScDPSaveData* pDPSave)
{
List aDimensions = pDPSave->GetDimensions();
sal_Int32 nDimCount = aDimensions.Count();
for (sal_Int32 nDim = 0; nDim < nDimCount; nDim++)
{
WriteDimension((ScDPSaveDimension*)aDimensions.GetObject(nDim), pDPSave->GetExistingDimensionData());
}
}
void ScXMLExportDataPilot::WriteGrandTotal(::xmloff::token::XMLTokenEnum eOrient, bool bVisible, const OUString* pGrandTotal)
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, bVisible ? XML_TRUE : XML_FALSE);
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORIENTATION, eOrient);
if (pGrandTotal)
rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pGrandTotal);
SvXMLElementExport aElemGrandTotal(rExport, XML_NAMESPACE_TABLE_EXT, XML_DATA_PILOT_GRAND_TOTAL, sal_True, sal_True);
}
void ScXMLExportDataPilot::WriteDataPilots(const uno::Reference <sheet::XSpreadsheetDocument>& /* xSpreadDoc */)
{
pDoc = rExport.GetDocument();
if (pDoc)
{
ScDPCollection* pDPs = pDoc->GetDPCollection();
if (pDPs)
{
sal_Int16 nDPCount = pDPs->GetCount();
if (nDPCount > 0)
{
SvXMLElementExport aElemDPs(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_TABLES, sal_True, sal_True);
rExport.CheckAttrList();
for (sal_Int16 i = 0; i < nDPCount; ++i)
{
ScDPSaveData* pDPSave = (*pDPs)[i]->GetSaveData();
if (pDPSave)
{
ScRange aOutRange((*pDPs)[i]->GetOutRange());
rtl::OUString sTargetRangeAddress;
ScRangeStringConverter::GetStringFromRange( sTargetRangeAddress, aOutRange, pDoc, ::formula::FormulaGrammar::CONV_OOO );
ScDocAttrIterator aAttrItr(pDoc, aOutRange.aStart.Tab(),
aOutRange.aStart.Col(), aOutRange.aStart.Row(),
aOutRange.aEnd.Col(), aOutRange.aEnd.Row());
SCCOL nCol;
SCROW nRow1, nRow2;
rtl::OUString sOUButtonList;
const ScPatternAttr* pAttr = aAttrItr.GetNext(nCol, nRow1, nRow2);
while (pAttr)
{
ScMergeFlagAttr& rItem = (ScMergeFlagAttr&)pAttr->GetItem(ATTR_MERGE_FLAG);
if (rItem.HasButton())
{
for (SCROW nButtonRow = nRow1; nButtonRow <= nRow2; ++nButtonRow)
{
ScAddress aButtonAddr(nCol, nButtonRow, aOutRange.aStart.Tab());
ScRangeStringConverter::GetStringFromAddress(
sOUButtonList, aButtonAddr, pDoc, ::formula::FormulaGrammar::CONV_OOO, ' ', sal_True );
}
}
pAttr = aAttrItr.GetNext(nCol, nRow1, nRow2);
}
rtl::OUString sName((*pDPs)[i]->GetName());
rtl::OUString sApplicationData((*pDPs)[i]->GetTag());
sal_Bool bRowGrand = pDPSave->GetRowGrand();
sal_Bool bColumnGrand = pDPSave->GetColumnGrand();
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, sName);
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_APPLICATION_DATA, sApplicationData);
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, sTargetRangeAddress);
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_BUTTONS, sOUButtonList);
if (!(bRowGrand && bColumnGrand))
{
if (bRowGrand)
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GRAND_TOTAL, XML_ROW);
else if (bColumnGrand)
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GRAND_TOTAL, XML_COLUMN);
else
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GRAND_TOTAL, XML_NONE);
}
if (pDPSave->GetIgnoreEmptyRows())
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IGNORE_EMPTY_ROWS, XML_TRUE);
if (pDPSave->GetRepeatIfEmpty())
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IDENTIFY_CATEGORIES, XML_TRUE);
if (!pDPSave->GetFilterButton())
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SHOW_FILTER_BUTTON, XML_FALSE);
if (!pDPSave->GetDrillDown())
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DRILL_DOWN_ON_DOUBLE_CLICK, XML_FALSE);
SvXMLElementExport aElemDP(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_TABLE, sal_True, sal_True);
// grand total elements.
const OUString* pGrandTotalName = pDPSave->GetGrandTotalName();
if (pGrandTotalName && rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST)
{
// Use the new data-pilot-grand-total element.
if (bRowGrand && bColumnGrand)
{
WriteGrandTotal(XML_BOTH, true, pGrandTotalName);
}
else
{
WriteGrandTotal(XML_ROW, bRowGrand, pGrandTotalName);
WriteGrandTotal(XML_COLUMN, bColumnGrand, pGrandTotalName);
}
}
rExport.CheckAttrList();
if ((*pDPs)[i]->IsSheetData())
{
const ScSheetSourceDesc* pSheetSource = (*pDPs)[i]->GetSheetDesc();
rtl::OUString sCellRangeAddress;
ScRangeStringConverter::GetStringFromRange( sCellRangeAddress, pSheetSource->aSourceRange, pDoc, ::formula::FormulaGrammar::CONV_OOO );
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, sCellRangeAddress);
SvXMLElementExport aElemSCR(rExport, XML_NAMESPACE_TABLE, XML_SOURCE_CELL_RANGE, sal_True, sal_True);
rExport.CheckAttrList();
WriteDPFilter(pSheetSource->aQueryParam);
}
else if ((*pDPs)[i]->IsImportData())
{
const ScImportSourceDesc* pImpSource = (*pDPs)[i]->GetImportSourceDesc();
switch (pImpSource->nType)
{
case sheet::DataImportMode_NONE : break;
case sheet::DataImportMode_QUERY :
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, rtl::OUString(pImpSource->aDBName));
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_QUERY_NAME, rtl::OUString(pImpSource->aObject));
SvXMLElementExport aElemID(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_QUERY, sal_True, sal_True);
rExport.CheckAttrList();
}
break;
case sheet::DataImportMode_TABLE :
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, rtl::OUString(pImpSource->aDBName));
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, rtl::OUString(pImpSource->aObject));
SvXMLElementExport aElemID(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_TABLE, sal_True, sal_True);
rExport.CheckAttrList();
}
break;
case sheet::DataImportMode_SQL :
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, rtl::OUString(pImpSource->aDBName));
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SQL_STATEMENT, rtl::OUString(pImpSource->aObject));
if (!pImpSource->bNative)
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PARSE_SQL_STATEMENT, XML_TRUE);
SvXMLElementExport aElemID(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_SQL, sal_True, sal_True);
rExport.CheckAttrList();
}
break;
}
}
else if ((*pDPs)[i]->IsServiceData())
{
const ScDPServiceDesc* pServSource = (*pDPs)[i]->GetDPServiceDesc();
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, rtl::OUString(pServSource->aServiceName));
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SOURCE_NAME, rtl::OUString(pServSource->aParSource));
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_OBJECT_NAME, rtl::OUString(pServSource->aParName));
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_USER_NAME, rtl::OUString(pServSource->aParUser));
// #i111754# leave out password attribute as long as DataPilotSource doesn't specify the content
// rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PASSWORD, rtl::OUString(pServSource->aParPass));
SvXMLElementExport aElemSD(rExport, XML_NAMESPACE_TABLE, XML_SOURCE_SERVICE, sal_True, sal_True);
rExport.CheckAttrList();
}
WriteDimensions(pDPSave);
}
}
}
}
}
}