diff options
-rw-r--r-- | sc/source/core/data/dptabres.cxx | 14 | ||||
-rw-r--r-- | sc/source/filter/excel/xepivot.cxx | 30 | ||||
-rw-r--r-- | sc/source/filter/excel/xipivot.cxx | 28 | ||||
-rw-r--r-- | sc/source/filter/xml/XMLExportDataPilot.cxx | 39 | ||||
-rw-r--r-- | sc/source/filter/xml/XMLExportDataPilot.hxx | 3 | ||||
-rw-r--r-- | sc/source/filter/xml/xmldpimp.cxx | 181 | ||||
-rw-r--r-- | sc/source/filter/xml/xmldpimp.hxx | 41 | ||||
-rw-r--r-- | sc/source/filter/xml/xmlimprt.cxx | 23 | ||||
-rw-r--r-- | sc/source/filter/xml/xmlimprt.hxx | 15 | ||||
-rw-r--r-- | sc/source/ui/view/dbfunc3.cxx | 14 |
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); } |