summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sc/source/core/data/dptabres.cxx14
-rw-r--r--sc/source/filter/excel/xepivot.cxx30
-rw-r--r--sc/source/filter/excel/xipivot.cxx28
-rw-r--r--sc/source/filter/xml/XMLExportDataPilot.cxx39
-rw-r--r--sc/source/filter/xml/XMLExportDataPilot.hxx3
-rw-r--r--sc/source/filter/xml/xmldpimp.cxx181
-rw-r--r--sc/source/filter/xml/xmldpimp.hxx41
-rw-r--r--sc/source/filter/xml/xmlimprt.cxx23
-rw-r--r--sc/source/filter/xml/xmlimprt.hxx15
-rw-r--r--sc/source/ui/view/dbfunc3.cxx14
10 files changed, 360 insertions, 28 deletions
diff --git a/sc/source/core/data/dptabres.cxx b/sc/source/core/data/dptabres.cxx
index 07a783bdb2b1..e548db56d7ff 100644
--- a/sc/source/core/data/dptabres.cxx
+++ b/sc/source/core/data/dptabres.cxx
@@ -1186,20 +1186,28 @@ void ScDPResultMember::ProcessData( const vector<ScDPItemData>& aChildMembers, c
}
/**
- * Parse subtotal string and replace all occurrences of '?' with the
- * caption string.
+ * Parse subtotal string and replace all occurrences of '?' with the caption
+ * string. Do ensure that escaped characters are not translated.
*/
static String lcl_parseSubtotalName(const String& rSubStr, const String& rCaption)
{
String aNewStr;
xub_StrLen n = rSubStr.Len();
+ bool bEscaped = false;
for (xub_StrLen i = 0; i < n; ++i)
{
sal_Unicode c = rSubStr.GetChar(i);
- if (c == sal_Unicode('?'))
+ if (!bEscaped && c == sal_Unicode('\\'))
+ {
+ bEscaped = true;
+ continue;
+ }
+
+ if (!bEscaped && c == sal_Unicode('?'))
aNewStr.Append(rCaption);
else
aNewStr.Append(c);
+ bEscaped = false;
}
return aNewStr;
}
diff --git a/sc/source/filter/excel/xepivot.cxx b/sc/source/filter/excel/xepivot.cxx
index 78bc0e0b2f99..80af288cce99 100644
--- a/sc/source/filter/excel/xepivot.cxx
+++ b/sc/source/filter/excel/xepivot.cxx
@@ -1035,6 +1035,31 @@ sal_uInt16 XclExpPTField::GetItemIndex( const String& rName, sal_uInt16 nDefault
// fill data --------------------------------------------------------------
+/**
+ * Calc's subtotal names are escaped with backslashes ('\'), while Excel's
+ * are not escaped at all.
+ */
+static OUString lcl_convertCalcSubtotalName(const OUString& rName)
+{
+ OUStringBuffer aBuf;
+ const sal_Unicode* p = rName.getStr();
+ sal_Int32 n = rName.getLength();
+ bool bEscaped = false;
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ const sal_Unicode c = p[i];
+ if (!bEscaped && c == sal_Unicode('\\'))
+ {
+ bEscaped = true;
+ continue;
+ }
+
+ aBuf.append(c);
+ bEscaped = false;
+ }
+ return aBuf.makeStringAndClear();
+}
+
void XclExpPTField::SetPropertiesFromDim( const ScDPSaveDimension& rSaveDim )
{
// orientation
@@ -1052,7 +1077,10 @@ void XclExpPTField::SetPropertiesFromDim( const ScDPSaveDimension& rSaveDim )
const rtl::OUString* pSubtotalName = rSaveDim.GetSubtotalName();
if (pSubtotalName)
- maFieldExtInfo.mpFieldTotalName.reset(new rtl::OUString(*pSubtotalName));
+ {
+ OUString aSubName = lcl_convertCalcSubtotalName(*pSubtotalName);
+ maFieldExtInfo.mpFieldTotalName.reset(new rtl::OUString(aSubName));
+ }
// subtotals
XclPTSubtotalVec aSubtotals;
diff --git a/sc/source/filter/excel/xipivot.cxx b/sc/source/filter/excel/xipivot.cxx
index 29e20e52e64a..e6bf8ea01a2f 100644
--- a/sc/source/filter/excel/xipivot.cxx
+++ b/sc/source/filter/excel/xipivot.cxx
@@ -61,6 +61,7 @@
#include "xltable.hxx"
using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
using ::com::sun::star::sheet::DataPilotFieldOrientation;
using ::com::sun::star::sheet::DataPilotFieldOrientation_DATA;
using ::com::sun::star::sheet::DataPilotFieldSortInfo;
@@ -1029,6 +1030,28 @@ void XclImpPTField::ConvertDataField( ScDPSaveData& rSaveData ) const
// private --------------------------------------------------------------------
+/**
+ * Convert Excel-encoded subtotal name to a Calc-encoded one.
+ */
+static OUString lcl_convertExcelSubtotalName(const OUString& rName)
+{
+ OUStringBuffer aBuf;
+ const sal_Unicode* p = rName.getStr();
+ sal_Int32 n = rName.getLength();
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ const sal_Unicode c = p[i];
+ if (c == sal_Unicode('\\'))
+ {
+ aBuf.append(c);
+ aBuf.append(c);
+ }
+ else
+ aBuf.append(c);
+ }
+ return aBuf.makeStringAndClear();
+}
+
ScDPSaveDimension* XclImpPTField::ConvertRCPField( ScDPSaveData& rSaveData ) const
{
const String& rFieldName = GetFieldName();
@@ -1084,7 +1107,10 @@ ScDPSaveDimension* XclImpPTField::ConvertRCPField( ScDPSaveData& rSaveData ) con
// custom subtotal name
if (maFieldExtInfo.mpFieldTotalName.get())
- rSaveDim.SetSubtotalName(*maFieldExtInfo.mpFieldTotalName);
+ {
+ OUString aSubName = lcl_convertExcelSubtotalName(*maFieldExtInfo.mpFieldTotalName);
+ rSaveDim.SetSubtotalName(aSubName);
+ }
return &rSaveDim;
}
diff --git a/sc/source/filter/xml/XMLExportDataPilot.cxx b/sc/source/filter/xml/XMLExportDataPilot.cxx
index 32cf92e08d1a..318606ca3c49 100644
--- a/sc/source/filter/xml/XMLExportDataPilot.cxx
+++ b/sc/source/filter/xml/XMLExportDataPilot.cxx
@@ -68,6 +68,7 @@
using namespace com::sun::star;
using namespace xmloff::token;
+using ::rtl::OUString;
ScXMLExportDataPilot::ScXMLExportDataPilot(ScXMLExport& rTempExport)
: rExport(rTempExport),
@@ -448,7 +449,10 @@ void ScXMLExportDataPilot::WriteLayoutInfo(ScDPSaveDimension* pDim)
void ScXMLExportDataPilot::WriteSubTotals(ScDPSaveDimension* pDim)
{
+ using sheet::GeneralFunction;
+
sal_Int32 nSubTotalCount = pDim->GetSubTotalsCount();
+ const OUString* pLayoutName = pDim->GetSubtotalName();
if (nSubTotalCount > 0)
{
SvXMLElementExport aElemSTs(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_SUBTOTALS, sal_True, sal_True);
@@ -456,8 +460,11 @@ void ScXMLExportDataPilot::WriteSubTotals(ScDPSaveDimension* pDim)
for (sal_Int32 nSubTotal = 0; nSubTotal < nSubTotalCount; nSubTotal++)
{
rtl::OUString sFunction;
- ScXMLConverter::GetStringFromFunction( sFunction, (sheet::GeneralFunction)pDim->GetSubTotalFunc(nSubTotal) );
+ 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, XML_DISPLAY_NAME, *pLayoutName);
SvXMLElementExport aElemST(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_SUBTOTAL, sal_True, sal_True);
}
}
@@ -473,6 +480,9 @@ void ScXMLExportDataPilot::WriteMembers(ScDPSaveDimension* pDim)
for (ScDPSaveDimension::MemberList::const_iterator i=rMembers.begin(); i != rMembers.end() ; i++)
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, rtl::OUString((*i)->GetName()));
+ const OUString* pLayoutName = (*i)->GetLayoutName();
+ if (pLayoutName)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, *pLayoutName);
rtl::OUStringBuffer sBuffer;
SvXMLUnitConverter::convertBool(sBuffer, (*i)->GetIsVisible());
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, sBuffer.makeStringAndClear());
@@ -670,6 +680,10 @@ void ScXMLExportDataPilot::WriteGroupDimElements(ScDPSaveDimension* pDim, const
void ScXMLExportDataPilot::WriteDimension(ScDPSaveDimension* pDim, const ScDPDimensionSaveData* pDimData)
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SOURCE_FIELD_NAME, rtl::OUString(pDim->GetName()));
+ const OUString* pLayoutName = pDim->GetLayoutName();
+ if (pLayoutName)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, *pLayoutName);
+
if (pDim->IsDataLayout())
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_DATA_LAYOUT_FIELD, XML_TRUE);
rtl::OUString sValueStr;
@@ -707,6 +721,15 @@ void ScXMLExportDataPilot::WriteDimensions(ScDPSaveData* pDPSave)
}
}
+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, XML_DISPLAY_NAME, *pGrandTotal);
+ SvXMLElementExport aElemGrandTotal(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_GRAND_TOTAL, sal_True, sal_True);
+}
+
void ScXMLExportDataPilot::WriteDataPilots(const uno::Reference <sheet::XSpreadsheetDocument>& /* xSpreadDoc */)
{
pDoc = rExport.GetDocument();
@@ -775,6 +798,20 @@ void ScXMLExportDataPilot::WriteDataPilots(const uno::Reference <sheet::XSpreads
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 (bRowGrand && bColumnGrand)
+ {
+ WriteGrandTotal(XML_BOTH, true, pGrandTotalName);
+ }
+ else
+ {
+ WriteGrandTotal(XML_ROW, bRowGrand, pGrandTotalName);
+ WriteGrandTotal(XML_COLUMN, bColumnGrand, pGrandTotalName);
+ }
+
rExport.CheckAttrList();
if ((*pDPs)[i]->IsSheetData())
{
diff --git a/sc/source/filter/xml/XMLExportDataPilot.hxx b/sc/source/filter/xml/XMLExportDataPilot.hxx
index fb78a59d616b..8bf884ab2fd6 100644
--- a/sc/source/filter/xml/XMLExportDataPilot.hxx
+++ b/sc/source/filter/xml/XMLExportDataPilot.hxx
@@ -34,6 +34,7 @@
#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
#include <rtl/ustring.hxx>
#include "global.hxx"
+#include "xmloff/xmltoken.hxx"
class ScXMLExport;
class ScDocument;
@@ -69,6 +70,8 @@ class ScXMLExportDataPilot
void WriteDimension(ScDPSaveDimension* pDim, const ScDPDimensionSaveData* pDimData);
void WriteDimensions(ScDPSaveData* pDPSave);
+ void WriteGrandTotal(::xmloff::token::XMLTokenEnum eOrient, bool bVisible, const ::rtl::OUString* pGrandTotal);
+
public:
ScXMLExportDataPilot(ScXMLExport& rExport);
~ScXMLExportDataPilot();
diff --git a/sc/source/filter/xml/xmldpimp.cxx b/sc/source/filter/xml/xmldpimp.cxx
index 428e369a94dc..9cdca232c25a 100644
--- a/sc/source/filter/xml/xmldpimp.cxx
+++ b/sc/source/filter/xml/xmldpimp.cxx
@@ -65,6 +65,8 @@
using namespace com::sun::star;
using namespace xmloff::token;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::xml::sax::XAttributeList;
using ::rtl::OUString;
//------------------------------------------------------------------
@@ -113,6 +115,9 @@ void ScXMLDataPilotTablesContext::EndElement()
{
}
+ScXMLDataPilotTableContext::GrandTotalItem::GrandTotalItem() :
+ mbVisible(false) {}
+
ScXMLDataPilotTableContext::ScXMLDataPilotTableContext( ScXMLImport& rImport,
USHORT nPrfx,
const ::rtl::OUString& rLName,
@@ -159,6 +164,19 @@ ScXMLDataPilotTableContext::ScXMLDataPilotTableContext( ScXMLImport& rImport,
case XML_TOK_DATA_PILOT_TABLE_ATTR_GRAND_TOTAL :
{
sGrandTotal = sValue;
+ if (IsXMLToken(sValue, XML_BOTH))
+ {
+ maRowGrandTotal.mbVisible = true;
+ maColGrandTotal.mbVisible = true;
+ }
+ else if (IsXMLToken(sValue, XML_ROW))
+ {
+ maRowGrandTotal.mbVisible = true;
+ }
+ else if (IsXMLToken(sValue, XML_COLUMN))
+ {
+ maColGrandTotal.mbVisible = true;
+ }
}
break;
case XML_TOK_DATA_PILOT_TABLE_ATTR_IGNORE_EMPTY_ROWS :
@@ -238,6 +256,11 @@ SvXMLImportContext *ScXMLDataPilotTableContext::CreateChildContext( USHORT nPref
nSourceType = SERVICE;
}
break;
+ case XML_TOK_DATA_PILOT_TABLE_ELEM_GRAND_TOTAL:
+ {
+ pContext = new ScXMLDataPilotGrandTotalContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ }
+ break;
case XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_CELL_RANGE :
{
pContext = new ScXMLSourceCellRangeContext(GetScImport(), nPrefix, rLName, xAttrList, this);
@@ -362,26 +385,15 @@ void ScXMLDataPilotTableContext::EndElement()
}
break;
}
- if (IsXMLToken(sGrandTotal, XML_BOTH))
- {
- pDPSave->SetRowGrand(sal_True);
- pDPSave->SetColumnGrand(sal_True);
- }
- else if (IsXMLToken(sGrandTotal, XML_ROW))
- {
- pDPSave->SetRowGrand(sal_True);
- pDPSave->SetColumnGrand(sal_False);
- }
- else if (IsXMLToken(sGrandTotal, XML_COLUMN))
- {
- pDPSave->SetRowGrand(sal_False);
- pDPSave->SetColumnGrand(sal_True);
- }
- else
- {
- pDPSave->SetRowGrand(sal_False);
- pDPSave->SetColumnGrand(sal_False);
- }
+
+ pDPSave->SetRowGrand(maRowGrandTotal.mbVisible);
+ pDPSave->SetColumnGrand(maColGrandTotal.mbVisible);
+ if (maRowGrandTotal.maDisplayName.getLength())
+ // TODO: Right now, we only support one grand total name for both
+ // column and row totals. Take the value from the row total for
+ // now.
+ pDPSave->SetGrandTotalName(maRowGrandTotal.maDisplayName);
+
pDPSave->SetIgnoreEmptyRows(bIgnoreEmptyRows);
pDPSave->SetRepeatIfEmpty(bIdentifyCategories);
pDPSave->SetFilterButton(bShowFilter);
@@ -399,6 +411,30 @@ void ScXMLDataPilotTableContext::EndElement()
}
}
+void ScXMLDataPilotTableContext::SetGrandTotal(
+ XMLTokenEnum eOrientation, bool bVisible, const OUString& rDisplayName)
+{
+ switch (eOrientation)
+ {
+ case XML_BOTH:
+ maRowGrandTotal.mbVisible = bVisible;
+ maRowGrandTotal.maDisplayName = rDisplayName;
+ maColGrandTotal.mbVisible = bVisible;
+ maColGrandTotal.maDisplayName = rDisplayName;
+ break;
+ case XML_ROW:
+ maRowGrandTotal.mbVisible = bVisible;
+ maRowGrandTotal.maDisplayName = rDisplayName;
+ break;
+ case XML_COLUMN:
+ maColGrandTotal.mbVisible = bVisible;
+ maColGrandTotal.maDisplayName = rDisplayName;
+ break;
+ default:
+ ;
+ }
+}
+
ScXMLDPSourceSQLContext::ScXMLDPSourceSQLContext( ScXMLImport& rImport,
USHORT nPrfx,
const ::rtl::OUString& rLName,
@@ -643,6 +679,80 @@ void ScXMLSourceServiceContext::EndElement()
{
}
+ScXMLImport& ScXMLDataPilotGrandTotalContext::GetScImport()
+{
+ return static_cast<ScXMLImport&>(GetImport());
+}
+
+ScXMLDataPilotGrandTotalContext::ScXMLDataPilotGrandTotalContext(
+ ScXMLImport& rImport, USHORT nPrefix, const OUString& rLName, const Reference<XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pTableContext ) :
+ SvXMLImportContext( rImport, nPrefix, rLName ),
+ mpTableContext(pTableContext),
+ meOrientation(NONE),
+ mbVisible(false)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotGrandTotalAttrTokenMap();
+ for (sal_Int16 i = 0; i < nAttrCount; ++i)
+ {
+ const OUString& rAttrName = xAttrList->getNameByIndex(i);
+ const OUString& rAttrValue = xAttrList->getValueByIndex(i);
+
+ OUString aLocalName;
+ USHORT nLocalPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(rAttrName, &aLocalName);
+ switch (rAttrTokenMap.Get(nLocalPrefix, aLocalName))
+ {
+ case XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY:
+ mbVisible = IsXMLToken(rAttrValue, XML_TRUE);
+ break;
+ case XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_ORIENTATION:
+ if (IsXMLToken(rAttrValue, XML_BOTH))
+ meOrientation = BOTH;
+ else if (IsXMLToken(rAttrValue, XML_ROW))
+ meOrientation = ROW;
+ else if (IsXMLToken(rAttrValue, XML_COLUMN))
+ meOrientation = COLUMN;
+ break;
+ case XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME:
+ maDisplayName = rAttrValue;
+ break;
+ default:
+ ;
+ }
+ }
+}
+
+ScXMLDataPilotGrandTotalContext::~ScXMLDataPilotGrandTotalContext()
+{
+}
+
+SvXMLImportContext* ScXMLDataPilotGrandTotalContext::CreateChildContext(
+ USHORT /*nPrefix*/, const ::rtl::OUString& /*rLocalName*/, const Reference<XAttributeList>& /*xAttrList*/ )
+{
+ return NULL;
+}
+
+void ScXMLDataPilotGrandTotalContext::EndElement()
+{
+ XMLTokenEnum eOrient = XML_NONE;
+ switch (meOrientation)
+ {
+ case BOTH:
+ eOrient = XML_BOTH;
+ break;
+ case ROW:
+ eOrient = XML_ROW;
+ break;
+ case COLUMN:
+ eOrient = XML_COLUMN;
+ break;
+ default:
+ ;
+ }
+ mpTableContext->SetGrandTotal(eOrient, mbVisible, maDisplayName);
+}
+
ScXMLSourceCellRangeContext::ScXMLSourceCellRangeContext( ScXMLImport& rImport,
USHORT nPrfx,
const ::rtl::OUString& rLName,
@@ -727,6 +837,7 @@ ScXMLDataPilotFieldContext::ScXMLDataPilotFieldContext( ScXMLImport& rImport,
{
sal_Bool bHasName(sal_False);
sal_Bool bDataLayout(sal_False);
+ OUString aDisplayName;
sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotFieldAttrTokenMap();
for( sal_Int16 i=0; i < nAttrCount; ++i )
@@ -745,6 +856,11 @@ ScXMLDataPilotFieldContext::ScXMLDataPilotFieldContext( ScXMLImport& rImport,
bHasName = sal_True;
}
break;
+ case XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME:
+ {
+ aDisplayName = sValue;
+ }
+ break;
case XML_TOK_DATA_PILOT_FIELD_ATTR_IS_DATA_LAYOUT_FIELD :
{
bDataLayout = IsXMLToken(sValue, XML_TRUE);
@@ -774,7 +890,11 @@ ScXMLDataPilotFieldContext::ScXMLDataPilotFieldContext( ScXMLImport& rImport,
}
}
if (bHasName)
+ {
pDim = new ScDPSaveDimension(String(sName), bDataLayout);
+ if (aDisplayName.getLength())
+ pDim->SetLayoutName(aDisplayName);
+ }
}
ScXMLDataPilotFieldContext::~ScXMLDataPilotFieldContext()
@@ -875,6 +995,12 @@ void ScXMLDataPilotFieldContext::EndElement()
}
}
+void ScXMLDataPilotFieldContext::SetSubTotalName(const OUString& rName)
+{
+ if (pDim)
+ pDim->SetSubtotalName(rName);
+}
+
ScXMLDataPilotFieldReferenceContext::ScXMLDataPilotFieldReferenceContext( ScXMLImport& rImport, USHORT nPrfx,
const ::rtl::OUString& rLName,
const uno::Reference<xml::sax::XAttributeList>& xAttrList,
@@ -1199,6 +1325,8 @@ SvXMLImportContext *ScXMLDataPilotSubTotalsContext::CreateChildContext( USHORT n
void ScXMLDataPilotSubTotalsContext::EndElement()
{
pDataPilotField->SetSubTotals(pFunctions, nFunctionCount);
+ if (maDisplayName.getLength())
+ pDataPilotField->SetSubTotalName(maDisplayName);
}
void ScXMLDataPilotSubTotalsContext::AddFunction(sal_Int16 nFunction)
@@ -1221,6 +1349,11 @@ void ScXMLDataPilotSubTotalsContext::AddFunction(sal_Int16 nFunction)
}
}
+void ScXMLDataPilotSubTotalsContext::SetDisplayName(const OUString& rName)
+{
+ maDisplayName = rName;
+}
+
ScXMLDataPilotSubTotalContext::ScXMLDataPilotSubTotalContext( ScXMLImport& rImport,
USHORT nPrfx,
const ::rtl::OUString& rLName,
@@ -1247,6 +1380,8 @@ ScXMLDataPilotSubTotalContext::ScXMLDataPilotSubTotalContext( ScXMLImport& rImpo
pDataPilotSubTotals->AddFunction( sal::static_int_cast<sal_Int16>(
ScXMLConverter::GetFunctionFromString( sValue ) ) );
}
+ case XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME:
+ pDataPilotSubTotals->SetDisplayName(sValue);
break;
}
}
@@ -1344,6 +1479,10 @@ ScXMLDataPilotMemberContext::ScXMLDataPilotMemberContext( ScXMLImport& rImport,
bHasName = sal_True;
}
break;
+ case XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME:
+ {
+ maDisplayName = sValue;
+ }
case XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY :
{
bDisplay = IsXMLToken(sValue, XML_TRUE);
@@ -1380,6 +1519,8 @@ void ScXMLDataPilotMemberContext::EndElement()
if (bHasName) // #i53407# don't check sName, empty name is allowed
{
ScDPSaveMember* pMember = new ScDPSaveMember(String(sName));
+ if (maDisplayName.getLength())
+ pMember->SetLayoutName(maDisplayName);
pMember->SetIsVisible(bDisplay);
pMember->SetShowDetails(bDisplayDetails);
pDataPilotField->AddMember(pMember);
diff --git a/sc/source/filter/xml/xmldpimp.hxx b/sc/source/filter/xml/xmldpimp.hxx
index 874fe27654ba..fee4e36c02e5 100644
--- a/sc/source/filter/xml/xmldpimp.hxx
+++ b/sc/source/filter/xml/xmldpimp.hxx
@@ -79,10 +79,18 @@ public:
class ScXMLDataPilotTableContext : public SvXMLImportContext
{
+ struct GrandTotalItem
+ {
+ ::rtl::OUString maDisplayName;
+ bool mbVisible;
+ GrandTotalItem();
+ };
ScDocument* pDoc;
ScDPObject* pDPObject;
ScDPSaveData* pDPSave;
ScDPDimensionSaveData* pDPDimSaveData;
+ GrandTotalItem maRowGrandTotal;
+ GrandTotalItem maColGrandTotal;
rtl::OUString sDataPilotTableName;
rtl::OUString sApplicationData;
rtl::OUString sGrandTotal;
@@ -131,6 +139,7 @@ public:
virtual void EndElement();
+ void SetGrandTotal(::xmloff::token::XMLTokenEnum eOrientation, bool bVisible, const ::rtl::OUString& rDisplayName);
void SetDatabaseName(const rtl::OUString& sValue) { sDatabaseName = sValue; }
void SetSourceObject(const rtl::OUString& sValue) { sSourceObject = sValue; }
void SetNative(const sal_Bool bValue) { bIsNative = bValue; }
@@ -253,6 +262,34 @@ public:
virtual void EndElement();
};
+class ScXMLDataPilotGrandTotalContext : public SvXMLImportContext
+{
+ enum Orientation { COLUMN, ROW, BOTH, NONE };
+
+ ScXMLImport& GetScImport();
+
+ ScXMLDataPilotTableContext* mpTableContext;
+ ::rtl::OUString maDisplayName;
+ Orientation meOrientation;
+ bool mbVisible;
+
+public:
+ ScXMLDataPilotGrandTotalContext(
+ ScXMLImport& rImport, USHORT nPrefix, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pTableContext );
+
+ virtual ~ScXMLDataPilotGrandTotalContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
class ScXMLSourceCellRangeContext : public SvXMLImportContext
{
ScXMLDataPilotTableContext* pDataPilotTable;
@@ -329,6 +366,7 @@ public:
void SetShowEmpty(const sal_Bool bValue) { if (pDim) pDim->SetShowEmpty(bValue); }
void SetSubTotals(const sal_uInt16* pFunctions, const sal_Int16 nCount) { if(pDim) pDim->SetSubTotals(nCount, pFunctions); }
+ void SetSubTotalName(const ::rtl::OUString& rName);
void AddMember(ScDPSaveMember* pMember) { if (pDim) pDim->AddMember(pMember); }
void SetFieldReference(const com::sun::star::sheet::DataPilotFieldReference& aRef) { if (pDim) pDim->SetReferenceValue(&aRef); }
void SetAutoShowInfo(const com::sun::star::sheet::DataPilotFieldAutoShowInfo& aInfo) { if (pDim) pDim->SetAutoShowInfo(&aInfo); }
@@ -453,6 +491,7 @@ class ScXMLDataPilotSubTotalsContext : public SvXMLImportContext
sal_Int16 nFunctionCount;
sal_uInt16* pFunctions;
+ ::rtl::OUString maDisplayName;
const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
@@ -476,6 +515,7 @@ public:
virtual void EndElement();
void AddFunction(sal_Int16 nFunction);
+ void SetDisplayName(const ::rtl::OUString& rName);
};
class ScXMLDataPilotSubTotalContext : public SvXMLImportContext
@@ -533,6 +573,7 @@ class ScXMLDataPilotMemberContext : public SvXMLImportContext
ScXMLDataPilotFieldContext* pDataPilotField;
rtl::OUString sName;
+ rtl::OUString maDisplayName;
sal_Bool bDisplay;
sal_Bool bDisplayDetails;
sal_Bool bHasName;
diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx
index 873e95168088..f025a97ce5ae 100644
--- a/sc/source/filter/xml/xmlimprt.cxx
+++ b/sc/source/filter/xml/xmlimprt.cxx
@@ -1344,6 +1344,7 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotTableElemTokenMap()
{
{ XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_SQL, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SQL },
{ XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_TABLE, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_TABLE },
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_GRAND_TOTAL, XML_TOK_DATA_PILOT_TABLE_ELEM_GRAND_TOTAL },
{ XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_QUERY, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_QUERY },
{ XML_NAMESPACE_TABLE, XML_SOURCE_SERVICE, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SERVICE },
{ XML_NAMESPACE_TABLE, XML_SOURCE_CELL_RANGE, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_CELL_RANGE },
@@ -1377,6 +1378,24 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotTableSourceServiceAttrTokenMap()
return *pDataPilotTableSourceServiceAttrTokenMap;
}
+const SvXMLTokenMap& ScXMLImport::GetDataPilotGrandTotalAttrTokenMap()
+{
+ if (!pDataPilotGrandTotalAttrTokenMap)
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDataPilotGrandTotalAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY },
+ { XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_ORIENTATION },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotGrandTotalAttrTokenMap = new SvXMLTokenMap( aDataPilotGrandTotalAttrTokenMap );
+ }
+
+ return *pDataPilotGrandTotalAttrTokenMap;
+}
+
const SvXMLTokenMap& ScXMLImport::GetDataPilotTableSourceCellRangeAttrTokenMap()
{
if( !pDataPilotTableSourceCellRangeAttrTokenMap )
@@ -1416,6 +1435,7 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotFieldAttrTokenMap()
static __FAR_DATA SvXMLTokenMapEntry aDataPilotFieldAttrTokenMap[] =
{
{ XML_NAMESPACE_TABLE, XML_SOURCE_FIELD_NAME, XML_TOK_DATA_PILOT_FIELD_ATTR_SOURCE_FIELD_NAME },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME },
{ XML_NAMESPACE_TABLE, XML_IS_DATA_LAYOUT_FIELD, XML_TOK_DATA_PILOT_FIELD_ATTR_IS_DATA_LAYOUT_FIELD },
{ XML_NAMESPACE_TABLE, XML_FUNCTION, XML_TOK_DATA_PILOT_FIELD_ATTR_FUNCTION },
{ XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_TOK_DATA_PILOT_FIELD_ATTR_ORIENTATION },
@@ -1507,6 +1527,7 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotSubTotalAttrTokenMap()
static __FAR_DATA SvXMLTokenMapEntry aDataPilotSubTotalAttrTokenMap[] =
{
{ XML_NAMESPACE_TABLE, XML_FUNCTION, XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_FUNCTION },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME },
XML_TOKEN_MAP_END
};
@@ -1539,6 +1560,7 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotMemberAttrTokenMap()
static __FAR_DATA SvXMLTokenMapEntry aDataPilotMemberAttrTokenMap[] =
{
{ XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_DATA_PILOT_MEMBER_ATTR_NAME },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME },
{ XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY },
{ XML_NAMESPACE_TABLE, XML_SHOW_DETAILS, XML_TOK_DATA_PILOT_MEMBER_ATTR_SHOW_DETAILS },
XML_TOKEN_MAP_END
@@ -1674,6 +1696,7 @@ ScXMLImport::ScXMLImport(
pDataPilotTableAttrTokenMap( 0 ),
pDataPilotTableElemTokenMap( 0 ),
pDataPilotTableSourceServiceAttrTokenMap( 0 ),
+ pDataPilotGrandTotalAttrTokenMap(NULL),
pDataPilotTableSourceCellRangeElemTokenMap( 0 ),
pDataPilotTableSourceCellRangeAttrTokenMap( 0 ),
pDataPilotFieldAttrTokenMap( 0 ),
diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx
index 052ef20c6022..ec8a9cd6640b 100644
--- a/sc/source/filter/xml/xmlimprt.hxx
+++ b/sc/source/filter/xml/xmlimprt.hxx
@@ -489,6 +489,7 @@ enum ScXMLDataPilotTableElemTokens
{
XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SQL,
XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_TABLE,
+ XML_TOK_DATA_PILOT_TABLE_ELEM_GRAND_TOTAL,
XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_QUERY,
XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SERVICE,
XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_CELL_RANGE,
@@ -504,6 +505,13 @@ enum ScXMLDataPilotTableSourceServiceAttrTokens
XML_TOK_SOURCE_SERVICE_ATTR_PASSWORD
};
+enum ScXMLDataPilotGrandTotalAttrTokens
+{
+ XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY,
+ XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_ORIENTATION,
+ XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME
+};
+
enum ScXMLDataPilotTableSourceCellRangeElemTokens
{
XML_TOK_SOURCE_CELL_RANGE_ELEM_FILTER
@@ -517,6 +525,7 @@ enum ScXMLDataPilotTableSourceCellRangeAttrTokens
enum ScXMLDataPilotFieldAttrTokens
{
XML_TOK_DATA_PILOT_FIELD_ATTR_SOURCE_FIELD_NAME,
+ XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME,
XML_TOK_DATA_PILOT_FIELD_ATTR_IS_DATA_LAYOUT_FIELD,
XML_TOK_DATA_PILOT_FIELD_ATTR_FUNCTION,
XML_TOK_DATA_PILOT_FIELD_ATTR_ORIENTATION,
@@ -552,7 +561,8 @@ enum ScXMLDataPilotSubTotalsElemTokens
enum ScXMLDataPilotSubTotalAttrTokens
{
- XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_FUNCTION
+ XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_FUNCTION,
+ XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME
};
enum ScXMLDataPilotMembersElemTokens
@@ -563,6 +573,7 @@ enum ScXMLDataPilotMembersElemTokens
enum ScXMLDataPilotMemberAttrTokens
{
XML_TOK_DATA_PILOT_MEMBER_ATTR_NAME,
+ XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME,
XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY,
XML_TOK_DATA_PILOT_MEMBER_ATTR_SHOW_DETAILS
};
@@ -719,6 +730,7 @@ class ScXMLImport: public SvXMLImport
SvXMLTokenMap *pDataPilotTableAttrTokenMap;
SvXMLTokenMap *pDataPilotTableElemTokenMap;
SvXMLTokenMap *pDataPilotTableSourceServiceAttrTokenMap;
+ SvXMLTokenMap *pDataPilotGrandTotalAttrTokenMap;
SvXMLTokenMap *pDataPilotTableSourceCellRangeElemTokenMap;
SvXMLTokenMap *pDataPilotTableSourceCellRangeAttrTokenMap;
SvXMLTokenMap *pDataPilotFieldAttrTokenMap;
@@ -882,6 +894,7 @@ public:
const SvXMLTokenMap& GetDataPilotTableAttrTokenMap();
const SvXMLTokenMap& GetDataPilotTableElemTokenMap();
const SvXMLTokenMap& GetDataPilotTableSourceServiceAttrTokenMap();
+ const SvXMLTokenMap& GetDataPilotGrandTotalAttrTokenMap();
const SvXMLTokenMap& GetDataPilotTableSourceCellRangeElemTokenMap();
const SvXMLTokenMap& GetDataPilotTableSourceCellRangeAttrTokenMap();
const SvXMLTokenMap& GetDataPilotFieldAttrTokenMap();
diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx
index 41a5e9d0e050..c71bc31a1150 100644
--- a/sc/source/ui/view/dbfunc3.cxx
+++ b/sc/source/ui/view/dbfunc3.cxx
@@ -1355,7 +1355,7 @@ void ScDBFunc::UngroupDataPilot()
}
}
-OUString lcl_replaceMemberNameInSubtotal(const OUString& rSubtotal, const OUString& rMemberName)
+static OUString lcl_replaceMemberNameInSubtotal(const OUString& rSubtotal, const OUString& rMemberName)
{
sal_Int32 n = rSubtotal.getLength();
const sal_Unicode* p = rSubtotal.getStr();
@@ -1372,6 +1372,18 @@ OUString lcl_replaceMemberNameInSubtotal(const OUString& rSubtotal, const OUStri
aBuf.append(aWord);
aBuf.append(c);
}
+ else if (c == sal_Unicode('\\'))
+ {
+ // Escape a backslash character.
+ aWordBuf.append(c);
+ aWordBuf.append(c);
+ }
+ else if (c == sal_Unicode('?'))
+ {
+ // A literal '?' must be escaped with a backslash ('\');
+ aWordBuf.append(sal_Unicode('\\'));
+ aWordBuf.append(c);
+ }
else
aWordBuf.append(c);
}