diff options
Diffstat (limited to 'sc/source/filter/xml')
98 files changed, 41979 insertions, 0 deletions
diff --git a/sc/source/filter/xml/XMLCalculationSettingsContext.cxx b/sc/source/filter/xml/XMLCalculationSettingsContext.cxx new file mode 100644 index 000000000000..3d1c02fc2c11 --- /dev/null +++ b/sc/source/filter/xml/XMLCalculationSettingsContext.cxx @@ -0,0 +1,273 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- +#include "XMLCalculationSettingsContext.hxx" +#include "xmlimprt.hxx" +#include "unonames.hxx" +#include "docoptio.hxx" +#include "document.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/xmluconv.hxx> +#include <xmloff/nmspmap.hxx> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include <comphelper/extract.hxx> + +using namespace com::sun::star; +using namespace xmloff::token; + +//------------------------------------------------------------------ + +ScXMLCalculationSettingsContext::ScXMLCalculationSettingsContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList) : + SvXMLImportContext( rImport, nPrfx, rLName ), + fIterationEpsilon(0.001), + nIterationCount(100), + nYear2000(1930), + bIsIterationEnabled(sal_False), + bCalcAsShown(sal_False), + bIgnoreCase(sal_False), + bLookUpLabels(sal_True), + bMatchWholeCell(sal_True), + bUseRegularExpressions(sal_True) +{ + aNullDate.Day = 30; + aNullDate.Month = 12; + aNullDate.Year = 1899; + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(aLocalName, XML_CASE_SENSITIVE)) + { + if (IsXMLToken(sValue, XML_FALSE)) + bIgnoreCase = sal_True; + } + else if (IsXMLToken(aLocalName, XML_PRECISION_AS_SHOWN)) + { + if (IsXMLToken(sValue, XML_TRUE)) + bCalcAsShown = sal_True; + } + else if (IsXMLToken(aLocalName, XML_SEARCH_CRITERIA_MUST_APPLY_TO_WHOLE_CELL)) + { + if (IsXMLToken(sValue, XML_FALSE)) + bMatchWholeCell = sal_False; + } + else if (IsXMLToken(aLocalName, XML_AUTOMATIC_FIND_LABELS)) + { + if (IsXMLToken(sValue, XML_FALSE)) + bLookUpLabels = sal_False; + } + else if (IsXMLToken(aLocalName, XML_NULL_YEAR)) + { + sal_Int32 nTemp; + GetScImport().GetMM100UnitConverter().convertNumber(nTemp, sValue); + nYear2000 = static_cast<sal_uInt16>(nTemp); + } + else if (IsXMLToken(aLocalName, XML_USE_REGULAR_EXPRESSIONS)) + { + if (IsXMLToken(sValue, XML_FALSE)) + bUseRegularExpressions = sal_False; + } + } + } +} + +ScXMLCalculationSettingsContext::~ScXMLCalculationSettingsContext() +{ +} + +SvXMLImportContext *ScXMLCalculationSettingsContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(rLName, XML_NULL_DATE)) + pContext = new ScXMLNullDateContext(GetScImport(), nPrefix, rLName, xAttrList, this); + else if (IsXMLToken(rLName, XML_ITERATION)) + pContext = new ScXMLIterationContext(GetScImport(), nPrefix, rLName, xAttrList, this); + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLCalculationSettingsContext::EndElement() +{ + if (GetScImport().GetModel().is()) + { + uno::Reference <beans::XPropertySet> xPropertySet (GetScImport().GetModel(), uno::UNO_QUERY); + if (xPropertySet.is()) + { + xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_CALCASSHOWN)), uno::makeAny(bCalcAsShown) ); + xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_IGNORECASE)), uno::makeAny(bIgnoreCase) ); + xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_LOOKUPLABELS)), uno::makeAny(bLookUpLabels) ); + xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_MATCHWHOLE)), uno::makeAny(bMatchWholeCell) ); + xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_REGEXENABLED)), uno::makeAny(bUseRegularExpressions) ); + xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITERENABLED)), uno::makeAny(bIsIterationEnabled) ); + xPropertySet->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITERCOUNT)), uno::makeAny(nIterationCount) ); + xPropertySet->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITEREPSILON)), uno::makeAny(fIterationEpsilon) ); + xPropertySet->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_NULLDATE)), uno::makeAny(aNullDate) ); + if (GetScImport().GetDocument()) + { + GetScImport().LockSolarMutex(); + ScDocOptions aDocOptions (GetScImport().GetDocument()->GetDocOptions()); + aDocOptions.SetYear2000(nYear2000); + GetScImport().GetDocument()->SetDocOptions(aDocOptions); + GetScImport().UnlockSolarMutex(); + } + } + } +} + +ScXMLNullDateContext::ScXMLNullDateContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLCalculationSettingsContext* pCalcSet) : + SvXMLImportContext( rImport, nPrfx, rLName ) +{ + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + if (nPrefix == XML_NAMESPACE_TABLE && IsXMLToken(aLocalName, XML_DATE_VALUE)) + { + util::DateTime aDateTime; + GetScImport().GetMM100UnitConverter().convertDateTime(aDateTime, sValue); + util::Date aDate; + aDate.Day = aDateTime.Day; + aDate.Month = aDateTime.Month; + aDate.Year = aDateTime.Year; + pCalcSet->SetNullDate(aDate); + } + } +} + +ScXMLNullDateContext::~ScXMLNullDateContext() +{ +} + +SvXMLImportContext *ScXMLNullDateContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLNullDateContext::EndElement() +{ +} + +ScXMLIterationContext::ScXMLIterationContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLCalculationSettingsContext* pCalcSet) : + SvXMLImportContext( rImport, nPrfx, rLName ) +{ + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(aLocalName, XML_STATUS)) + { + if (IsXMLToken(sValue, XML_ENABLE)) + pCalcSet->SetIterationStatus(sal_True); + } + else if (IsXMLToken(aLocalName, XML_STEPS)) + { + sal_Int32 nSteps; + GetScImport().GetMM100UnitConverter().convertNumber(nSteps, sValue); + pCalcSet->SetIterationCount(nSteps); + } + else if (IsXMLToken(aLocalName, XML_MAXIMUM_DIFFERENCE)) + { + double fDif; + GetScImport().GetMM100UnitConverter().convertDouble(fDif, sValue); + pCalcSet->SetIterationEpsilon(fDif); + } + } + } +} + +ScXMLIterationContext::~ScXMLIterationContext() +{ +} + +SvXMLImportContext *ScXMLIterationContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLIterationContext::EndElement() +{ +} diff --git a/sc/source/filter/xml/XMLCalculationSettingsContext.hxx b/sc/source/filter/xml/XMLCalculationSettingsContext.hxx new file mode 100644 index 000000000000..4b5fa4a1114b --- /dev/null +++ b/sc/source/filter/xml/XMLCalculationSettingsContext.hxx @@ -0,0 +1,111 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLCALCULATIONSETTINGSCONTEXT_HXX +#define SC_XMLCALCULATIONSETTINGSCONTEXT_HXX + +#include <xmloff/xmlictxt.hxx> +#include <com/sun/star/util/Date.hpp> + +class ScXMLImport; + +class ScXMLCalculationSettingsContext : public SvXMLImportContext +{ + com::sun::star::util::Date aNullDate; + double fIterationEpsilon; + sal_Int32 nIterationCount; + sal_uInt16 nYear2000; + sal_Bool bIsIterationEnabled; + sal_Bool bCalcAsShown; + sal_Bool bIgnoreCase; + sal_Bool bLookUpLabels; + sal_Bool bMatchWholeCell; + sal_Bool bUseRegularExpressions; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } +public: + ScXMLCalculationSettingsContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList); + + virtual ~ScXMLCalculationSettingsContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + void SetNullDate(const com::sun::star::util::Date& aDate) { aNullDate = aDate; } + void SetIterationStatus(const sal_Bool bValue) { bIsIterationEnabled = bValue; } + void SetIterationCount(const sal_Int32 nValue) { nIterationCount = nValue; } + void SetIterationEpsilon(const double fValue) { fIterationEpsilon = fValue; } + virtual void EndElement(); +}; + +class ScXMLNullDateContext : public SvXMLImportContext +{ + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } +public: + ScXMLNullDateContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, ScXMLCalculationSettingsContext* pCalcSet); + + virtual ~ScXMLNullDateContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLIterationContext : public SvXMLImportContext +{ + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } +public: + ScXMLIterationContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, ScXMLCalculationSettingsContext* pCalcSet); + + virtual ~ScXMLIterationContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +#endif diff --git a/sc/source/filter/xml/XMLCellRangeSourceContext.cxx b/sc/source/filter/xml/XMLCellRangeSourceContext.cxx new file mode 100644 index 000000000000..d02c5c52bba0 --- /dev/null +++ b/sc/source/filter/xml/XMLCellRangeSourceContext.cxx @@ -0,0 +1,133 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +//___________________________________________________________________ +#include "XMLCellRangeSourceContext.hxx" +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmluconv.hxx> +#include "xmlimprt.hxx" + +using ::rtl::OUString; +using namespace ::com::sun::star; + + +//___________________________________________________________________ + +ScMyImpCellRangeSource::ScMyImpCellRangeSource() : + nColumns( 0 ), + nRows( 0 ), + nRefresh( 0 ) +{ +} + + +//___________________________________________________________________ + +ScXMLCellRangeSourceContext::ScXMLCellRangeSourceContext( + ScXMLImport& rImport, + sal_uInt16 nPrfx, + const OUString& rLName, + const uno::Reference< xml::sax::XAttributeList >& xAttrList, + ScMyImpCellRangeSource* pCellRangeSource ) : + SvXMLImportContext( rImport, nPrfx, rLName ) +{ + if( !xAttrList.is() ) return; + + sal_Int16 nAttrCount = xAttrList->getLength(); + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetTableCellRangeSourceAttrTokenMap(); + + for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( nIndex )); + const OUString& sValue(xAttrList->getValueByIndex( nIndex )); + OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_NAME: + pCellRangeSource->sSourceStr = sValue; + break; + case XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_FILTER_NAME: + pCellRangeSource->sFilterName = sValue; + break; + case XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_FILTER_OPTIONS: + pCellRangeSource->sFilterOptions = sValue; + break; + case XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_HREF: + pCellRangeSource->sURL = GetScImport().GetAbsoluteReference(sValue); + break; + case XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_LAST_COLUMN: + { + sal_Int32 nValue; + if( SvXMLUnitConverter::convertNumber( nValue, sValue, 1 ) ) + pCellRangeSource->nColumns = nValue; + else + pCellRangeSource->nColumns = 1; + } + break; + case XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_LAST_ROW: + { + sal_Int32 nValue; + if( SvXMLUnitConverter::convertNumber( nValue, sValue, 1 ) ) + pCellRangeSource->nRows = nValue; + else + pCellRangeSource->nRows = 1; + } + break; + case XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_REFRESH_DELAY: + { + double fTime; + if( SvXMLUnitConverter::convertTime( fTime, sValue ) ) + pCellRangeSource->nRefresh = Max( (sal_Int32)(fTime * 86400.0), (sal_Int32)0 ); + } + break; + } + } +} + +ScXMLCellRangeSourceContext::~ScXMLCellRangeSourceContext() +{ +} + +SvXMLImportContext *ScXMLCellRangeSourceContext::CreateChildContext( + sal_uInt16 nPrefix, + const OUString& rLName, + const uno::Reference< xml::sax::XAttributeList>& /* xAttrList */ ) +{ + return new SvXMLImportContext( GetImport(), nPrefix, rLName ); +} + +void ScXMLCellRangeSourceContext::EndElement() +{ +} + diff --git a/sc/source/filter/xml/XMLCellRangeSourceContext.hxx b/sc/source/filter/xml/XMLCellRangeSourceContext.hxx new file mode 100644 index 000000000000..34645007f0f9 --- /dev/null +++ b/sc/source/filter/xml/XMLCellRangeSourceContext.hxx @@ -0,0 +1,80 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLCELLRANGESOURCECONTEXT_HXX +#define SC_XMLCELLRANGESOURCECONTEXT_HXX + +#include <xmloff/xmlimp.hxx> + +class ScXMLImport; + + +//___________________________________________________________________ + +struct ScMyImpCellRangeSource +{ + ::rtl::OUString sSourceStr; + ::rtl::OUString sFilterName; + ::rtl::OUString sFilterOptions; + ::rtl::OUString sURL; + sal_Int32 nColumns; + sal_Int32 nRows; + sal_Int32 nRefresh; + + ScMyImpCellRangeSource(); +}; + + +//___________________________________________________________________ + +class ScXMLCellRangeSourceContext : public SvXMLImportContext +{ +private: + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLCellRangeSourceContext( + ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList, + ScMyImpCellRangeSource* pCellRangeSource + ); + virtual ~ScXMLCellRangeSourceContext(); + + virtual SvXMLImportContext* CreateChildContext( + sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList + ); + virtual void EndElement(); +}; + + +#endif + diff --git a/sc/source/filter/xml/XMLChangeTrackingExportHelper.cxx b/sc/source/filter/xml/XMLChangeTrackingExportHelper.cxx new file mode 100644 index 000000000000..5cd97e0714a9 --- /dev/null +++ b/sc/source/filter/xml/XMLChangeTrackingExportHelper.cxx @@ -0,0 +1,817 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" +#include "XMLChangeTrackingExportHelper.hxx" +#include "xmlexprt.hxx" +#include "XMLConverter.hxx" +#include "document.hxx" +#include "chgtrack.hxx" +#include "chgviset.hxx" +#include "cell.hxx" +#include "textuno.hxx" +#include "rangeutl.hxx" +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmluconv.hxx> +#include <com/sun/star/util/DateTime.hpp> +#include <tools/debug.hxx> +#include <tools/datetime.hxx> +#include <svl/zforlist.hxx> + +#define SC_CHANGE_ID_PREFIX "ct" + +using namespace ::com::sun::star; +using namespace xmloff::token; + +ScChangeTrackingExportHelper::ScChangeTrackingExportHelper(ScXMLExport& rTempExport) + : rExport(rTempExport), + pChangeTrack(NULL), + pEditTextObj(NULL), + pDependings(NULL), + sChangeIDPrefix(RTL_CONSTASCII_USTRINGPARAM(SC_CHANGE_ID_PREFIX)) +{ + pChangeTrack = rExport.GetDocument() ? rExport.GetDocument()->GetChangeTrack() : NULL; + pDependings = new ScChangeActionTable(); +} + +ScChangeTrackingExportHelper::~ScChangeTrackingExportHelper() +{ + if (pDependings) + delete pDependings; +} + +rtl::OUString ScChangeTrackingExportHelper::GetChangeID(const sal_uInt32 nActionNumber) +{ + rtl::OUStringBuffer sBuffer(sChangeIDPrefix); + SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(nActionNumber)); + return sBuffer.makeStringAndClear(); +} + +void ScChangeTrackingExportHelper::GetAcceptanceState(const ScChangeAction* pAction) +{ + if (pAction->IsRejected()) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ACCEPTANCE_STATE, XML_REJECTED); + else if (pAction->IsAccepted()) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ACCEPTANCE_STATE, XML_ACCEPTED); +} + +void ScChangeTrackingExportHelper::WriteBigRange(const ScBigRange& rBigRange, XMLTokenEnum aName) +{ + sal_Int32 nStartColumn; + sal_Int32 nEndColumn; + sal_Int32 nStartRow; + sal_Int32 nEndRow; + sal_Int32 nStartSheet; + sal_Int32 nEndSheet; + rBigRange.GetVars(nStartColumn, nStartRow, nStartSheet, + nEndColumn, nEndRow, nEndSheet); + if ((nStartColumn == nEndColumn) && (nStartRow == nEndRow) && (nStartSheet == nEndSheet)) + { + rtl::OUStringBuffer sBuffer; + SvXMLUnitConverter::convertNumber(sBuffer, nStartColumn); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_COLUMN, sBuffer.makeStringAndClear()); + SvXMLUnitConverter::convertNumber(sBuffer, nStartRow); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ROW, sBuffer.makeStringAndClear()); + SvXMLUnitConverter::convertNumber(sBuffer, nStartSheet); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE, sBuffer.makeStringAndClear()); + } + else + { + rtl::OUStringBuffer sBuffer; + SvXMLUnitConverter::convertNumber(sBuffer, nStartColumn); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START_COLUMN, sBuffer.makeStringAndClear()); + SvXMLUnitConverter::convertNumber(sBuffer, nStartRow); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START_ROW, sBuffer.makeStringAndClear()); + SvXMLUnitConverter::convertNumber(sBuffer, nStartSheet); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START_TABLE, sBuffer.makeStringAndClear()); + SvXMLUnitConverter::convertNumber(sBuffer, nEndColumn); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END_COLUMN, sBuffer.makeStringAndClear()); + SvXMLUnitConverter::convertNumber(sBuffer, nEndRow); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END_ROW, sBuffer.makeStringAndClear()); + SvXMLUnitConverter::convertNumber(sBuffer, nEndSheet); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END_TABLE, sBuffer.makeStringAndClear()); + } + SvXMLElementExport aBigRangeElem(rExport, XML_NAMESPACE_TABLE, aName, sal_True, sal_True); +} + +void ScChangeTrackingExportHelper::WriteChangeInfo(const ScChangeAction* pAction) +{ + SvXMLElementExport aElemInfo (rExport, XML_NAMESPACE_OFFICE, XML_CHANGE_INFO, sal_True, sal_True); + + { + SvXMLElementExport aCreatorElem( rExport, XML_NAMESPACE_DC, + XML_CREATOR, sal_True, + sal_False ); + rtl::OUString sAuthor(pAction->GetUser()); + rExport.Characters(sAuthor); + } + + { + rtl::OUStringBuffer sDate; + ScXMLConverter::ConvertDateTimeToString(pAction->GetDateTimeUTC(), sDate); + SvXMLElementExport aDateElem( rExport, XML_NAMESPACE_DC, + XML_DATE, sal_True, + sal_False ); + rExport.Characters(sDate.makeStringAndClear()); + } + + rtl::OUString sComment(pAction->GetComment()); + if (sComment.getLength()) + { + SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TEXT, XML_P, sal_True, sal_False); + sal_Bool bPrevCharWasSpace(sal_True); + rExport.GetTextParagraphExport()->exportText(sComment, bPrevCharWasSpace); + } +} + +void ScChangeTrackingExportHelper::WriteGenerated(const ScChangeAction* pGeneratedAction) +{ +#ifdef DBG_UTIL + sal_uInt32 nActionNumber(pGeneratedAction->GetActionNumber()); + DBG_ASSERT(pChangeTrack->IsGenerated(nActionNumber), "a not generated action found"); +#endif + SvXMLElementExport aElemPrev(rExport, XML_NAMESPACE_TABLE, XML_CELL_CONTENT_DELETION, sal_True, sal_True); + WriteBigRange(pGeneratedAction->GetBigRange(), XML_CELL_ADDRESS); + String sValue; + static_cast<const ScChangeActionContent*>(pGeneratedAction)->GetNewString(sValue); + WriteCell(static_cast<const ScChangeActionContent*>(pGeneratedAction)->GetNewCell(), sValue); +} + +void ScChangeTrackingExportHelper::WriteDeleted(const ScChangeAction* pDeletedAction) +{ + sal_uInt32 nActionNumber(pDeletedAction->GetActionNumber()); + if (pDeletedAction->GetType() == SC_CAT_CONTENT) + { + const ScChangeActionContent* pContentAction = static_cast<const ScChangeActionContent*>(pDeletedAction); + if (pContentAction) + { + if (!pChangeTrack->IsGenerated(nActionNumber)) + { + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(nActionNumber)); + SvXMLElementExport aElemPrev(rExport, XML_NAMESPACE_TABLE, XML_CELL_CONTENT_DELETION, sal_True, sal_True); + if (static_cast<const ScChangeActionContent*>(pDeletedAction)->IsTopContent() && pDeletedAction->IsDeletedIn()) + { + String sValue; + pContentAction->GetNewString(sValue); + WriteCell(pContentAction->GetNewCell(), sValue); + } + } + else + WriteGenerated(pContentAction); + } + } + else + { + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(nActionNumber)); + SvXMLElementExport aElemPrev(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_DELETION, sal_True, sal_True); + } +} + +void ScChangeTrackingExportHelper::WriteDepending(const ScChangeAction* pDependAction) +{ + sal_uInt32 nActionNumber(pDependAction->GetActionNumber()); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(nActionNumber)); + + // #i80033# save old "dependence" element if backward compatibility is requested, + // correct "dependency" element otherwise + const bool bSaveBackwardsCompatible = ( rExport.getExportFlags() & EXPORT_SAVEBACKWARDCOMPATIBLE ); + SvXMLElementExport aDependElem(rExport, XML_NAMESPACE_TABLE, + bSaveBackwardsCompatible ? XML_DEPENDENCE : XML_DEPENDENCY, + sal_True, sal_True); +} + +void ScChangeTrackingExportHelper::WriteDependings(ScChangeAction* pAction) +{ + if (pAction->HasDependent()) + { + SvXMLElementExport aDependingsElem (rExport, XML_NAMESPACE_TABLE, XML_DEPENDENCIES, sal_True, sal_True); + const ScChangeActionLinkEntry* pEntry = pAction->GetFirstDependentEntry(); + while (pEntry) + { + WriteDepending(pEntry->GetAction()); + pEntry = pEntry->GetNext(); + } + } + if (pAction->HasDeleted()) + { + SvXMLElementExport aDependingsElem (rExport, XML_NAMESPACE_TABLE, XML_DELETIONS, sal_True, sal_True); + const ScChangeActionLinkEntry* pEntry = pAction->GetFirstDeletedEntry(); + while (pEntry) + { + WriteDeleted(pEntry->GetAction()); + pEntry = pEntry->GetNext(); + } + /*if (pAction->IsDeleteType()) + { + ScChangeActionDel* pDelAction = static_cast<ScChangeActionDel*> (pAction); + if (pDelAction) + { + const ScChangeActionCellListEntry* pCellEntry = pDelAction->GetFirstCellEntry(); + while (pCellEntry) + { + WriteGenerated(pCellEntry->GetContent()); + pCellEntry = pCellEntry->GetNext(); + } + } + } + else if (pAction->GetType() == SC_CAT_MOVE) + { + ScChangeActionMove* pMoveAction = static_cast<ScChangeActionMove*> (pAction); + if (pMoveAction) + { + const ScChangeActionCellListEntry* pCellEntry = pMoveAction->GetFirstCellEntry(); + while (pCellEntry) + { + WriteGenerated(pCellEntry->GetContent()); + pCellEntry = pCellEntry->GetNext(); + } + } + }*/ + } +} + +/*void ScChangeTrackingExportHelper::WriteDependings(ScChangeAction* pAction) +{ + pChangeTrack->GetDependents(pAction, *pDependings); + if (pDependings->Count()) + { + SvXMLElementExport aDependingsElem (rExport, XML_NAMESPACE_TABLE, XML_DEPENDENCIES, sal_True, sal_True); + ScChangeAction* pDependAction = pDependings->First(); + while (pDependAction != NULL) + { + WriteDepending(pDependAction); + pDependAction = pDependings->Next(); + } + } +}*/ + +void ScChangeTrackingExportHelper::WriteEmptyCell() +{ + SvXMLElementExport aElemEmptyCell(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, sal_True, sal_True); +} + +void ScChangeTrackingExportHelper::SetValueAttributes(const double& fValue, const String& sValue) +{ + sal_Bool bSetAttributes(sal_False); + if (sValue.Len()) + { + sal_uInt32 nIndex; + double fTempValue; + if (rExport.GetDocument() && rExport.GetDocument()->GetFormatTable()->IsNumberFormat(sValue, nIndex, fTempValue)) + { + sal_uInt16 nType = rExport.GetDocument()->GetFormatTable()->GetType(nIndex); + if ((nType & NUMBERFORMAT_DEFINED) == NUMBERFORMAT_DEFINED) + nType -= NUMBERFORMAT_DEFINED; + switch(nType) + { + case NUMBERFORMAT_DATE: + { + if ( rExport.GetMM100UnitConverter().setNullDate(rExport.GetModel()) ) + { + rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_DATE); + rtl::OUStringBuffer sBuffer; + rExport.GetMM100UnitConverter().convertDateTime(sBuffer, fTempValue); + rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_DATE_VALUE, sBuffer.makeStringAndClear()); + bSetAttributes = sal_True; + } + } + break; + case NUMBERFORMAT_TIME: + { + rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_TIME); + rtl::OUStringBuffer sBuffer; + rExport.GetMM100UnitConverter().convertTime(sBuffer, fTempValue); + rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_TIME_VALUE, sBuffer.makeStringAndClear()); + bSetAttributes = sal_True; + } + break; + } + } + } + if (!bSetAttributes) + { + rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT); + rtl::OUStringBuffer sBuffer; + SvXMLUnitConverter::convertDouble(sBuffer, fValue); + rtl::OUString sNumValue(sBuffer.makeStringAndClear()); + if (sNumValue.getLength()) + rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE, sNumValue); + } +} + + +void ScChangeTrackingExportHelper::WriteValueCell(const ScBaseCell* pCell, const String& sValue) +{ + const ScValueCell* pValueCell = static_cast<const ScValueCell*>(pCell); + if (pValueCell) + { + SetValueAttributes(pValueCell->GetValue(), sValue); + SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, sal_True, sal_True); +/* if (sValue.Len()) + { + SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TEXT, XML_P, sal_True, sal_False); + sal_Bool bPrevCharWasSpace(sal_True); + rExport.GetTextParagraphExport()->exportText(sValue, bPrevCharWasSpace); + }*/ + } +} + +void ScChangeTrackingExportHelper::WriteStringCell(const ScBaseCell* pCell) +{ + const ScStringCell* pStringCell = static_cast<const ScStringCell*>(pCell); + if (pStringCell) + { + String sString; + pStringCell->GetString(sString); + rtl::OUString sOUString(sString); + rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING); + SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, sal_True, sal_True); + if (sOUString.getLength()) + { + SvXMLElementExport aElemP(rExport, XML_NAMESPACE_TEXT, XML_P, sal_True, sal_False); + sal_Bool bPrevCharWasSpace(sal_True); + rExport.GetTextParagraphExport()->exportText(sOUString, bPrevCharWasSpace); + } + } +} + +void ScChangeTrackingExportHelper::WriteEditCell(const ScBaseCell* pCell) +{ + const ScEditCell* pEditCell = static_cast<const ScEditCell*>(pCell); + if (pEditCell) + { + String sString; + pEditCell->GetString(sString); + rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING); + SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, sal_True, sal_True); + if (sString.Len()) + { + if (!pEditTextObj) + { + pEditTextObj = new ScEditEngineTextObj(); + xText.set(pEditTextObj); + } + pEditTextObj->SetText(*(pEditCell->GetData())); + if (xText.is()) + rExport.GetTextParagraphExport()->exportText(xText, sal_False, sal_False); + } + } +} + +void ScChangeTrackingExportHelper::WriteFormulaCell(const ScBaseCell* pCell, const String& sValue) +{ + ScBaseCell* pBaseCell = const_cast<ScBaseCell*>(pCell); + ScFormulaCell* pFormulaCell = static_cast<ScFormulaCell*>(pBaseCell); + if (pFormulaCell) + { + rtl::OUString sAddress; + const ScDocument* pDoc = rExport.GetDocument(); + ScRangeStringConverter::GetStringFromAddress(sAddress, pFormulaCell->aPos, pDoc, ::formula::FormulaGrammar::CONV_OOO); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CELL_ADDRESS, sAddress); + const formula::FormulaGrammar::Grammar eGrammar = pDoc->GetStorageGrammar(); + sal_uInt16 nNamespacePrefix = (eGrammar == formula::FormulaGrammar::GRAM_ODFF ? XML_NAMESPACE_OF : XML_NAMESPACE_OOOC); + String sFormula; + pFormulaCell->GetFormula(sFormula, eGrammar); + rtl::OUString sOUFormula(sFormula); + sal_uInt8 nMatrixFlag(pFormulaCell->GetMatrixFlag()); + if (nMatrixFlag) + { + if (nMatrixFlag == MM_FORMULA) + { + SCCOL nColumns; + SCROW nRows; + pFormulaCell->GetMatColsRows(nColumns, nRows); + rtl::OUStringBuffer sColumns; + rtl::OUStringBuffer sRows; + SvXMLUnitConverter::convertNumber(sColumns, static_cast<sal_Int32>(nColumns)); + SvXMLUnitConverter::convertNumber(sRows, static_cast<sal_Int32>(nRows)); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_COLUMNS_SPANNED, sColumns.makeStringAndClear()); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_ROWS_SPANNED, sRows.makeStringAndClear()); + } + else + { + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MATRIX_COVERED, XML_TRUE); + } + rtl::OUString sMatrixFormula = sOUFormula.copy(1, sOUFormula.getLength() - 2); + rtl::OUString sQValue = rExport.GetNamespaceMap().GetQNameByKey( nNamespacePrefix, sMatrixFormula, sal_False ); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FORMULA, sQValue); + } + else + { + rtl::OUString sQValue = rExport.GetNamespaceMap().GetQNameByKey( nNamespacePrefix, sFormula, sal_False ); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FORMULA, sQValue); + } + if (pFormulaCell->IsValue()) + { + SetValueAttributes(pFormulaCell->GetValue(), sValue); + SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, sal_True, sal_True); + } + else + { + rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING); + String sCellValue; + pFormulaCell->GetString(sCellValue); + rtl::OUString sOUValue(sCellValue); + SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, sal_True, sal_True); + if (sOUValue.getLength()) + { + SvXMLElementExport aElemP(rExport, XML_NAMESPACE_TEXT, XML_P, sal_True, sal_False); + sal_Bool bPrevCharWasSpace(sal_True); + rExport.GetTextParagraphExport()->exportText(sOUValue, bPrevCharWasSpace); + } + } + } +} + +void ScChangeTrackingExportHelper::WriteCell(const ScBaseCell* pCell, const String& sValue) +{ + if (pCell) + { + switch (pCell->GetCellType()) + { + case CELLTYPE_NONE: + WriteEmptyCell(); + break; + case CELLTYPE_VALUE: + WriteValueCell(pCell, sValue); + break; + case CELLTYPE_STRING: + WriteStringCell(pCell); + break; + case CELLTYPE_EDIT: + WriteEditCell(pCell); + break; + case CELLTYPE_FORMULA: + WriteFormulaCell(pCell, sValue); + break; + default: + { + // added to avoid warnings + } + } + } + else + WriteEmptyCell(); +} + +void ScChangeTrackingExportHelper::WriteContentChange(ScChangeAction* pAction) +{ + SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_CELL_CONTENT_CHANGE, sal_True, sal_True); + const ScChangeAction* pConstAction = pAction; + WriteBigRange(pConstAction->GetBigRange(), XML_CELL_ADDRESS); + WriteChangeInfo(pAction); + WriteDependings(pAction); + { + ScChangeActionContent* pPrevAction = static_cast<ScChangeActionContent*>(pAction)->GetPrevContent(); + if (pPrevAction) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(pPrevAction->GetActionNumber())); + SvXMLElementExport aElemPrev(rExport, XML_NAMESPACE_TABLE, XML_PREVIOUS, sal_True, sal_True); + String sValue; + static_cast<ScChangeActionContent*>(pAction)->GetOldString(sValue); + WriteCell(static_cast<ScChangeActionContent*>(pAction)->GetOldCell(), sValue); + } +} + +void ScChangeTrackingExportHelper::AddInsertionAttributes(const ScChangeAction* pConstAction) +{ + sal_Int32 nPosition(0); + sal_Int32 nCount(0); + sal_Int32 nStartPosition(0); + sal_Int32 nEndPosition(0); + sal_Int32 nStartColumn; + sal_Int32 nEndColumn; + sal_Int32 nStartRow; + sal_Int32 nEndRow; + sal_Int32 nStartSheet; + sal_Int32 nEndSheet; + const ScBigRange& rBigRange = pConstAction->GetBigRange(); + rBigRange.GetVars(nStartColumn, nStartRow, nStartSheet, + nEndColumn, nEndRow, nEndSheet); + switch (pConstAction->GetType()) + { + case SC_CAT_INSERT_COLS : + { + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_COLUMN); + nStartPosition = nStartColumn; + nEndPosition = nEndColumn; + } + break; + case SC_CAT_INSERT_ROWS : + { + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_ROW); + nStartPosition = nStartRow; + nEndPosition = nEndRow; + } + break; + case SC_CAT_INSERT_TABS : + { + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_TABLE); + nStartPosition = nStartSheet; + nEndPosition = nEndSheet; + } + break; + default : + { + DBG_ERROR("wrong insertion type"); + } + break; + } + nPosition = nStartPosition; + nCount = nEndPosition - nStartPosition + 1; + rtl::OUStringBuffer sBuffer; + SvXMLUnitConverter::convertNumber(sBuffer, nPosition); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_POSITION, sBuffer.makeStringAndClear()); + DBG_ASSERT(nCount > 0, "wrong insertion count"); + if (nCount > 1) + { + SvXMLUnitConverter::convertNumber(sBuffer, nCount); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_COUNT, sBuffer.makeStringAndClear()); + } + if (pConstAction->GetType() != SC_CAT_INSERT_TABS) + { + SvXMLUnitConverter::convertNumber(sBuffer, nStartSheet); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE, sBuffer.makeStringAndClear()); + } +} + +void ScChangeTrackingExportHelper::WriteInsertion(ScChangeAction* pAction) +{ + AddInsertionAttributes(pAction); + SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_INSERTION, sal_True, sal_True); + WriteChangeInfo(pAction); + WriteDependings(pAction); +} + +void ScChangeTrackingExportHelper::AddDeletionAttributes(const ScChangeActionDel* pDelAction, const ScChangeActionDel* /* pLastAction */) +{ + sal_Int32 nPosition(0); + const ScBigRange& rBigRange = pDelAction->GetBigRange(); + sal_Int32 nStartColumn(0); + sal_Int32 nEndColumn(0); + sal_Int32 nStartRow(0); + sal_Int32 nEndRow(0); + sal_Int32 nStartSheet(0); + sal_Int32 nEndSheet(0); + rBigRange.GetVars(nStartColumn, nStartRow, nStartSheet, + nEndColumn, nEndRow, nEndSheet); + switch (pDelAction->GetType()) + { + case SC_CAT_DELETE_COLS : + { + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_COLUMN); + nPosition = nStartColumn; + } + break; + case SC_CAT_DELETE_ROWS : + { + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_ROW); + nPosition = nStartRow; + } + break; + case SC_CAT_DELETE_TABS : + { + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_TABLE); + nPosition = nStartSheet; + //DBG_ERROR("not implemented feature"); + } + break; + default : + { + DBG_ERROR("wrong deletion type"); + } + break; + } + rtl::OUStringBuffer sBuffer; + SvXMLUnitConverter::convertNumber(sBuffer, nPosition); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_POSITION, sBuffer.makeStringAndClear()); + if (pDelAction->GetType() != SC_CAT_DELETE_TABS) + { + SvXMLUnitConverter::convertNumber(sBuffer, nStartSheet); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE, sBuffer.makeStringAndClear()); + if (pDelAction->IsMultiDelete() && !pDelAction->GetDx() && !pDelAction->GetDy()) + { + const ScChangeAction* p = pDelAction->GetNext(); + sal_Bool bAll(sal_False); + sal_Int32 nSlavesCount (1); + while (!bAll && p) + { + if ( !p || p->GetType() != pDelAction->GetType() ) + bAll = sal_True; + else + { + const ScChangeActionDel* pDel = (const ScChangeActionDel*) p; + if ( (pDel->GetDx() > pDelAction->GetDx() || pDel->GetDy() > pDelAction->GetDy()) && + pDel->GetBigRange() == pDelAction->GetBigRange() ) + { + ++nSlavesCount; + p = p->GetNext(); + } + else + bAll = sal_True; + } + } + + SvXMLUnitConverter::convertNumber(sBuffer, nSlavesCount); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MULTI_DELETION_SPANNED, sBuffer.makeStringAndClear()); + } + } +} + +void ScChangeTrackingExportHelper::WriteCutOffs(const ScChangeActionDel* pAction) +{ + const ScChangeActionIns* pCutOffIns = pAction->GetCutOffInsert(); + const ScChangeActionDelMoveEntry* pLinkMove = pAction->GetFirstMoveEntry(); + if (pCutOffIns || pLinkMove) + { + SvXMLElementExport aCutOffsElem (rExport, XML_NAMESPACE_TABLE, XML_CUT_OFFS, sal_True, sal_True); + rtl::OUStringBuffer sBuffer; + if (pCutOffIns) + { + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(pCutOffIns->GetActionNumber())); + SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(pAction->GetCutOffCount())); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_POSITION, sBuffer.makeStringAndClear()); + SvXMLElementExport aInsertCutOffElem (rExport, XML_NAMESPACE_TABLE, XML_INSERTION_CUT_OFF, sal_True, sal_True); + } + while (pLinkMove) + { + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(pLinkMove->GetAction()->GetActionNumber())); + if (pLinkMove->GetCutOffFrom() == pLinkMove->GetCutOffTo()) + { + SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(pLinkMove->GetCutOffFrom())); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_POSITION, sBuffer.makeStringAndClear()); + } + else + { + SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(pLinkMove->GetCutOffFrom())); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START_POSITION, sBuffer.makeStringAndClear()); + SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(pLinkMove->GetCutOffTo())); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END_POSITION, sBuffer.makeStringAndClear()); + } + SvXMLElementExport aMoveCutOffElem (rExport, XML_NAMESPACE_TABLE, XML_MOVEMENT_CUT_OFF, sal_True, sal_True); + pLinkMove = pLinkMove->GetNext(); + } + } +} + +void ScChangeTrackingExportHelper::WriteDeletion(ScChangeAction* pAction) +{ + ScChangeActionDel* pDelAction = static_cast<ScChangeActionDel*> (pAction); + AddDeletionAttributes(pDelAction, pDelAction); + SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_DELETION, sal_True, sal_True); + WriteChangeInfo(pDelAction); + WriteDependings(pDelAction); + WriteCutOffs(pDelAction); +} + +void ScChangeTrackingExportHelper::WriteMovement(ScChangeAction* pAction) +{ + const ScChangeActionMove* pMoveAction = static_cast<ScChangeActionMove*> (pAction); + SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_MOVEMENT, sal_True, sal_True); + WriteBigRange(pMoveAction->GetFromRange(), XML_SOURCE_RANGE_ADDRESS); + WriteBigRange(pMoveAction->GetBigRange(), XML_TARGET_RANGE_ADDRESS); + WriteChangeInfo(pAction); + WriteDependings(pAction); +} + +void ScChangeTrackingExportHelper::WriteRejection(ScChangeAction* pAction) +{ + SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_REJECTION, sal_True, sal_True); + WriteChangeInfo(pAction); + WriteDependings(pAction); +} + +void ScChangeTrackingExportHelper::CollectCellAutoStyles(const ScBaseCell* pBaseCell) +{ + if (pBaseCell && (pBaseCell->GetCellType() == CELLTYPE_EDIT)) + { + const ScEditCell* pEditCell = static_cast<const ScEditCell*>(pBaseCell); + if (pEditCell) + { + if (!pEditTextObj) + { + pEditTextObj = new ScEditEngineTextObj(); + xText.set(pEditTextObj); + } + pEditTextObj->SetText(*(pEditCell->GetData())); + if (xText.is()) + rExport.GetTextParagraphExport()->collectTextAutoStyles(xText, sal_False, sal_False); + } + } +} + +void ScChangeTrackingExportHelper::CollectActionAutoStyles(ScChangeAction* pAction) +{ + if (pAction->GetType() == SC_CAT_CONTENT) + { + if (pChangeTrack->IsGenerated(pAction->GetActionNumber())) + CollectCellAutoStyles(static_cast<ScChangeActionContent*>(pAction)->GetNewCell()); + else + { + CollectCellAutoStyles(static_cast<ScChangeActionContent*>(pAction)->GetOldCell()); + if (static_cast<ScChangeActionContent*>(pAction)->IsTopContent() && pAction->IsDeletedIn()) + CollectCellAutoStyles(static_cast<ScChangeActionContent*>(pAction)->GetNewCell()); + } + } +} + +void ScChangeTrackingExportHelper::WorkWithChangeAction(ScChangeAction* pAction) +{ + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(pAction->GetActionNumber())); + GetAcceptanceState(pAction); + if (pAction->IsRejecting()) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_REJECTING_CHANGE_ID, GetChangeID(pAction->GetRejectAction())); + if (pAction->GetType() == SC_CAT_CONTENT) + WriteContentChange(pAction); + else if (pAction->IsInsertType()) + WriteInsertion(pAction); + else if (pAction->IsDeleteType()) + WriteDeletion(pAction); + else if (pAction->GetType() == SC_CAT_MOVE) + WriteMovement(pAction); + else if (pAction->GetType() == SC_CAT_REJECT) + WriteRejection(pAction); + else + { + DBG_ERROR("not a writeable type"); + } + rExport.CheckAttrList(); +} + +void ScChangeTrackingExportHelper::CollectAutoStyles() +{ + if (pChangeTrack) + { + sal_uInt32 nCount (pChangeTrack->GetActionMax()); + if (nCount) + { + ScChangeAction* pAction = pChangeTrack->GetFirst(); + CollectActionAutoStyles(pAction); + ScChangeAction* pLastAction = pChangeTrack->GetLast(); + while (pAction != pLastAction) + { + pAction = pAction->GetNext(); + CollectActionAutoStyles(pAction); + } + pAction = pChangeTrack->GetFirstGenerated(); + while (pAction) + { + CollectActionAutoStyles(pAction); + pAction = pAction->GetNext(); + } + } + } +} + +void ScChangeTrackingExportHelper::CollectAndWriteChanges() +{ + if (pChangeTrack) + { +/* if (pChangeTrack->IsProtected()) + { + rtl::OUStringBuffer aBuffer; + SvXMLUnitConverter::encodeBase64(aBuffer, pChangeTrack->GetProtection()); + if (aBuffer.getLength()) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, aBuffer.makeStringAndClear()); + }*/ + SvXMLElementExport aCangeListElem(rExport, XML_NAMESPACE_TABLE, XML_TRACKED_CHANGES, sal_True, sal_True); + { + ScChangeAction* pAction = pChangeTrack->GetFirst(); + if (pAction) + { + WorkWithChangeAction(pAction); + ScChangeAction* pLastAction = pChangeTrack->GetLast(); + while (pAction != pLastAction) + { + pAction = pAction->GetNext(); + WorkWithChangeAction(pAction); + } + } + } + } +} diff --git a/sc/source/filter/xml/XMLChangeTrackingExportHelper.hxx b/sc/source/filter/xml/XMLChangeTrackingExportHelper.hxx new file mode 100644 index 000000000000..f07f0ed905a0 --- /dev/null +++ b/sc/source/filter/xml/XMLChangeTrackingExportHelper.hxx @@ -0,0 +1,98 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLCHANGETRACKINGEXPORTHELPER_HXX +#define SC_XMLCHANGETRACKINGEXPORTHELPER_HXX + +#include <xmloff/xmltoken.hxx> +#include <list> +#include <com/sun/star/text/XText.hpp> +#include <rtl/ustrbuf.hxx> + +class ScChangeAction; +class ScChangeTrack; +class ScXMLExport; +class ScBaseCell; +class ScChangeActionDel; +class ScBigRange; +class ScEditEngineTextObj; +class ScChangeActionTable; +class String; +class DateTime; + +typedef std::list<ScChangeActionDel*> ScMyDeletionsList; + +class ScChangeTrackingExportHelper +{ + ScXMLExport& rExport; + + ScChangeTrack* pChangeTrack; + ScEditEngineTextObj* pEditTextObj; + ScChangeActionTable* pDependings; + rtl::OUString sChangeIDPrefix; + com::sun::star::uno::Reference<com::sun::star::text::XText> xText; + + rtl::OUString GetChangeID(const sal_uInt32 nActionNumber); + void GetAcceptanceState(const ScChangeAction* pAction); + + void WriteBigRange(const ScBigRange& rBigRange, xmloff::token::XMLTokenEnum aName); + void WriteChangeInfo(const ScChangeAction* pAction); + void WriteGenerated(const ScChangeAction* pDependAction); + void WriteDeleted(const ScChangeAction* pDependAction); + void WriteDepending(const ScChangeAction* pDependAction); + void WriteDependings(ScChangeAction* pAction); + + void WriteEmptyCell(); + void SetValueAttributes(const double& fValue, const String& sValue); + void WriteValueCell(const ScBaseCell* pCell, const String& sValue); + void WriteStringCell(const ScBaseCell* pCell); + void WriteEditCell(const ScBaseCell* pCell); + void WriteFormulaCell(const ScBaseCell* pCell, const String& sValue); + void WriteCell(const ScBaseCell* pCell, const String& sValue); + + void WriteContentChange(ScChangeAction* pAction); + void AddInsertionAttributes(const ScChangeAction* pAction); + void WriteInsertion(ScChangeAction* pAction); + void AddDeletionAttributes(const ScChangeActionDel* pAction, const ScChangeActionDel* pLastAction); + void WriteDeletionCells(ScChangeActionDel* pAction); + void WriteCutOffs(const ScChangeActionDel* pAction); + void WriteDeletion(ScChangeAction* pAction); + void WriteMovement(ScChangeAction* pAction); + void WriteRejection(ScChangeAction* pAction); + + void CollectCellAutoStyles(const ScBaseCell* pBaseCell); + void CollectActionAutoStyles(ScChangeAction* pAction); + void WorkWithChangeAction(ScChangeAction* pAction); +public: + ScChangeTrackingExportHelper(ScXMLExport& rExport); + ~ScChangeTrackingExportHelper(); + + void CollectAutoStyles(); + void CollectAndWriteChanges(); +}; + +#endif diff --git a/sc/source/filter/xml/XMLChangeTrackingImportHelper.cxx b/sc/source/filter/xml/XMLChangeTrackingImportHelper.cxx new file mode 100644 index 000000000000..828f32de82da --- /dev/null +++ b/sc/source/filter/xml/XMLChangeTrackingImportHelper.cxx @@ -0,0 +1,935 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" +#include "XMLChangeTrackingImportHelper.hxx" +#include "XMLConverter.hxx" +#include "cell.hxx" +#include "document.hxx" +#include "chgviset.hxx" +#include "rangeutl.hxx" +#include <tools/debug.hxx> +#include <tools/datetime.hxx> +#include <svl/zforlist.hxx> +#include <xmloff/xmluconv.hxx> + +#define SC_CHANGE_ID_PREFIX "ct" + +ScMyCellInfo::ScMyCellInfo() + : pCell(NULL), + sFormulaAddress(), + sFormula(), + sInputString(), + fValue(0.0), + nMatrixCols(0), + nMatrixRows(0), + eGrammar( formula::FormulaGrammar::GRAM_STORAGE_DEFAULT), + nType(NUMBERFORMAT_ALL), + nMatrixFlag(MM_NONE) +{ +} + +ScMyCellInfo::ScMyCellInfo(ScBaseCell* pTempCell, const rtl::OUString& rFormulaAddress, const rtl::OUString& rFormula, + const formula::FormulaGrammar::Grammar eTempGrammar, const rtl::OUString& rInputString, + const double& rValue, const sal_uInt16 nTempType, const sal_uInt8 nTempMatrixFlag, const sal_Int32 nTempMatrixCols, + const sal_Int32 nTempMatrixRows) + : pCell(pTempCell), + sFormulaAddress(rFormulaAddress), + sFormula(rFormula), + sInputString(rInputString), + fValue(rValue), + nMatrixCols(nTempMatrixCols), + nMatrixRows(nTempMatrixRows), + eGrammar( eTempGrammar), + nType(nTempType), + nMatrixFlag(nTempMatrixFlag) +{ +} + +ScMyCellInfo::~ScMyCellInfo() +{ + if (pCell) + pCell->Delete(); +} + +ScBaseCell* ScMyCellInfo::CreateCell(ScDocument* pDoc) +{ + if (pDoc) + { + if (!pCell && sFormula.getLength() && sFormulaAddress.getLength()) + { + ScAddress aPos; + sal_Int32 nOffset(0); + ScRangeStringConverter::GetAddressFromString(aPos, sFormulaAddress, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset); + pCell = new ScFormulaCell(pDoc, aPos, sFormula, eGrammar, nMatrixFlag); + static_cast<ScFormulaCell*>(pCell)->SetMatColsRows(static_cast<SCCOL>(nMatrixCols), static_cast<SCROW>(nMatrixRows)); + } + + if ((nType == NUMBERFORMAT_DATE || nType == NUMBERFORMAT_TIME) && sInputString.Len() == 0) + { + sal_uInt32 nFormat(0); + if (nType == NUMBERFORMAT_DATE) + nFormat = pDoc->GetFormatTable()->GetStandardFormat( NUMBERFORMAT_DATE, ScGlobal::eLnge ); + else if (nType == NUMBERFORMAT_TIME) + nFormat = pDoc->GetFormatTable()->GetStandardFormat( NUMBERFORMAT_TIME, ScGlobal::eLnge ); + pDoc->GetFormatTable()->GetInputLineString(fValue, nFormat, sInputString); + } + } + + return pCell ? pCell->CloneWithoutNote( *pDoc ) : 0; +} + +ScMyDeleted::ScMyDeleted() + : pCellInfo(NULL) +{ +} + +ScMyDeleted::~ScMyDeleted() +{ + if (pCellInfo) + delete pCellInfo; +} + +ScMyGenerated::ScMyGenerated(ScMyCellInfo* pTempCellInfo, const ScBigRange& aTempBigRange) + : aBigRange(aTempBigRange), + nID(0), + pCellInfo(pTempCellInfo) +{ +} + +ScMyGenerated::~ScMyGenerated() +{ + if (pCellInfo) + delete pCellInfo; +} + +ScMyBaseAction::ScMyBaseAction(const ScChangeActionType nTempActionType) + : aDependencies(), + aDeletedList(), + nActionNumber(0), + nRejectingNumber(0), + nPreviousAction(0), + nActionType(nTempActionType), + nActionState(SC_CAS_VIRGIN) +{ +} + +ScMyBaseAction::~ScMyBaseAction() +{ +} + +ScMyInsAction::ScMyInsAction(const ScChangeActionType nActionTypeP) + : ScMyBaseAction(nActionTypeP) +{ +} + +ScMyInsAction::~ScMyInsAction() +{ +} + +ScMyDelAction::ScMyDelAction(const ScChangeActionType nActionTypeP) + : ScMyBaseAction(nActionTypeP), + aGeneratedList(), + pInsCutOff(NULL), + aMoveCutOffs(), + nD(0) +{ +} + +ScMyDelAction::~ScMyDelAction() +{ + if (pInsCutOff) + delete pInsCutOff; +} + +ScMyMoveAction::ScMyMoveAction() + : ScMyBaseAction(SC_CAT_MOVE), + aGeneratedList(), + pMoveRanges(NULL) +{ +} + +ScMyMoveAction::~ScMyMoveAction() +{ + if (pMoveRanges) + delete pMoveRanges; +} + + +ScMyContentAction::ScMyContentAction() + : ScMyBaseAction(SC_CAT_CONTENT), + pCellInfo(NULL) +{ +} + +ScMyContentAction::~ScMyContentAction() +{ + if (pCellInfo) + delete pCellInfo; +} + +ScMyRejAction::ScMyRejAction() + : ScMyBaseAction(SC_CAT_REJECT) +{ +} + +ScMyRejAction::~ScMyRejAction() +{ +} + +ScXMLChangeTrackingImportHelper::ScXMLChangeTrackingImportHelper() + : aUsers(), + aActions(), + pDoc(NULL), + pTrack(NULL), + pCurrentAction(NULL), + sIDPrefix(RTL_CONSTASCII_USTRINGPARAM(SC_CHANGE_ID_PREFIX)), + nMultiSpanned(0), + nMultiSpannedSlaveCount(0), + bChangeTrack(sal_False) +{ + nPrefixLength = sIDPrefix.getLength(); +} + +ScXMLChangeTrackingImportHelper::~ScXMLChangeTrackingImportHelper() +{ +} + +void ScXMLChangeTrackingImportHelper::StartChangeAction(const ScChangeActionType nActionType) +{ + DBG_ASSERT(!pCurrentAction, "a not inserted action"); + switch (nActionType) + { + case SC_CAT_INSERT_COLS: + case SC_CAT_INSERT_ROWS: + case SC_CAT_INSERT_TABS: + { + pCurrentAction = new ScMyInsAction(nActionType); + } + break; + case SC_CAT_DELETE_COLS: + case SC_CAT_DELETE_ROWS: + case SC_CAT_DELETE_TABS: + { + pCurrentAction = new ScMyDelAction(nActionType); + } + break; + case SC_CAT_MOVE: + { + pCurrentAction = new ScMyMoveAction(); + } + break; + case SC_CAT_CONTENT: + { + pCurrentAction = new ScMyContentAction(); + } + break; + case SC_CAT_REJECT: + { + pCurrentAction = new ScMyRejAction(); + } + break; + default: + { + // added to avoid warnings + } + } +} + +sal_uInt32 ScXMLChangeTrackingImportHelper::GetIDFromString(const rtl::OUString& sID) +{ + sal_uInt32 nResult(0); + sal_uInt32 nLength(sID.getLength()); + if (nLength) + { + if (sID.compareTo(sIDPrefix, nPrefixLength) == 0) + { + rtl::OUString sValue(sID.copy(nPrefixLength, nLength - nPrefixLength)); + sal_Int32 nValue; + SvXMLUnitConverter::convertNumber(nValue, sValue); + DBG_ASSERT(nValue > 0, "wrong change action ID"); + nResult = nValue; + } + else + { + DBG_ERROR("wrong change action ID"); + } + } + return nResult; +} + +void ScXMLChangeTrackingImportHelper::SetActionInfo(const ScMyActionInfo& aInfo) +{ + pCurrentAction->aInfo = aInfo; + String aUser(aInfo.sUser); + StrData* pStrData = new StrData( aUser ); + if ( !aUsers.Insert( pStrData ) ) + delete pStrData; +} + +void ScXMLChangeTrackingImportHelper::SetPreviousChange(const sal_uInt32 nPreviousAction, + ScMyCellInfo* pCellInfo) +{ + DBG_ASSERT(pCurrentAction->nActionType == SC_CAT_CONTENT, "wrong action type"); + ScMyContentAction* pAction = static_cast<ScMyContentAction*>(pCurrentAction); + pAction->nPreviousAction = nPreviousAction; + pAction->pCellInfo = pCellInfo; +} + +void ScXMLChangeTrackingImportHelper::SetPosition(const sal_Int32 nPosition, const sal_Int32 nCount, const sal_Int32 nTable) +{ + DBG_ASSERT(((pCurrentAction->nActionType != SC_CAT_MOVE) && + (pCurrentAction->nActionType != SC_CAT_CONTENT) && + (pCurrentAction->nActionType != SC_CAT_REJECT)), "wrong action type"); + DBG_ASSERT(nCount > 0, "wrong count"); + switch(pCurrentAction->nActionType) + { + case SC_CAT_INSERT_COLS: + case SC_CAT_DELETE_COLS: + { + pCurrentAction->aBigRange.Set(nPosition, nInt32Min, nTable, + nPosition + nCount - 1, nInt32Max, nTable); + } + break; + case SC_CAT_INSERT_ROWS: + case SC_CAT_DELETE_ROWS: + { + pCurrentAction->aBigRange.Set(nInt32Min, nPosition, nTable, + nInt32Max, nPosition + nCount - 1, nTable); + } + break; + case SC_CAT_INSERT_TABS: + case SC_CAT_DELETE_TABS: + { + pCurrentAction->aBigRange.Set(nInt32Min, nInt32Min, nPosition, + nInt32Max, nInt32Max, nPosition + nCount - 1); + } + break; + default: + { + // added to avoid warnings + } + } +} + +void ScXMLChangeTrackingImportHelper::AddDeleted(const sal_uInt32 nID) +{ + ScMyDeleted* pDeleted = new ScMyDeleted(); + pDeleted->nID = nID; + pCurrentAction->aDeletedList.push_front(pDeleted); +} + +void ScXMLChangeTrackingImportHelper::AddDeleted(const sal_uInt32 nID, ScMyCellInfo* pCellInfo) +{ + ScMyDeleted* pDeleted = new ScMyDeleted(); + pDeleted->nID = nID; + pDeleted->pCellInfo = pCellInfo; + pCurrentAction->aDeletedList.push_front(pDeleted); +} + +void ScXMLChangeTrackingImportHelper::SetMultiSpanned(const sal_Int16 nTempMultiSpanned) +{ + if (nTempMultiSpanned) + { + DBG_ASSERT(((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) || + (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS)), "wrong action type"); + nMultiSpanned = nTempMultiSpanned; + nMultiSpannedSlaveCount = 0; + } +} + +void ScXMLChangeTrackingImportHelper::SetInsertionCutOff(const sal_uInt32 nID, const sal_Int32 nPosition) +{ + if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) || + (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS)) + { + static_cast<ScMyDelAction*>(pCurrentAction)->pInsCutOff = new ScMyInsertionCutOff(nID, nPosition); + } + else + { + DBG_ERROR("wrong action type"); + } +} + +void ScXMLChangeTrackingImportHelper::AddMoveCutOff(const sal_uInt32 nID, const sal_Int32 nStartPosition, const sal_Int32 nEndPosition) +{ + if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) || + (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS)) + { + static_cast<ScMyDelAction*>(pCurrentAction)->aMoveCutOffs.push_front(ScMyMoveCutOff(nID, nStartPosition, nEndPosition)); + } + else + { + DBG_ERROR("wrong action type"); + } +} + +void ScXMLChangeTrackingImportHelper::SetMoveRanges(const ScBigRange& aSourceRange, const ScBigRange& aTargetRange) +{ + if (pCurrentAction->nActionType == SC_CAT_MOVE) + { + static_cast<ScMyMoveAction*>(pCurrentAction)->pMoveRanges = new ScMyMoveRanges(aSourceRange, aTargetRange); + } + else + { + DBG_ERROR("wrong action type"); + } +} + +void ScXMLChangeTrackingImportHelper::GetMultiSpannedRange() +{ + if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) || + (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS)) + { + if (nMultiSpannedSlaveCount) + { + static_cast<ScMyDelAction*>(pCurrentAction)->nD = nMultiSpannedSlaveCount; + } + ++nMultiSpannedSlaveCount; + if (nMultiSpannedSlaveCount >= nMultiSpanned) + { + nMultiSpanned = 0; + nMultiSpannedSlaveCount = 0; + } + } + else + { + DBG_ERROR("wrong action type"); + } +} + +void ScXMLChangeTrackingImportHelper::AddGenerated(ScMyCellInfo* pCellInfo, const ScBigRange& aBigRange) +{ + ScMyGenerated* pGenerated = new ScMyGenerated(pCellInfo, aBigRange); + if (pCurrentAction->nActionType == SC_CAT_MOVE) + { + static_cast<ScMyMoveAction*>(pCurrentAction)->aGeneratedList.push_back(pGenerated); + } + else if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) || + (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS)) + { + static_cast<ScMyDelAction*>(pCurrentAction)->aGeneratedList.push_back(pGenerated); + } + else + { + DBG_ERROR("try to insert a generated action to a wrong action"); + } +} + +void ScXMLChangeTrackingImportHelper::EndChangeAction() +{ + if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) || + (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS)) + GetMultiSpannedRange(); + if (pCurrentAction && pCurrentAction->nActionNumber > 0) + aActions.push_back(pCurrentAction); + else + { + DBG_ERROR("no current action"); + } + pCurrentAction = NULL; +} + +void ScXMLChangeTrackingImportHelper::ConvertInfo(const ScMyActionInfo& aInfo, String& rUser, DateTime& aDateTime) +{ + Date aDate(aInfo.aDateTime.Day, aInfo.aDateTime.Month, aInfo.aDateTime.Year); + Time aTime(aInfo.aDateTime.Hours, aInfo.aDateTime.Minutes, aInfo.aDateTime.Seconds, aInfo.aDateTime.HundredthSeconds); + aDateTime.SetDate( aDate.GetDate() ); + aDateTime.SetTime( aTime.GetTime() ); + + // #97286# old files didn't store 100th seconds, enable again + if ( aInfo.aDateTime.HundredthSeconds ) + pTrack->SetTime100thSeconds( sal_True ); + + StrData aStrData( aInfo.sUser ); + sal_uInt16 nPos; + if ( pTrack->GetUserCollection().Search( &aStrData, nPos ) ) + { + const StrData* pUser = static_cast<const StrData*>( pTrack->GetUserCollection().At( nPos ) ); + if ( pUser ) + rUser = pUser->GetString(); + else + rUser = aInfo.sUser; // shouldn't happen + } + else + rUser = aInfo.sUser; // shouldn't happen +} + +ScChangeAction* ScXMLChangeTrackingImportHelper::CreateInsertAction(ScMyInsAction* pAction) +{ + DateTime aDateTime( Date(0), Time(0) ); + String aUser; + ConvertInfo(pAction->aInfo, aUser, aDateTime); + + String sComment (pAction->aInfo.sComment); + + ScChangeAction* pNewAction = new ScChangeActionIns(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber, + pAction->aBigRange, aUser, aDateTime, sComment, pAction->nActionType); + return pNewAction; +} + +ScChangeAction* ScXMLChangeTrackingImportHelper::CreateDeleteAction(ScMyDelAction* pAction) +{ + DateTime aDateTime( Date(0), Time(0) ); + String aUser; + ConvertInfo(pAction->aInfo, aUser, aDateTime); + + String sComment (pAction->aInfo.sComment); + + ScChangeAction* pNewAction = new ScChangeActionDel(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber, + pAction->aBigRange, aUser, aDateTime, sComment, pAction->nActionType, pAction->nD, pTrack); + return pNewAction; +} + +ScChangeAction* ScXMLChangeTrackingImportHelper::CreateMoveAction(ScMyMoveAction* pAction) +{ + DBG_ASSERT(pAction->pMoveRanges, "no move ranges"); + if (pAction->pMoveRanges) + { + DateTime aDateTime( Date(0), Time(0) ); + String aUser; + ConvertInfo(pAction->aInfo, aUser, aDateTime); + + String sComment (pAction->aInfo.sComment); + + ScChangeAction* pNewAction = new ScChangeActionMove(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber, + pAction->pMoveRanges->aTargetRange, aUser, aDateTime, sComment, pAction->pMoveRanges->aSourceRange , pTrack); + return pNewAction; + } + return NULL; +} + +ScChangeAction* ScXMLChangeTrackingImportHelper::CreateRejectionAction(ScMyRejAction* pAction) +{ + DateTime aDateTime( Date(0), Time(0) ); + String aUser; + ConvertInfo(pAction->aInfo, aUser, aDateTime); + + String sComment (pAction->aInfo.sComment); + + ScChangeAction* pNewAction = new ScChangeActionReject(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber, + pAction->aBigRange, aUser, aDateTime, sComment); + return pNewAction; +} + +ScChangeAction* ScXMLChangeTrackingImportHelper::CreateContentAction(ScMyContentAction* pAction) +{ + ScBaseCell* pCell = NULL; + if (pAction->pCellInfo) + pCell = pAction->pCellInfo->CreateCell(pDoc); + + DateTime aDateTime( Date(0), Time(0) ); + String aUser; + ConvertInfo(pAction->aInfo, aUser, aDateTime); + + String sComment (pAction->aInfo.sComment); + + ScChangeAction* pNewAction = new ScChangeActionContent(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber, + pAction->aBigRange, aUser, aDateTime, sComment, pCell, pDoc, pAction->pCellInfo->sInputString); + return pNewAction; +} + +void ScXMLChangeTrackingImportHelper::CreateGeneratedActions(ScMyGeneratedList& rList) +{ + if (!rList.empty()) + { + ScMyGeneratedList::iterator aItr(rList.begin()); + ScMyGeneratedList::iterator aEndItr(rList.end()); + while (aItr != aEndItr) + { + if (((*aItr)->nID == 0)) + { + ScBaseCell* pCell = NULL; + if ((*aItr)->pCellInfo) + pCell = (*aItr)->pCellInfo->CreateCell(pDoc); + + if (pCell) + { + (*aItr)->nID = pTrack->AddLoadedGenerated(pCell, (*aItr)->aBigRange, (*aItr)->pCellInfo->sInputString ); + DBG_ASSERT((*aItr)->nID, "could not insert generated action"); + } + } + ++aItr; + } + } +} + +void ScXMLChangeTrackingImportHelper::SetDeletionDependencies(ScMyDelAction* pAction, ScChangeActionDel* pDelAct) +{ + if (!pAction->aGeneratedList.empty()) + { + DBG_ASSERT(((pAction->nActionType == SC_CAT_DELETE_COLS) || + (pAction->nActionType == SC_CAT_DELETE_ROWS) || + (pAction->nActionType == SC_CAT_DELETE_TABS)), "wrong action type"); + if (pDelAct) + { + ScMyGeneratedList::iterator aItr(pAction->aGeneratedList.begin()); + ScMyGeneratedList::iterator aEndItr(pAction->aGeneratedList.end()); + while (aItr != aEndItr) + { + DBG_ASSERT((*aItr)->nID, "a not inserted generated action"); + pDelAct->SetDeletedInThis((*aItr)->nID, pTrack); + if (*aItr) + delete *aItr; + aItr = pAction->aGeneratedList.erase(aItr); + } + } + } + if (pAction->pInsCutOff) + { + DBG_ASSERT(((pAction->nActionType == SC_CAT_DELETE_COLS) || + (pAction->nActionType == SC_CAT_DELETE_ROWS) || + (pAction->nActionType == SC_CAT_DELETE_TABS)), "wrong action type"); + ScChangeAction* pChangeAction = pTrack->GetAction(pAction->pInsCutOff->nID); + if (pChangeAction && pChangeAction->IsInsertType()) + { + ScChangeActionIns* pInsAction = static_cast<ScChangeActionIns*>(pChangeAction); + if (pInsAction && pDelAct) + pDelAct->SetCutOffInsert(pInsAction, static_cast<sal_Int16>(pAction->pInsCutOff->nPosition)); + } + else + { + DBG_ERROR("no cut off insert action"); + } + } + if (!pAction->aMoveCutOffs.empty()) + { + DBG_ASSERT(((pAction->nActionType == SC_CAT_DELETE_COLS) || + (pAction->nActionType == SC_CAT_DELETE_ROWS) || + (pAction->nActionType == SC_CAT_DELETE_TABS)), "wrong action type"); + ScMyMoveCutOffs::iterator aItr(pAction->aMoveCutOffs.begin()); + ScMyMoveCutOffs::iterator aEndItr(pAction->aMoveCutOffs.end()); + while(aItr != aEndItr) + { + ScChangeAction* pChangeAction = pTrack->GetAction(aItr->nID); + if (pChangeAction && (pChangeAction->GetType() == SC_CAT_MOVE)) + { + ScChangeActionMove* pMoveAction = static_cast<ScChangeActionMove*>(pChangeAction); + if (pMoveAction && pDelAct) + pDelAct->AddCutOffMove(pMoveAction, static_cast<sal_Int16>(aItr->nStartPosition), + static_cast<sal_Int16>(aItr->nEndPosition)); + } + else + { + DBG_ERROR("no cut off move action"); + } + aItr = pAction->aMoveCutOffs.erase(aItr); + } + } +} + +void ScXMLChangeTrackingImportHelper::SetMovementDependencies(ScMyMoveAction* pAction, ScChangeActionMove* pMoveAct) +{ + if (!pAction->aGeneratedList.empty()) + { + if (pAction->nActionType == SC_CAT_MOVE) + { + if (pMoveAct) + { + ScMyGeneratedList::iterator aItr(pAction->aGeneratedList.begin()); + ScMyGeneratedList::iterator aEndItr(pAction->aGeneratedList.end()); + while (aItr != aEndItr) + { + DBG_ASSERT((*aItr)->nID, "a not inserted generated action"); + pMoveAct->SetDeletedInThis((*aItr)->nID, pTrack); + if (*aItr) + delete *aItr; + aItr = pAction->aGeneratedList.erase(aItr); + } + } + } + } +} + +void ScXMLChangeTrackingImportHelper::SetContentDependencies(ScMyContentAction* pAction, ScChangeActionContent* pActContent) +{ + if (pAction->nPreviousAction) + { + DBG_ASSERT(pAction->nActionType == SC_CAT_CONTENT, "wrong action type"); + ScChangeAction* pPrevAct = pTrack->GetAction(pAction->nPreviousAction); + if (pPrevAct) + { + ScChangeActionContent* pPrevActContent = static_cast<ScChangeActionContent*>(pPrevAct); + if (pPrevActContent && pActContent) + { + pActContent->SetPrevContent(pPrevActContent); + pPrevActContent->SetNextContent(pActContent); + const ScBaseCell* pOldCell = pActContent->GetOldCell(); + if (pOldCell) + { + ScBaseCell* pNewCell = pOldCell->CloneWithoutNote( *pDoc ); + if (pNewCell) + { + pPrevActContent->SetNewCell(pNewCell, pDoc, EMPTY_STRING); + pPrevActContent->SetNewValue(pActContent->GetOldCell(), pDoc); + } + } + } + } + } +} + +void ScXMLChangeTrackingImportHelper::SetDependencies(ScMyBaseAction* pAction) +{ + ScChangeAction* pAct = pTrack->GetAction(pAction->nActionNumber); + if (pAct) + { + if (!pAction->aDependencies.empty()) + { + ScMyDependencies::iterator aItr(pAction->aDependencies.begin()); + ScMyDependencies::iterator aEndItr(pAction->aDependencies.end()); + while(aItr != aEndItr) + { + pAct->AddDependent(*aItr, pTrack); + aItr = pAction->aDependencies.erase(aItr); + } + } + if (!pAction->aDeletedList.empty()) + { + ScMyDeletedList::iterator aItr(pAction->aDeletedList.begin()); + ScMyDeletedList::iterator aEndItr(pAction->aDeletedList.end()); + while(aItr != aEndItr) + { + pAct->SetDeletedInThis((*aItr)->nID, pTrack); + ScChangeAction* pDeletedAct = pTrack->GetAction((*aItr)->nID); + if ((pDeletedAct->GetType() == SC_CAT_CONTENT) && (*aItr)->pCellInfo) + { + ScChangeActionContent* pContentAct = static_cast<ScChangeActionContent*>(pDeletedAct); + if (pContentAct && (*aItr)->pCellInfo) + { + ScBaseCell* pCell = (*aItr)->pCellInfo->CreateCell(pDoc); + if (!ScBaseCell::CellEqual(pCell, pContentAct->GetNewCell())) + { + // #i40704# Don't overwrite SetNewCell result by calling SetNewValue, + // instead pass the input string to SetNewCell. + pContentAct->SetNewCell(pCell, pDoc, (*aItr)->pCellInfo->sInputString); + } + } + } + if (*aItr) + delete *aItr; + aItr = pAction->aDeletedList.erase(aItr); + } + } + if ((pAction->nActionType == SC_CAT_DELETE_COLS) || + (pAction->nActionType == SC_CAT_DELETE_ROWS)) + SetDeletionDependencies(static_cast<ScMyDelAction*>(pAction), static_cast<ScChangeActionDel*>(pAct)); + else if (pAction->nActionType == SC_CAT_MOVE) + SetMovementDependencies(static_cast<ScMyMoveAction*>(pAction), static_cast<ScChangeActionMove*>(pAct)); + else if (pAction->nActionType == SC_CAT_CONTENT) + SetContentDependencies(static_cast<ScMyContentAction*>(pAction), static_cast<ScChangeActionContent*>(pAct)); + } + else + { + DBG_ERROR("could not find the action"); + } +} + +void ScXMLChangeTrackingImportHelper::SetNewCell(ScMyContentAction* pAction) +{ + ScChangeAction* pChangeAction = pTrack->GetAction(pAction->nActionNumber); + if (pChangeAction) + { + ScChangeActionContent* pChangeActionContent = static_cast<ScChangeActionContent*>(pChangeAction); + if (pChangeActionContent) + { + if (pChangeActionContent->IsTopContent() && !pChangeActionContent->IsDeletedIn()) + { + sal_Int32 nCol, nRow, nTab, nCol2, nRow2, nTab2; + pAction->aBigRange.GetVars(nCol, nRow, nTab, nCol2, nRow2, nTab2); + if ((nCol >= 0) && (nCol <= MAXCOL) && + (nRow >= 0) && (nRow <= MAXROW) && + (nTab >= 0) && (nTab <= MAXTAB)) + { + ScAddress aAddress (static_cast<SCCOL>(nCol), + static_cast<SCROW>(nRow), + static_cast<SCTAB>(nTab)); + ScBaseCell* pCell = pDoc->GetCell(aAddress); + if (pCell) + { + ScBaseCell* pNewCell = NULL; + if (pCell->GetCellType() != CELLTYPE_FORMULA) + pNewCell = pCell->CloneWithoutNote( *pDoc ); + else + { + sal_uInt8 nMatrixFlag = static_cast<ScFormulaCell*>(pCell)->GetMatrixFlag(); + String sFormula; + // With GRAM_ODFF reference detection is faster on compilation. + /* FIXME: new cell should be created with a clone + * of the token array instead. Any reason why this + * wasn't done? */ + static_cast<ScFormulaCell*>(pCell)->GetFormula(sFormula,formula::FormulaGrammar::GRAM_ODFF); + rtl::OUString sOUFormula(sFormula); + + // #i87826# [Collaboration] Rejected move destroys formulas + // FIXME: adjust ScFormulaCell::GetFormula(), so that the right formula string + // is returned and no further string handling is necessary + rtl::OUString sOUFormula2; + if ( nMatrixFlag != MM_NONE ) + { + sOUFormula2 = sOUFormula.copy( 2, sOUFormula.getLength() - 3 ); + } + else + { + sOUFormula2 = sOUFormula.copy( 1, sOUFormula.getLength() - 1 ); + } + + String sFormula2(sOUFormula2); + pNewCell = new ScFormulaCell(pDoc, aAddress, sFormula2,formula::FormulaGrammar::GRAM_ODFF, nMatrixFlag); + if (pNewCell) + { + if (nMatrixFlag == MM_FORMULA) + { + SCCOL nCols; + SCROW nRows; + static_cast<ScFormulaCell*>(pCell)->GetMatColsRows(nCols, nRows); + static_cast<ScFormulaCell*>(pNewCell)->SetMatColsRows(nCols, nRows); + } + static_cast<ScFormulaCell*>(pNewCell)->SetInChangeTrack(sal_True); + } + } + pChangeActionContent->SetNewCell(pNewCell, pDoc, EMPTY_STRING); + // #i40704# don't overwrite the formula string from above with pCell's content + if (pCell->GetCellType() != CELLTYPE_FORMULA) + pChangeActionContent->SetNewValue(pCell, pDoc); + } + } + else + { + DBG_ERROR("wrong cell position"); + } + } + } + } +} + +void ScXMLChangeTrackingImportHelper::CreateChangeTrack(ScDocument* pTempDoc) +{ + pDoc = pTempDoc; + if (pDoc) + { + pTrack = new ScChangeTrack(pDoc, aUsers); + // #97286# old files didn't store 100th seconds, disable until encountered + pTrack->SetTime100thSeconds( sal_False ); + + ScMyActions::iterator aItr(aActions.begin()); + ScMyActions::iterator aEndItr(aActions.end()); + while (aItr != aEndItr) + { + ScChangeAction* pAction = NULL; + + switch ((*aItr)->nActionType) + { + case SC_CAT_INSERT_COLS: + case SC_CAT_INSERT_ROWS: + case SC_CAT_INSERT_TABS: + { + pAction = CreateInsertAction(static_cast<ScMyInsAction*>(*aItr)); + } + break; + case SC_CAT_DELETE_COLS: + case SC_CAT_DELETE_ROWS: + case SC_CAT_DELETE_TABS: + { + ScMyDelAction* pDelAct = static_cast<ScMyDelAction*>(*aItr); + pAction = CreateDeleteAction(pDelAct); + CreateGeneratedActions(pDelAct->aGeneratedList); + } + break; + case SC_CAT_MOVE: + { + ScMyMoveAction* pMovAct = static_cast<ScMyMoveAction*>(*aItr); + pAction = CreateMoveAction(pMovAct); + CreateGeneratedActions(pMovAct->aGeneratedList); + } + break; + case SC_CAT_CONTENT: + { + pAction = CreateContentAction(static_cast<ScMyContentAction*>(*aItr)); + } + break; + case SC_CAT_REJECT: + { + pAction = CreateRejectionAction(static_cast<ScMyRejAction*>(*aItr)); + } + break; + default: + { + // added to avoid warnings + } + } + + if (pAction) + pTrack->AppendLoaded(pAction); + else + { + DBG_ERROR("no action"); + } + + ++aItr; + } + if (pTrack->GetLast()) + pTrack->SetActionMax(pTrack->GetLast()->GetActionNumber()); + + aItr = aActions.begin(); + aEndItr = aActions.end(); + while (aItr != aEndItr) + { + SetDependencies(*aItr); + + if ((*aItr)->nActionType == SC_CAT_CONTENT) + ++aItr; + else + { + if (*aItr) + delete (*aItr); + aItr = aActions.erase(aItr); + } + } + + aItr = aActions.begin(); + aEndItr = aActions.end(); + while (aItr != aEndItr) + { + DBG_ASSERT((*aItr)->nActionType == SC_CAT_CONTENT, "wrong action type"); + SetNewCell(static_cast<ScMyContentAction*>(*aItr)); + if (*aItr) + delete (*aItr); + aItr = aActions.erase(aItr); + } + if (aProtect.getLength()) + pTrack->SetProtection(aProtect); + else if (pDoc->GetChangeTrack() && pDoc->GetChangeTrack()->IsProtected()) + pTrack->SetProtection(pDoc->GetChangeTrack()->GetProtection()); + + if ( pTrack->GetLast() ) + pTrack->SetLastSavedActionNumber(pTrack->GetLast()->GetActionNumber()); + + pDoc->SetChangeTrack(pTrack); + } +} diff --git a/sc/source/filter/xml/XMLChangeTrackingImportHelper.hxx b/sc/source/filter/xml/XMLChangeTrackingImportHelper.hxx new file mode 100644 index 000000000000..9857683b13ac --- /dev/null +++ b/sc/source/filter/xml/XMLChangeTrackingImportHelper.hxx @@ -0,0 +1,249 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLCHANGETRACKINGIMPORTHELPER_HXX +#define SC_XMLCHANGETRACKINGIMPORTHELPER_HXX + +#include "chgtrack.hxx" +#include <list> +#include <com/sun/star/util/DateTime.hpp> + +class ScBaseCell; +class ScDocument; +class DateTime; + +struct ScMyActionInfo +{ + rtl::OUString sUser; + rtl::OUString sComment; + com::sun::star::util::DateTime aDateTime; +}; + +struct ScMyCellInfo +{ + ScBaseCell* pCell; + rtl::OUString sFormulaAddress; + rtl::OUString sFormula; + String sInputString; + double fValue; + sal_Int32 nMatrixCols; + sal_Int32 nMatrixRows; + formula::FormulaGrammar::Grammar eGrammar; + sal_uInt16 nType; + sal_uInt8 nMatrixFlag; + + ScMyCellInfo(ScBaseCell* pCell, const rtl::OUString& sFormulaAddress, const rtl::OUString& sFormula, + const formula::FormulaGrammar::Grammar eGrammar, const rtl::OUString& sInputString, + const double& fValue, const sal_uInt16 nType, const sal_uInt8 nMatrixFlag, const sal_Int32 nMatrixCols, + const sal_Int32 nMatrixRows); + ~ScMyCellInfo(); + + ScBaseCell* CreateCell(ScDocument* pDoc); + +private: + ScMyCellInfo(); // disabled +}; + +struct ScMyDeleted +{ + sal_uInt32 nID; + ScMyCellInfo* pCellInfo; + + ScMyDeleted(); + ~ScMyDeleted(); +}; + +typedef std::list<ScMyDeleted*> ScMyDeletedList; + +struct ScMyGenerated +{ + ScBigRange aBigRange; + sal_uInt32 nID; + ScMyCellInfo* pCellInfo; + + ScMyGenerated(ScMyCellInfo* pCellInfo, const ScBigRange& aBigRange); + ~ScMyGenerated(); +}; + +typedef std::list<ScMyGenerated*> ScMyGeneratedList; + +struct ScMyInsertionCutOff +{ + sal_uInt32 nID; + sal_Int32 nPosition; + + ScMyInsertionCutOff(const sal_uInt32 nTempID, const sal_Int32 nTempPosition) : + nID(nTempID), nPosition(nTempPosition) {} +}; + +struct ScMyMoveCutOff +{ + sal_uInt32 nID; + sal_Int32 nStartPosition; + sal_Int32 nEndPosition; + + ScMyMoveCutOff(const sal_uInt32 nTempID, const sal_Int32 nStartPos, const sal_Int32 nEndPos) : + nID(nTempID), nStartPosition(nStartPos), nEndPosition(nEndPos) {} +}; + +typedef std::list<ScMyMoveCutOff> ScMyMoveCutOffs; + +struct ScMyMoveRanges +{ + ScBigRange aSourceRange; + ScBigRange aTargetRange; + + ScMyMoveRanges(const ScBigRange& aSource, const ScBigRange aTarget) : + aSourceRange(aSource), aTargetRange(aTarget) {} +}; + +typedef std::list<sal_uInt32> ScMyDependencies; + +struct ScMyBaseAction +{ + ScMyActionInfo aInfo; + ScBigRange aBigRange; + ScMyDependencies aDependencies; + ScMyDeletedList aDeletedList; + sal_uInt32 nActionNumber; + sal_uInt32 nRejectingNumber; + sal_uInt32 nPreviousAction; + ScChangeActionType nActionType; + ScChangeActionState nActionState; + + ScMyBaseAction(const ScChangeActionType nActionType); + virtual ~ScMyBaseAction(); +}; + +struct ScMyInsAction : public ScMyBaseAction +{ + ScMyInsAction(const ScChangeActionType nActionType); + ~ScMyInsAction(); +}; + +struct ScMyDelAction : public ScMyBaseAction +{ + ScMyGeneratedList aGeneratedList; + ScMyInsertionCutOff* pInsCutOff; + ScMyMoveCutOffs aMoveCutOffs; + sal_Int32 nD; + + ScMyDelAction(const ScChangeActionType nActionType); + ~ScMyDelAction(); +}; + +struct ScMyMoveAction : public ScMyBaseAction +{ + ScMyGeneratedList aGeneratedList; + ScMyMoveRanges* pMoveRanges; + + ScMyMoveAction(); + ~ScMyMoveAction(); +}; + +struct ScMyContentAction : public ScMyBaseAction +{ + ScMyCellInfo* pCellInfo; + + ScMyContentAction(); + ~ScMyContentAction(); +}; + +struct ScMyRejAction : public ScMyBaseAction +{ + ScMyRejAction(); + ~ScMyRejAction(); +}; + +typedef std::list<ScMyBaseAction*> ScMyActions; + +class ScChangeViewSettings; + +class ScXMLChangeTrackingImportHelper +{ + ScStrCollection aUsers; + ScMyActions aActions; + com::sun::star::uno::Sequence<sal_Int8> aProtect; + ScDocument* pDoc; + ScChangeTrack* pTrack; + ScMyBaseAction* pCurrentAction; + rtl::OUString sIDPrefix; + sal_uInt32 nPrefixLength; + sal_Int16 nMultiSpanned; + sal_Int16 nMultiSpannedSlaveCount; + sal_Bool bChangeTrack; + +private: + void ConvertInfo(const ScMyActionInfo& aInfo, String& rUser, DateTime& aDateTime); + ScChangeAction* CreateInsertAction(ScMyInsAction* pAction); + ScChangeAction* CreateDeleteAction(ScMyDelAction* pAction); + ScChangeAction* CreateMoveAction(ScMyMoveAction* pAction); + ScChangeAction* CreateRejectionAction(ScMyRejAction* pAction); + ScChangeAction* CreateContentAction(ScMyContentAction* pAction); + + void CreateGeneratedActions(ScMyGeneratedList& rList); + +public: + ScXMLChangeTrackingImportHelper(); + ~ScXMLChangeTrackingImportHelper(); + + void SetChangeTrack(sal_Bool bValue) { bChangeTrack = bValue; } + void SetProtection(const com::sun::star::uno::Sequence<sal_Int8>& rProtect) { aProtect = rProtect; } + void StartChangeAction(const ScChangeActionType nActionType); + + sal_uInt32 GetIDFromString(const rtl::OUString& sID); + + void SetActionNumber(const sal_uInt32 nActionNumber) { pCurrentAction->nActionNumber = nActionNumber; } + void SetActionState(const ScChangeActionState nActionState) { pCurrentAction->nActionState = nActionState; } + void SetRejectingNumber(const sal_uInt32 nRejectingNumber) { pCurrentAction->nRejectingNumber = nRejectingNumber; } + void SetActionInfo(const ScMyActionInfo& aInfo); + void SetBigRange(const ScBigRange& aBigRange) { pCurrentAction->aBigRange = aBigRange; } + void SetPreviousChange(const sal_uInt32 nPreviousAction, ScMyCellInfo* pCellInfo); + void SetPosition(const sal_Int32 nPosition, const sal_Int32 nCount, const sal_Int32 nTable); + void AddDependence(const sal_uInt32 nID) { pCurrentAction->aDependencies.push_front(nID); } + void AddDeleted(const sal_uInt32 nID); + void AddDeleted(const sal_uInt32 nID, ScMyCellInfo* pCellInfo); + void SetMultiSpanned(const sal_Int16 nMultiSpanned); + void SetInsertionCutOff(const sal_uInt32 nID, const sal_Int32 nPosition); + void AddMoveCutOff(const sal_uInt32 nID, const sal_Int32 nStartPosition, const sal_Int32 nEndPosition); + void SetMoveRanges(const ScBigRange& aSourceRange, const ScBigRange& aTargetRange); + void GetMultiSpannedRange(); + void AddGenerated(ScMyCellInfo* pCellInfo, const ScBigRange& aBigRange); + + void EndChangeAction(); + + void SetDeletionDependencies(ScMyDelAction* pAction, ScChangeActionDel* pDelAct); + void SetMovementDependencies(ScMyMoveAction* pAction, ScChangeActionMove* pMoveAct); + void SetContentDependencies(ScMyContentAction* pAction, ScChangeActionContent* pActContent); + void SetDependencies(ScMyBaseAction* pAction); + + void SetNewCell(ScMyContentAction* pAction); + + void CreateChangeTrack(ScDocument* pDoc); +}; + +#endif diff --git a/sc/source/filter/xml/XMLCodeNameProvider.cxx b/sc/source/filter/xml/XMLCodeNameProvider.cxx new file mode 100644 index 000000000000..646d245c13f1 --- /dev/null +++ b/sc/source/filter/xml/XMLCodeNameProvider.cxx @@ -0,0 +1,204 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +// INCLUDE --------------------------------------------------------------- + +#include "XMLCodeNameProvider.hxx" +#include "document.hxx" + +using namespace rtl; +using namespace com::sun::star; + +sal_Bool XMLCodeNameProvider::_getCodeName( const uno::Any& aAny, String& rCodeName ) +{ + uno::Sequence<beans::PropertyValue> aProps; + if( !(aAny >>= aProps) ) + return sal_False; + + OUString sCodeNameProp( RTL_CONSTASCII_USTRINGPARAM("CodeName") ); + sal_Int32 nPropCount = aProps.getLength(); + for( sal_Int32 i=0; i<nPropCount; i++ ) + { + if( aProps[i].Name == sCodeNameProp ) + { + OUString sCodeName; + if( aProps[i].Value >>= sCodeName ) + { + rCodeName = sCodeName; + return sal_True; + } + } + } + + return sal_False; +} + + +XMLCodeNameProvider::XMLCodeNameProvider( ScDocument* pDoc ) : + mpDoc( pDoc ), + msDocName( RTL_CONSTASCII_USTRINGPARAM("*doc*") ), + msCodeNameProp( RTL_CONSTASCII_USTRINGPARAM("CodeName") ) +{ +} + +XMLCodeNameProvider::~XMLCodeNameProvider() +{ +} + +::sal_Bool SAL_CALL XMLCodeNameProvider::hasByName( const OUString& aName ) + throw (uno::RuntimeException ) +{ + if( aName == msDocName ) + return mpDoc->GetCodeName().Len() > 0; + + SCTAB nCount = mpDoc->GetTableCount(); + String sName( aName ); + String sSheetName, sCodeName; + for( SCTAB i = 0; i < nCount; i++ ) + { + if( mpDoc->GetName( i, sSheetName ) && sSheetName == sName ) + { + mpDoc->GetCodeName( i, sCodeName ); + return sCodeName.Len() > 0; + } + } + + return sal_False; +} + +uno::Any SAL_CALL XMLCodeNameProvider::getByName( const OUString& aName ) + throw (container::NoSuchElementException, + lang::WrappedTargetException, uno::RuntimeException) +{ + uno::Any aRet; + uno::Sequence<beans::PropertyValue> aProps(1); + aProps[0].Name = msCodeNameProp; + if( aName == msDocName ) + { + OUString sUCodeName( mpDoc->GetCodeName() ); + aProps[0].Value <<= sUCodeName; + aRet <<= aProps; + return aRet; + } + + SCTAB nCount = mpDoc->GetTableCount(); + String sName( aName ); + String sSheetName, sCodeName; + for( SCTAB i = 0; i < nCount; i++ ) + { + if( mpDoc->GetName( i, sSheetName ) && sSheetName == sName ) + { + mpDoc->GetCodeName( i, sCodeName ); + OUString sUCodeName( sCodeName ); + aProps[0].Value <<= sUCodeName; + aRet <<= aProps; + return aRet; + } + } + + return aRet; +} + +uno::Sequence< OUString > SAL_CALL XMLCodeNameProvider::getElementNames( ) + throw (uno::RuntimeException) +{ + SCTAB nCount = mpDoc->GetTableCount() + 1; + uno::Sequence< rtl::OUString > aNames( nCount ); + sal_Int32 nRealCount = 0; + + if( mpDoc->GetCodeName().Len() ) + aNames[nRealCount++] = msDocName; + + String sSheetName, sCodeName; + for( SCTAB i = 0; i < nCount; i++ ) + { + mpDoc->GetCodeName( i, sCodeName ); + if( sCodeName.Len() > 0 ) + { + if( mpDoc->GetName( i, sSheetName ) ) + aNames[nRealCount++] = sSheetName; + } + } + + if( nCount != nRealCount ) + aNames.realloc( nRealCount ); + + return aNames; +} + +uno::Type SAL_CALL XMLCodeNameProvider::getElementType( ) + throw (uno::RuntimeException) +{ + return getCppuType( static_cast< uno::Sequence< beans::PropertyValue >* >( 0 ) ); +} + +::sal_Bool SAL_CALL XMLCodeNameProvider::hasElements() + throw (uno::RuntimeException ) +{ + if( mpDoc->GetCodeName().Len() > 0 ) + return sal_True; + + SCTAB nCount = mpDoc->GetTableCount(); + String sSheetName, sCodeName; + for( SCTAB i = 0; i < nCount; i++ ) + { + mpDoc->GetCodeName( i, sCodeName ); + if( sCodeName.Len() > 0 && mpDoc->GetName( i, sSheetName ) ) + return sal_True; + } + + return sal_False; +} + +void XMLCodeNameProvider::set( const uno::Reference< container::XNameAccess>& xNameAccess, ScDocument *pDoc ) +{ + uno::Any aAny; + OUString sDocName( RTL_CONSTASCII_USTRINGPARAM("*doc*") ); + String sCodeName; + if( xNameAccess->hasByName( sDocName ) ) + { + aAny = xNameAccess->getByName( sDocName ); + if( _getCodeName( aAny, sCodeName ) ) + pDoc->SetCodeName( sCodeName ); + } + + SCTAB nCount = pDoc->GetTableCount(); + String sSheetName; + for( SCTAB i = 0; i < nCount; i++ ) + { + if( pDoc->GetName( i, sSheetName ) && + xNameAccess->hasByName( sSheetName ) ) + { + aAny = xNameAccess->getByName( sSheetName ); + if( _getCodeName( aAny, sCodeName ) ) + pDoc->SetCodeName( i, sCodeName ); + } + } +} diff --git a/sc/source/filter/xml/XMLCodeNameProvider.hxx b/sc/source/filter/xml/XMLCodeNameProvider.hxx new file mode 100755 index 000000000000..39d84409c555 --- /dev/null +++ b/sc/source/filter/xml/XMLCodeNameProvider.hxx @@ -0,0 +1,70 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLCODENAMEPROVIDER_HXX +#define SC_XMLCODENAMEPROVIDER_HXX + +#include <com/sun/star/container/XNameAccess.hpp> +#include <cppuhelper/implbase1.hxx> + +class ScDocument; +class String; + +class XMLCodeNameProvider : public ::cppu::WeakImplHelper1< ::com::sun::star::container::XNameAccess > +{ + ScDocument* mpDoc; + ::rtl::OUString msDocName; + ::rtl::OUString msCodeNameProp; + + static sal_Bool _getCodeName( const ::com::sun::star::uno::Any& aAny, + String& rCodeName ); + +public: + XMLCodeNameProvider( ScDocument* pDoc ); + virtual ~XMLCodeNameProvider(); + + virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) + throw (::com::sun::star::uno::RuntimeException ); + + virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) + throw (::com::sun::star::container::NoSuchElementException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) + throw (::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) + throw (::com::sun::star::uno::RuntimeException); + + virtual ::sal_Bool SAL_CALL hasElements() + throw (::com::sun::star::uno::RuntimeException ); + + static void set( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess>& xNameAccess, ScDocument *pDoc ); +}; + +#endif diff --git a/sc/source/filter/xml/XMLColumnRowGroupExport.cxx b/sc/source/filter/xml/XMLColumnRowGroupExport.cxx new file mode 100644 index 000000000000..4c2929de02e3 --- /dev/null +++ b/sc/source/filter/xml/XMLColumnRowGroupExport.cxx @@ -0,0 +1,187 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- +#include "XMLColumnRowGroupExport.hxx" +#include "xmlexprt.hxx" +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnmspe.hxx> + +#include <algorithm> + +using namespace xmloff::token; + +ScMyColumnRowGroup::ScMyColumnRowGroup() +{ +} + +sal_Bool ScMyColumnRowGroup::operator<(const ScMyColumnRowGroup& rGroup) const +{ + if (rGroup.nField > nField) + return sal_True; + else + if (rGroup.nField == nField && rGroup.nLevel > nLevel) + return sal_True; + else + return sal_False; +} + +ScMyOpenCloseColumnRowGroup::ScMyOpenCloseColumnRowGroup(ScXMLExport& rTempExport, sal_uInt32 nToken) + : rExport(rTempExport), + rName(rExport.GetNamespaceMap().GetQNameByKey(XML_NAMESPACE_TABLE, GetXMLToken(XMLTokenEnum(nToken)))), + aTableStart(), + aTableEnd() +{ +} + +ScMyOpenCloseColumnRowGroup::~ScMyOpenCloseColumnRowGroup() +{ +} + +void ScMyOpenCloseColumnRowGroup::NewTable() +{ + aTableStart.clear(); + aTableEnd.clear(); +} + +void ScMyOpenCloseColumnRowGroup::AddGroup(const ScMyColumnRowGroup& aGroup, const sal_Int32 nEndField) +{ + aTableStart.push_back(aGroup); + aTableEnd.push_back(nEndField); +} + +sal_Bool ScMyOpenCloseColumnRowGroup::IsGroupStart(const sal_Int32 nField) +{ + sal_Bool bGroupStart(sal_False); + if (!aTableStart.empty()) + { + ScMyColumnRowGroupVec::iterator aItr(aTableStart.begin()); + sal_Int32 nItrField = aItr->nField; + if ( nItrField < nField ) + { + // #103327# when used to find repeated rows at the beginning of a group, + // aTableStart may contain entries before nField. They must be skipped here + // (they will be used for OpenGroups later in the right order). + + ScMyColumnRowGroupVec::iterator aEnd(aTableStart.end()); + while ( aItr != aEnd && nItrField < nField ) + { + ++aItr; + if ( aItr != aEnd ) + nItrField = aItr->nField; + } + } + + if (nItrField == nField) + bGroupStart = sal_True; + } + return bGroupStart; +} + +void ScMyOpenCloseColumnRowGroup::OpenGroup(const ScMyColumnRowGroup& rGroup) +{ + if (!rGroup.bDisplay) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, XML_FALSE); + rExport.StartElement( rName, sal_True); +} + +void ScMyOpenCloseColumnRowGroup::OpenGroups(const sal_Int32 nField) +{ + ScMyColumnRowGroupVec::iterator aItr(aTableStart.begin()); + ScMyColumnRowGroupVec::iterator aEndItr(aTableStart.end()); + sal_Bool bReady(sal_False); + while(!bReady && aItr != aEndItr) + { + if (aItr->nField == nField) + { + OpenGroup(*aItr); + aItr = aTableStart.erase(aItr); + } + else + bReady = sal_True; + } +} + +sal_Bool ScMyOpenCloseColumnRowGroup::IsGroupEnd(const sal_Int32 nField) +{ + sal_Bool bGroupEnd(sal_False); + if (!aTableEnd.empty()) + { + if (*(aTableEnd.begin()) == nField) + bGroupEnd = sal_True; + } + return bGroupEnd; +} + +void ScMyOpenCloseColumnRowGroup::CloseGroup() +{ + rExport.EndElement( rName, sal_True ); +} + +void ScMyOpenCloseColumnRowGroup::CloseGroups(const sal_Int32 nField) +{ + ScMyFieldGroupVec::iterator aItr(aTableEnd.begin()); + ScMyFieldGroupVec::iterator aEndItr(aTableEnd.end()); + sal_Bool bReady(sal_False); + while(!bReady && aItr != aEndItr) + { + if (*aItr == nField) + { + CloseGroup(); + aItr = aTableEnd.erase(aItr); + } + else + bReady = sal_True; + } +} + +sal_Int32 ScMyOpenCloseColumnRowGroup::GetLast() +{ + sal_Int32 maximum(-1); + ScMyFieldGroupVec::iterator i(aTableEnd.begin()); + ScMyFieldGroupVec::iterator endi(aTableEnd.end()); + while (i != endi) + { + if (*i > maximum) + maximum = *i; + ++i; + } + return maximum; +} + +void ScMyOpenCloseColumnRowGroup::Sort() +{ + aTableStart.sort(); + aTableEnd.sort(); +} + diff --git a/sc/source/filter/xml/XMLColumnRowGroupExport.hxx b/sc/source/filter/xml/XMLColumnRowGroupExport.hxx new file mode 100644 index 000000000000..51a93445ccfb --- /dev/null +++ b/sc/source/filter/xml/XMLColumnRowGroupExport.hxx @@ -0,0 +1,73 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLCOLUMNROWGROUPEXPORT_HXX +#define SC_XMLCOLUMNROWGROUPEXPORT_HXX + +#include <list> +#include <rtl/ustring.hxx> +#include <sal/types.h> + +struct ScMyColumnRowGroup +{ + sal_Int32 nField; + sal_Int16 nLevel; + sal_Bool bDisplay; + + ScMyColumnRowGroup(); + sal_Bool operator< (const ScMyColumnRowGroup& rGroup) const; +}; + +typedef std::list <ScMyColumnRowGroup> ScMyColumnRowGroupVec; +typedef std::list <sal_Int32> ScMyFieldGroupVec; + +class ScXMLExport; +class ScMyOpenCloseColumnRowGroup +{ + ScXMLExport& rExport; + const rtl::OUString rName; + ScMyColumnRowGroupVec aTableStart; + ScMyFieldGroupVec aTableEnd; + + void OpenGroup(const ScMyColumnRowGroup& rGroup); + void CloseGroup(); +public: + ScMyOpenCloseColumnRowGroup(ScXMLExport& rExport, sal_uInt32 nToken); + ~ScMyOpenCloseColumnRowGroup(); + + void NewTable(); + void AddGroup(const ScMyColumnRowGroup& aGroup, const sal_Int32 nEndField); + sal_Bool IsGroupStart(const sal_Int32 nField); + void OpenGroups(const sal_Int32 nField); + sal_Bool IsGroupEnd(const sal_Int32 nField); + void CloseGroups(const sal_Int32 nField); + sal_Int32 GetLast(); + void Sort(); +}; + +#endif + diff --git a/sc/source/filter/xml/XMLConsolidationContext.cxx b/sc/source/filter/xml/XMLConsolidationContext.cxx new file mode 100644 index 000000000000..1f03d566ff18 --- /dev/null +++ b/sc/source/filter/xml/XMLConsolidationContext.cxx @@ -0,0 +1,160 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +//___________________________________________________________________ +#include "XMLConsolidationContext.hxx" +#include "document.hxx" +#include "rangeutl.hxx" +#include "xmlimprt.hxx" +#include "XMLConverter.hxx" +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmltoken.hxx> + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace xmloff::token; + + +//___________________________________________________________________ + +ScXMLConsolidationContext::ScXMLConsolidationContext( + ScXMLImport& rImport, + sal_uInt16 nPrfx, + const OUString& rLName, + const uno::Reference< xml::sax::XAttributeList >& xAttrList ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + eFunction( SUBTOTAL_FUNC_NONE ), + bLinkToSource( sal_False ), + bTargetAddr(sal_False) +{ + rImport.LockSolarMutex(); + if( !xAttrList.is() ) return; + + sal_Int16 nAttrCount = xAttrList->getLength(); + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetConsolidationAttrTokenMap(); + + for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex ) + { + const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex )); + const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex )); + OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_CONSOLIDATION_ATTR_FUNCTION: + eFunction = ScXMLConverter::GetSubTotalFuncFromString( sValue ); + break; + case XML_TOK_CONSOLIDATION_ATTR_SOURCE_RANGES: + sSourceList = sValue; + break; + case XML_TOK_CONSOLIDATION_ATTR_TARGET_ADDRESS: + { + sal_Int32 nOffset(0); + bTargetAddr = ScRangeStringConverter::GetAddressFromString( + aTargetAddr, sValue, GetScImport().GetDocument(), ::formula::FormulaGrammar::CONV_OOO, nOffset ); + } + break; + case XML_TOK_CONSOLIDATION_ATTR_USE_LABEL: + sUseLabel = sValue; + break; + case XML_TOK_CONSOLIDATION_ATTR_LINK_TO_SOURCE: + bLinkToSource = IsXMLToken(sValue, XML_TRUE); + break; + } + } +} + +ScXMLConsolidationContext::~ScXMLConsolidationContext() +{ +} + +SvXMLImportContext *ScXMLConsolidationContext::CreateChildContext( + sal_uInt16 nPrefix, + const OUString& rLName, + const uno::Reference< xml::sax::XAttributeList>& /* xAttrList */ ) +{ + return new SvXMLImportContext( GetImport(), nPrefix, rLName ); +} + +void ScXMLConsolidationContext::EndElement() +{ + if (bTargetAddr) + { + ScConsolidateParam aConsParam; + aConsParam.nCol = aTargetAddr.Col(); + aConsParam.nRow = aTargetAddr.Row(); + aConsParam.nTab = aTargetAddr.Tab(); + aConsParam.eFunction = eFunction; + + sal_Bool bError = sal_False; + sal_uInt16 nCount = (sal_uInt16) Min( ScRangeStringConverter::GetTokenCount( sSourceList ), (sal_Int32)0xFFFF ); + ScArea** ppAreas = nCount ? new ScArea*[ nCount ] : NULL; + if( ppAreas ) + { + sal_Int32 nOffset = 0; + sal_uInt16 nIndex; + for( nIndex = 0; nIndex < nCount; ++nIndex ) + { + ppAreas[ nIndex ] = new ScArea; + if ( !ScRangeStringConverter::GetAreaFromString( + *ppAreas[ nIndex ], sSourceList, GetScImport().GetDocument(), ::formula::FormulaGrammar::CONV_OOO, nOffset ) ) + { + bError = sal_True; //! handle error + } + } + + aConsParam.SetAreas( ppAreas, nCount ); + + // array is copied in SetAreas + for( nIndex = 0; nIndex < nCount; ++nIndex ) + delete ppAreas[nIndex]; + delete[] ppAreas; + } + + aConsParam.bByCol = aConsParam.bByRow = sal_False; + if( IsXMLToken(sUseLabel, XML_COLUMN ) ) + aConsParam.bByCol = sal_True; + else if( IsXMLToken( sUseLabel, XML_ROW ) ) + aConsParam.bByRow = sal_True; + else if( IsXMLToken( sUseLabel, XML_BOTH ) ) + aConsParam.bByCol = aConsParam.bByRow = sal_True; + + aConsParam.bReferenceData = bLinkToSource; + + ScDocument* pDoc = GetScImport().GetDocument(); + if( pDoc ) + pDoc->SetConsolidateDlgData( &aConsParam ); + } + GetScImport().UnlockSolarMutex(); +} + diff --git a/sc/source/filter/xml/XMLConsolidationContext.hxx b/sc/source/filter/xml/XMLConsolidationContext.hxx new file mode 100644 index 000000000000..76249bf4cfab --- /dev/null +++ b/sc/source/filter/xml/XMLConsolidationContext.hxx @@ -0,0 +1,73 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLCONSOLIDATIONCONTEXT_HXX +#define SC_XMLCONSOLIDATIONCONTEXT_HXX + +#include "global.hxx" +#include "address.hxx" +#include <xmloff/xmlimp.hxx> + +class ScXMLImport; + + +//___________________________________________________________________ + +class ScXMLConsolidationContext : public SvXMLImportContext +{ +private: + ::rtl::OUString sSourceList; + ::rtl::OUString sUseLabel; + ScAddress aTargetAddr; + ScSubTotalFunc eFunction; + sal_Bool bLinkToSource; + sal_Bool bTargetAddr; + +protected: + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLConsolidationContext( + ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList + ); + virtual ~ScXMLConsolidationContext(); + + virtual SvXMLImportContext* CreateChildContext( + sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList + ); + virtual void EndElement(); +}; + + +#endif + diff --git a/sc/source/filter/xml/XMLConverter.cxx b/sc/source/filter/xml/XMLConverter.cxx new file mode 100644 index 000000000000..4de6246f4f28 --- /dev/null +++ b/sc/source/filter/xml/XMLConverter.cxx @@ -0,0 +1,670 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +#include "XMLConverter.hxx" +#include <com/sun/star/util/DateTime.hpp> +#include <tools/datetime.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmluconv.hxx> +#include "rangelst.hxx" +#include "rangeutl.hxx" +#include "docuno.hxx" +#include "convuno.hxx" +#include "document.hxx" +#include "ftools.hxx" + +using ::rtl::OUString; +using ::rtl::OUStringBuffer; +using namespace ::com::sun::star; +using namespace xmloff::token; + + +//___________________________________________________________________ + +ScDocument* ScXMLConverter::GetScDocument( uno::Reference< frame::XModel > xModel ) +{ + if (xModel.is()) + { + ScModelObj* pDocObj = ScModelObj::getImplementation( xModel ); + return pDocObj ? pDocObj->GetDocument() : NULL; + } + return NULL; +} + + +//___________________________________________________________________ +sheet::GeneralFunction ScXMLConverter::GetFunctionFromString( const OUString& sFunction ) +{ + if( IsXMLToken(sFunction, XML_SUM ) ) + return sheet::GeneralFunction_SUM; + if( IsXMLToken(sFunction, XML_AUTO ) ) + return sheet::GeneralFunction_AUTO; + if( IsXMLToken(sFunction, XML_COUNT ) ) + return sheet::GeneralFunction_COUNT; + if( IsXMLToken(sFunction, XML_COUNTNUMS ) ) + return sheet::GeneralFunction_COUNTNUMS; + if( IsXMLToken(sFunction, XML_PRODUCT ) ) + return sheet::GeneralFunction_PRODUCT; + if( IsXMLToken(sFunction, XML_AVERAGE ) ) + return sheet::GeneralFunction_AVERAGE; + if( IsXMLToken(sFunction, XML_MAX ) ) + return sheet::GeneralFunction_MAX; + if( IsXMLToken(sFunction, XML_MIN ) ) + return sheet::GeneralFunction_MIN; + if( IsXMLToken(sFunction, XML_STDEV ) ) + return sheet::GeneralFunction_STDEV; + if( IsXMLToken(sFunction, XML_STDEVP ) ) + return sheet::GeneralFunction_STDEVP; + if( IsXMLToken(sFunction, XML_VAR ) ) + return sheet::GeneralFunction_VAR; + if( IsXMLToken(sFunction, XML_VARP ) ) + return sheet::GeneralFunction_VARP; + return sheet::GeneralFunction_NONE; +} + +ScSubTotalFunc ScXMLConverter::GetSubTotalFuncFromString( const OUString& sFunction ) +{ + if( IsXMLToken(sFunction, XML_SUM ) ) + return SUBTOTAL_FUNC_SUM; + if( IsXMLToken(sFunction, XML_COUNT ) ) + return SUBTOTAL_FUNC_CNT; + if( IsXMLToken(sFunction, XML_COUNTNUMS ) ) + return SUBTOTAL_FUNC_CNT2; + if( IsXMLToken(sFunction, XML_PRODUCT ) ) + return SUBTOTAL_FUNC_PROD; + if( IsXMLToken(sFunction, XML_AVERAGE ) ) + return SUBTOTAL_FUNC_AVE; + if( IsXMLToken(sFunction, XML_MAX ) ) + return SUBTOTAL_FUNC_MAX; + if( IsXMLToken(sFunction, XML_MIN ) ) + return SUBTOTAL_FUNC_MIN; + if( IsXMLToken(sFunction, XML_STDEV ) ) + return SUBTOTAL_FUNC_STD; + if( IsXMLToken(sFunction, XML_STDEVP ) ) + return SUBTOTAL_FUNC_STDP; + if( IsXMLToken(sFunction, XML_VAR ) ) + return SUBTOTAL_FUNC_VAR; + if( IsXMLToken(sFunction, XML_VARP ) ) + return SUBTOTAL_FUNC_VARP; + return SUBTOTAL_FUNC_NONE; +} + + +//___________________________________________________________________ + +void ScXMLConverter::GetStringFromFunction( + OUString& rString, + const sheet::GeneralFunction eFunction, + sal_Bool bAppendStr ) +{ + OUString sFuncStr; + switch( eFunction ) + { + case sheet::GeneralFunction_AUTO: sFuncStr = GetXMLToken( XML_AUTO ); break; + case sheet::GeneralFunction_AVERAGE: sFuncStr = GetXMLToken( XML_AVERAGE ); break; + case sheet::GeneralFunction_COUNT: sFuncStr = GetXMLToken( XML_COUNT ); break; + case sheet::GeneralFunction_COUNTNUMS: sFuncStr = GetXMLToken( XML_COUNTNUMS ); break; + case sheet::GeneralFunction_MAX: sFuncStr = GetXMLToken( XML_MAX ); break; + case sheet::GeneralFunction_MIN: sFuncStr = GetXMLToken( XML_MIN ); break; + case sheet::GeneralFunction_NONE: sFuncStr = GetXMLToken( XML_NONE ); break; + case sheet::GeneralFunction_PRODUCT: sFuncStr = GetXMLToken( XML_PRODUCT ); break; + case sheet::GeneralFunction_STDEV: sFuncStr = GetXMLToken( XML_STDEV ); break; + case sheet::GeneralFunction_STDEVP: sFuncStr = GetXMLToken( XML_STDEVP ); break; + case sheet::GeneralFunction_SUM: sFuncStr = GetXMLToken( XML_SUM ); break; + case sheet::GeneralFunction_VAR: sFuncStr = GetXMLToken( XML_VAR ); break; + case sheet::GeneralFunction_VARP: sFuncStr = GetXMLToken( XML_VARP ); break; + default: + { + // added to avoid warnings + } + } + ScRangeStringConverter::AssignString( rString, sFuncStr, bAppendStr ); +} + +void ScXMLConverter::GetStringFromFunction( + OUString& rString, + const ScSubTotalFunc eFunction, + sal_Bool bAppendStr ) +{ + OUString sFuncStr; + switch( eFunction ) + { + case SUBTOTAL_FUNC_AVE: sFuncStr = GetXMLToken( XML_AVERAGE ); break; + case SUBTOTAL_FUNC_CNT: sFuncStr = GetXMLToken( XML_COUNT ); break; + case SUBTOTAL_FUNC_CNT2: sFuncStr = GetXMLToken( XML_COUNTNUMS ); break; + case SUBTOTAL_FUNC_MAX: sFuncStr = GetXMLToken( XML_MAX ); break; + case SUBTOTAL_FUNC_MIN: sFuncStr = GetXMLToken( XML_MIN ); break; + case SUBTOTAL_FUNC_NONE: sFuncStr = GetXMLToken( XML_NONE ); break; + case SUBTOTAL_FUNC_PROD: sFuncStr = GetXMLToken( XML_PRODUCT ); break; + case SUBTOTAL_FUNC_STD: sFuncStr = GetXMLToken( XML_STDEV ); break; + case SUBTOTAL_FUNC_STDP: sFuncStr = GetXMLToken( XML_STDEVP ); break; + case SUBTOTAL_FUNC_SUM: sFuncStr = GetXMLToken( XML_SUM ); break; + case SUBTOTAL_FUNC_VAR: sFuncStr = GetXMLToken( XML_VAR ); break; + case SUBTOTAL_FUNC_VARP: sFuncStr = GetXMLToken( XML_VARP ); break; + } + ScRangeStringConverter::AssignString( rString, sFuncStr, bAppendStr ); +} + + +//___________________________________________________________________ + +sheet::DataPilotFieldOrientation ScXMLConverter::GetOrientationFromString( + const OUString& rString ) +{ + if( IsXMLToken(rString, XML_COLUMN ) ) + return sheet::DataPilotFieldOrientation_COLUMN; + if( IsXMLToken(rString, XML_ROW ) ) + return sheet::DataPilotFieldOrientation_ROW; + if( IsXMLToken(rString, XML_PAGE ) ) + return sheet::DataPilotFieldOrientation_PAGE; + if( IsXMLToken(rString, XML_DATA ) ) + return sheet::DataPilotFieldOrientation_DATA; + return sheet::DataPilotFieldOrientation_HIDDEN; +} + + +//___________________________________________________________________ + +void ScXMLConverter::GetStringFromOrientation( + OUString& rString, + const sheet::DataPilotFieldOrientation eOrientation, + sal_Bool bAppendStr ) +{ + OUString sOrientStr; + switch( eOrientation ) + { + case sheet::DataPilotFieldOrientation_HIDDEN: + sOrientStr = GetXMLToken( XML_HIDDEN ); + break; + case sheet::DataPilotFieldOrientation_COLUMN: + sOrientStr = GetXMLToken( XML_COLUMN ); + break; + case sheet::DataPilotFieldOrientation_ROW: + sOrientStr = GetXMLToken( XML_ROW ); + break; + case sheet::DataPilotFieldOrientation_PAGE: + sOrientStr = GetXMLToken( XML_PAGE ); + break; + case sheet::DataPilotFieldOrientation_DATA: + sOrientStr = GetXMLToken( XML_DATA ); + break; + default: + { + // added to avoid warnings + } + } + ScRangeStringConverter::AssignString( rString, sOrientStr, bAppendStr ); +} + + +//___________________________________________________________________ + +ScDetectiveObjType ScXMLConverter::GetDetObjTypeFromString( const OUString& rString ) +{ + if( IsXMLToken(rString, XML_FROM_SAME_TABLE ) ) + return SC_DETOBJ_ARROW; + if( IsXMLToken(rString, XML_FROM_ANOTHER_TABLE ) ) + return SC_DETOBJ_FROMOTHERTAB; + if( IsXMLToken(rString, XML_TO_ANOTHER_TABLE ) ) + return SC_DETOBJ_TOOTHERTAB; + return SC_DETOBJ_NONE; +} + +sal_Bool ScXMLConverter::GetDetOpTypeFromString( ScDetOpType& rDetOpType, const OUString& rString ) +{ + if( IsXMLToken(rString, XML_TRACE_DEPENDENTS ) ) + rDetOpType = SCDETOP_ADDSUCC; + else if( IsXMLToken(rString, XML_TRACE_PRECEDENTS ) ) + rDetOpType = SCDETOP_ADDPRED; + else if( IsXMLToken(rString, XML_TRACE_ERRORS ) ) + rDetOpType = SCDETOP_ADDERROR; + else if( IsXMLToken(rString, XML_REMOVE_DEPENDENTS ) ) + rDetOpType = SCDETOP_DELSUCC; + else if( IsXMLToken(rString, XML_REMOVE_PRECEDENTS ) ) + rDetOpType = SCDETOP_DELPRED; + else + return sal_False; + return sal_True; +} + + +//___________________________________________________________________ + +void ScXMLConverter::GetStringFromDetObjType( + OUString& rString, + const ScDetectiveObjType eObjType, + sal_Bool bAppendStr ) +{ + OUString sTypeStr; + switch( eObjType ) + { + case SC_DETOBJ_ARROW: + sTypeStr = GetXMLToken( XML_FROM_SAME_TABLE ); + break; + case SC_DETOBJ_FROMOTHERTAB: + sTypeStr = GetXMLToken( XML_FROM_ANOTHER_TABLE ); + break; + case SC_DETOBJ_TOOTHERTAB: + sTypeStr = GetXMLToken( XML_TO_ANOTHER_TABLE ); + break; + default: + { + // added to avoid warnings + } + } + ScRangeStringConverter::AssignString( rString, sTypeStr, bAppendStr ); +} + +void ScXMLConverter::GetStringFromDetOpType( + OUString& rString, + const ScDetOpType eOpType, + sal_Bool bAppendStr ) +{ + OUString sTypeStr; + switch( eOpType ) + { + case SCDETOP_ADDSUCC: + sTypeStr = GetXMLToken( XML_TRACE_DEPENDENTS ); + break; + case SCDETOP_ADDPRED: + sTypeStr = GetXMLToken( XML_TRACE_PRECEDENTS ); + break; + case SCDETOP_ADDERROR: + sTypeStr = GetXMLToken( XML_TRACE_ERRORS ); + break; + case SCDETOP_DELSUCC: + sTypeStr = GetXMLToken( XML_REMOVE_DEPENDENTS ); + break; + case SCDETOP_DELPRED: + sTypeStr = GetXMLToken( XML_REMOVE_PRECEDENTS ); + break; + } + ScRangeStringConverter::AssignString( rString, sTypeStr, bAppendStr ); +} + + +//___________________________________________________________________ + +void ScXMLConverter::ParseFormula(OUString& sFormula, const sal_Bool bIsFormula) +{ + OUStringBuffer sBuffer(sFormula.getLength()); + sal_Bool bInQuotationMarks(sal_False); + sal_Bool bInDoubleQuotationMarks(sal_False); + sal_Int16 nCountBraces(0); + sal_Unicode chPrevious('='); + for (sal_Int32 i = 0; i < sFormula.getLength(); ++i) + { + if (sFormula[i] == '\'' && !bInDoubleQuotationMarks && + chPrevious != '\\') + bInQuotationMarks = !bInQuotationMarks; + else if (sFormula[i] == '"' && !bInQuotationMarks) + bInDoubleQuotationMarks = !bInDoubleQuotationMarks; + if (bInQuotationMarks || bInDoubleQuotationMarks) + sBuffer.append(sFormula[i]); + else if (sFormula[i] == '[') + ++nCountBraces; + else if (sFormula[i] == ']') + nCountBraces--; + else if ((sFormula[i] != '.') || + ((nCountBraces == 0) && bIsFormula) || + !((chPrevious == '[') || (chPrevious == ':') || (chPrevious == ' ') || (chPrevious == '='))) + sBuffer.append(sFormula[i]); + chPrevious = sFormula[i]; + } + + DBG_ASSERT(nCountBraces == 0, "there are some braces still open"); + sFormula = sBuffer.makeStringAndClear(); +} + + +//_____________________________________________________________________ + +void ScXMLConverter::ConvertDateTimeToString(const DateTime& aDateTime, rtl::OUStringBuffer& sDate) +{ + util::DateTime aAPIDateTime; + ConvertCoreToAPIDateTime(aDateTime, aAPIDateTime); + SvXMLUnitConverter::convertDateTime(sDate, aAPIDateTime); +} + +//UNUSED2008-05 void ScXMLConverter::ConvertStringToDateTime(const rtl::OUString& sDate, DateTime& aDateTime, SvXMLUnitConverter* /* pUnitConverter */) +//UNUSED2008-05 { +//UNUSED2008-05 com::sun::star::util::DateTime aAPIDateTime; +//UNUSED2008-05 SvXMLUnitConverter::convertDateTime(aAPIDateTime, sDate); +//UNUSED2008-05 ConvertAPIToCoreDateTime(aAPIDateTime, aDateTime); +//UNUSED2008-05 } + +void ScXMLConverter::ConvertCoreToAPIDateTime(const DateTime& aDateTime, util::DateTime& rDateTime) +{ + rDateTime.Year = aDateTime.GetYear(); + rDateTime.Month = aDateTime.GetMonth(); + rDateTime.Day = aDateTime.GetDay(); + rDateTime.Hours = aDateTime.GetHour(); + rDateTime.Minutes = aDateTime.GetMin(); + rDateTime.Seconds = aDateTime.GetSec(); + rDateTime.HundredthSeconds = aDateTime.Get100Sec(); +} + +void ScXMLConverter::ConvertAPIToCoreDateTime(const util::DateTime& aDateTime, DateTime& rDateTime) +{ + Date aDate(aDateTime.Day, aDateTime.Month, aDateTime.Year); + Time aTime(aDateTime.Hours, aDateTime.Minutes, aDateTime.Seconds, aDateTime.HundredthSeconds); + DateTime aTempDateTime (aDate, aTime); + rDateTime = aTempDateTime; +} + +// ============================================================================ + +namespace { + +/** Enumerates different types of condition tokens. */ +enum ScXMLConditionTokenType +{ + XML_COND_TYPE_KEYWORD, /// Simple keyword without parentheses, e.g. 'and'. + XML_COND_TYPE_COMPARISON, /// Comparison rule, e.g. 'cell-content()<=2'. + XML_COND_TYPE_FUNCTION0, /// Function without parameters, e.g. 'cell-content-is-whole-number()'. + XML_COND_TYPE_FUNCTION1, /// Function with 1 parameter, e.g. 'is-true-formula(1+1=2)'. + XML_COND_TYPE_FUNCTION2 /// Function with 2 parameters, e.g. 'cell-content-is-between(1,2)'. +}; + +struct ScXMLConditionInfo +{ + ScXMLConditionToken meToken; + ScXMLConditionTokenType meType; + sheet::ValidationType meValidation; + sheet::ConditionOperator meOperator; + const sal_Char* mpcIdentifier; + sal_Int32 mnIdentLength; +}; + +static const ScXMLConditionInfo spConditionInfos[] = +{ + { XML_COND_AND, XML_COND_TYPE_KEYWORD, sheet::ValidationType_ANY, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM( "and" ) }, + { XML_COND_CELLCONTENT, XML_COND_TYPE_COMPARISON, sheet::ValidationType_ANY, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM( "cell-content" ) }, + { XML_COND_ISBETWEEN, XML_COND_TYPE_FUNCTION2, sheet::ValidationType_ANY, sheet::ConditionOperator_BETWEEN, RTL_CONSTASCII_STRINGPARAM( "cell-content-is-between" ) }, + { XML_COND_ISNOTBETWEEN, XML_COND_TYPE_FUNCTION2, sheet::ValidationType_ANY, sheet::ConditionOperator_NOT_BETWEEN, RTL_CONSTASCII_STRINGPARAM( "cell-content-is-not-between" ) }, + { XML_COND_ISWHOLENUMBER, XML_COND_TYPE_FUNCTION0, sheet::ValidationType_WHOLE, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM( "cell-content-is-whole-number" ) }, + { XML_COND_ISDECIMALNUMBER, XML_COND_TYPE_FUNCTION0, sheet::ValidationType_DECIMAL, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM( "cell-content-is-decimal-number" ) }, + { XML_COND_ISDATE, XML_COND_TYPE_FUNCTION0, sheet::ValidationType_DATE, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM( "cell-content-is-date" ) }, + { XML_COND_ISTIME, XML_COND_TYPE_FUNCTION0, sheet::ValidationType_TIME, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM( "cell-content-is-time" ) }, + { XML_COND_ISINLIST, XML_COND_TYPE_FUNCTION1, sheet::ValidationType_LIST, sheet::ConditionOperator_EQUAL, RTL_CONSTASCII_STRINGPARAM( "cell-content-is-in-list" ) }, + { XML_COND_TEXTLENGTH, XML_COND_TYPE_COMPARISON, sheet::ValidationType_TEXT_LEN, sheet::ConditionOperator_NONE, RTL_CONSTASCII_STRINGPARAM( "cell-content-text-length" ) }, + { XML_COND_TEXTLENGTH_ISBETWEEN, XML_COND_TYPE_FUNCTION2, sheet::ValidationType_TEXT_LEN, sheet::ConditionOperator_BETWEEN, RTL_CONSTASCII_STRINGPARAM( "cell-content-text-length-is-between" ) }, + { XML_COND_TEXTLENGTH_ISNOTBETWEEN, XML_COND_TYPE_FUNCTION2, sheet::ValidationType_TEXT_LEN, sheet::ConditionOperator_NOT_BETWEEN, RTL_CONSTASCII_STRINGPARAM( "cell-content-text-length-is-not-between" ) }, + { XML_COND_ISTRUEFORMULA, XML_COND_TYPE_FUNCTION1, sheet::ValidationType_CUSTOM, sheet::ConditionOperator_FORMULA, RTL_CONSTASCII_STRINGPARAM( "is-true-formula" ) } +}; + +void lclSkipWhitespace( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd ) +{ + while( (rpcString < pcEnd) && (*rpcString <= ' ') ) ++rpcString; +} + +const ScXMLConditionInfo* lclGetConditionInfo( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd ) +{ + lclSkipWhitespace( rpcString, pcEnd ); + /* Search the end of an identifier name; assuming that valid identifiers + consist of [a-z-] only. */ + const sal_Unicode* pcIdStart = rpcString; + while( (rpcString < pcEnd) && (((*rpcString >= 'a') && (*rpcString <= 'z')) || (*rpcString == '-')) ) ++rpcString; + sal_Int32 nLength = static_cast< sal_Int32 >( rpcString - pcIdStart ); + + // search the table for an entry + if( nLength > 0 ) + for( const ScXMLConditionInfo* pInfo = spConditionInfos; pInfo < STATIC_TABLE_END( spConditionInfos ); ++pInfo ) + if( (nLength == pInfo->mnIdentLength) && (::rtl_ustr_ascii_shortenedCompare_WithLength( pcIdStart, nLength, pInfo->mpcIdentifier, nLength ) == 0) ) + return pInfo; + + return 0; +} + +sheet::ConditionOperator lclGetConditionOperator( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd ) +{ + // check for double-char operators + if( (rpcString + 1 < pcEnd) && (rpcString[ 1 ] == '=') ) + { + sheet::ConditionOperator eOperator = sheet::ConditionOperator_NONE; + switch( *rpcString ) + { + case '!': eOperator = sheet::ConditionOperator_NOT_EQUAL; break; + case '<': eOperator = sheet::ConditionOperator_LESS_EQUAL; break; + case '>': eOperator = sheet::ConditionOperator_GREATER_EQUAL; break; + } + if( eOperator != sheet::ConditionOperator_NONE ) + { + rpcString += 2; + return eOperator; + } + } + + // check for single-char operators + if( rpcString < pcEnd ) + { + sheet::ConditionOperator eOperator = sheet::ConditionOperator_NONE; + switch( *rpcString ) + { + case '=': eOperator = sheet::ConditionOperator_EQUAL; break; + case '<': eOperator = sheet::ConditionOperator_LESS; break; + case '>': eOperator = sheet::ConditionOperator_GREATER; break; + } + if( eOperator != sheet::ConditionOperator_NONE ) + { + ++rpcString; + return eOperator; + } + } + + return sheet::ConditionOperator_NONE; +} + +/** Skips a literal string in a formula expression. + + @param rpcString + (in-out) On call, must point to the first character of the string + following the leading string delimiter character. On return, points to + the trailing string delimiter character if existing, otherwise to + pcEnd. + + @param pcEnd + The end of the string to parse. + + @param cQuoteChar + The string delimiter character enclosing the string. + */ +void lclSkipExpressionString( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd, sal_Unicode cQuoteChar ) +{ + if( rpcString < pcEnd ) + { + sal_Int32 nLength = static_cast< sal_Int32 >( pcEnd - rpcString ); + sal_Int32 nNextQuote = ::rtl_ustr_indexOfChar_WithLength( rpcString, nLength, cQuoteChar ); + if( nNextQuote >= 0 ) + rpcString += nNextQuote; + else + rpcString = pcEnd; + } +} + +/** Skips a formula expression. Processes embedded parentheses, braces, and + literal strings. + + @param rpcString + (in-out) On call, must point to the first character of the expression. + On return, points to the passed end character if existing, otherwise to + pcEnd. + + @param pcEnd + The end of the string to parse. + + @param cEndChar + The termination character following the expression. + */ +void lclSkipExpression( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd, sal_Unicode cEndChar ) +{ + while( rpcString < pcEnd ) + { + if( *rpcString == cEndChar ) + return; + switch( *rpcString ) + { + case '(': lclSkipExpression( ++rpcString, pcEnd, ')' ); break; + case '{': lclSkipExpression( ++rpcString, pcEnd, '}' ); break; + case '"': lclSkipExpressionString( ++rpcString, pcEnd, '"' ); break; + case '\'': lclSkipExpressionString( ++rpcString, pcEnd, '\'' ); break; + } + if( rpcString < pcEnd ) ++rpcString; + } +} + +/** Extracts a formula expression. Processes embedded parentheses, braces, and + literal strings. + + @param rpcString + (in-out) On call, must point to the first character of the expression. + On return, points *behind* the passed end character if existing, + otherwise to pcEnd. + + @param pcEnd + The end of the string to parse. + + @param cEndChar + The termination character following the expression. + */ +OUString lclGetExpression( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd, sal_Unicode cEndChar ) +{ + OUString aExp; + const sal_Unicode* pcExpStart = rpcString; + lclSkipExpression( rpcString, pcEnd, cEndChar ); + if( rpcString < pcEnd ) + { + aExp = OUString( pcExpStart, static_cast< sal_Int32 >( rpcString - pcExpStart ) ).trim(); + ++rpcString; + } + return aExp; +} + +/** Tries to skip an empty pair of parentheses (which may contain whitespace + characters). + + @return + True on success, rpcString points behind the closing parentheses then. + */ +bool lclSkipEmptyParentheses( const sal_Unicode*& rpcString, const sal_Unicode* pcEnd ) +{ + if( (rpcString < pcEnd) && (*rpcString == '(') ) + { + lclSkipWhitespace( ++rpcString, pcEnd ); + if( (rpcString < pcEnd) && (*rpcString == ')') ) + { + ++rpcString; + return true; + } + } + return false; +} + +} // namespace + +// ---------------------------------------------------------------------------- + +/*static*/ void ScXMLConditionHelper::parseCondition( + ScXMLConditionParseResult& rParseResult, const OUString& rAttribute, sal_Int32 nStartIndex ) +{ + rParseResult.meToken = XML_COND_INVALID; + if( (nStartIndex < 0) || (nStartIndex >= rAttribute.getLength()) ) return; + + // try to find an identifier + const sal_Unicode* pcBegin = rAttribute.getStr(); + const sal_Unicode* pcString = pcBegin + nStartIndex; + const sal_Unicode* pcEnd = pcBegin + rAttribute.getLength(); + if( const ScXMLConditionInfo* pCondInfo = lclGetConditionInfo( pcString, pcEnd ) ) + { + // insert default values into parse result (may be changed below) + rParseResult.meValidation = pCondInfo->meValidation; + rParseResult.meOperator = pCondInfo->meOperator; + // continue parsing dependent on token type + switch( pCondInfo->meType ) + { + case XML_COND_TYPE_KEYWORD: + // nothing specific has to follow, success + rParseResult.meToken = pCondInfo->meToken; + break; + + case XML_COND_TYPE_COMPARISON: + // format is <condition>()<operator><expression> + if( lclSkipEmptyParentheses( pcString, pcEnd ) ) + { + rParseResult.meOperator = lclGetConditionOperator( pcString, pcEnd ); + if( rParseResult.meOperator != sheet::ConditionOperator_NONE ) + { + lclSkipWhitespace( pcString, pcEnd ); + if( pcString < pcEnd ) + { + rParseResult.meToken = pCondInfo->meToken; + // comparison must be at end of attribute, remaining text is the formula + rParseResult.maOperand1 = OUString( pcString, static_cast< sal_Int32 >( pcEnd - pcString ) ); + } + } + } + break; + + case XML_COND_TYPE_FUNCTION0: + // format is <condition>() + if( lclSkipEmptyParentheses( pcString, pcEnd ) ) + rParseResult.meToken = pCondInfo->meToken; + break; + + case XML_COND_TYPE_FUNCTION1: + // format is <condition>(<expression>) + if( (pcString < pcEnd) && (*pcString == '(') ) + { + rParseResult.maOperand1 = lclGetExpression( ++pcString, pcEnd, ')' ); + if( rParseResult.maOperand1.getLength() > 0 ) + rParseResult.meToken = pCondInfo->meToken; + } + break; + + case XML_COND_TYPE_FUNCTION2: + // format is <condition>(<expression1>,<expression2>) + if( (pcString < pcEnd) && (*pcString == '(') ) + { + rParseResult.maOperand1 = lclGetExpression( ++pcString, pcEnd, ',' ); + if( rParseResult.maOperand1.getLength() > 0 ) + { + rParseResult.maOperand2 = lclGetExpression( pcString, pcEnd, ')' ); + if( rParseResult.maOperand2.getLength() > 0 ) + rParseResult.meToken = pCondInfo->meToken; + } + } + break; + } + rParseResult.mnEndIndex = static_cast< sal_Int32 >( pcString - pcBegin ); + } +} + +// ============================================================================ + diff --git a/sc/source/filter/xml/XMLConverter.hxx b/sc/source/filter/xml/XMLConverter.hxx new file mode 100644 index 000000000000..94766ebe08ff --- /dev/null +++ b/sc/source/filter/xml/XMLConverter.hxx @@ -0,0 +1,177 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLCONVERTER_HXX +#define SC_XMLCONVERTER_HXX + +#include "global.hxx" +#include "detfunc.hxx" +#include "detdata.hxx" +#include <rtl/ustrbuf.hxx> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/sheet/ConditionOperator.hpp> +#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp> +#include <com/sun/star/sheet/GeneralFunction.hpp> +#include <com/sun/star/sheet/ValidationType.hpp> +#include <com/sun/star/util/DateTime.hpp> + +class ScDocument; +class DateTime; +class SvXMLUnitConverter; + + +//___________________________________________________________________ + +class ScXMLConverter +{ +public: + inline ScXMLConverter() {} + inline ~ScXMLConverter() {} + +// helper methods + static ScDocument* GetScDocument( + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > xModel ); + +// IMPORT: GeneralFunction / ScSubTotalFunc + static ::com::sun::star::sheet::GeneralFunction + GetFunctionFromString( + const ::rtl::OUString& rString ); + static ScSubTotalFunc GetSubTotalFuncFromString( + const ::rtl::OUString& rString ); + +// EXPORT: GeneralFunction / ScSubTotalFunc + static void GetStringFromFunction( + ::rtl::OUString& rString, + const ::com::sun::star::sheet::GeneralFunction eFunction, + sal_Bool bAppendStr = sal_False ); + static void GetStringFromFunction( + ::rtl::OUString& rString, + const ScSubTotalFunc eFunction, + sal_Bool bAppendStr = sal_False ); + +// IMPORT: DataPilotFieldOrientation + static ::com::sun::star::sheet::DataPilotFieldOrientation + GetOrientationFromString( + const ::rtl::OUString& rString ); + +// EXPORT: DataPilotFieldOrientation + static void GetStringFromOrientation( + ::rtl::OUString& rString, + const ::com::sun::star::sheet::DataPilotFieldOrientation eOrientation, + sal_Bool bAppendStr = sal_False ); + +// IMPORT: Detective + static ScDetectiveObjType + GetDetObjTypeFromString( + const ::rtl::OUString& rString ); + static sal_Bool GetDetOpTypeFromString( + ScDetOpType& rDetOpType, + const ::rtl::OUString& rString ); + +// EXPORT: Detective + static void GetStringFromDetObjType( + ::rtl::OUString& rString, + const ScDetectiveObjType eObjType, + sal_Bool bAppendStr = sal_False ); + static void GetStringFromDetOpType( + ::rtl::OUString& rString, + const ScDetOpType eOpType, + sal_Bool bAppendStr = sal_False ); + +// IMPORT: Formulas + static void ParseFormula( + ::rtl::OUString& sFormula, + const sal_Bool bIsFormula = sal_True); +// EXPORT: Core Date Time + static void ConvertDateTimeToString(const DateTime& aDateTime, rtl::OUStringBuffer& sDate); +//UNUSED2008-05 // IMPORT: Core Date Time +//UNUSED2008-05 static void ConvertStringToDateTime(const rtl::OUString& sDate, DateTime& aDateTime, SvXMLUnitConverter* pUnitConverter); + + static void ConvertCoreToAPIDateTime(const DateTime& aDateTime, com::sun::star::util::DateTime& rDateTime); + + static void ConvertAPIToCoreDateTime(const com::sun::star::util::DateTime& aDateTime, DateTime& rDateTime); +}; + +// ============================================================================ + +enum ScXMLConditionToken +{ + XML_COND_INVALID, /// Token not recognized. + XML_COND_AND, /// The 'and' token. + XML_COND_CELLCONTENT, /// The 'cell-content' token. + XML_COND_ISBETWEEN, /// The 'cell-content-is-between' token. + XML_COND_ISNOTBETWEEN, /// The 'cell-content-is-not-between' token. + XML_COND_ISWHOLENUMBER, /// The 'cell-content-is-whole-number' token. + XML_COND_ISDECIMALNUMBER, /// The 'cell-content-is-decimal-number' token. + XML_COND_ISDATE, /// The 'cell-content-is-date' token. + XML_COND_ISTIME, /// The 'cell-content-is-time' token. + XML_COND_ISINLIST, /// The 'cell-content-is-in-list' token. + XML_COND_TEXTLENGTH, /// The 'cell-content-text-length' token. + XML_COND_TEXTLENGTH_ISBETWEEN, /// The 'cell-content-text-length-is-between' token. + XML_COND_TEXTLENGTH_ISNOTBETWEEN, /// The 'cell-content-text-length-is-not-between' token. + XML_COND_ISTRUEFORMULA /// The 'is-true-formula' token. +}; + +// ---------------------------------------------------------------------------- + +/** Result of an attempt to parse a single condition in a 'condition' attribute + value of e.g. conditional formatting or data validation. + */ +struct ScXMLConditionParseResult +{ + ScXMLConditionToken meToken; /// The leading condition token. + ::com::sun::star::sheet::ValidationType + meValidation; /// A data validation type if existing. + ::com::sun::star::sheet::ConditionOperator + meOperator; /// A comparison operator if existing. + ::rtl::OUString maOperand1; /// First operand of the token or comparison value. + ::rtl::OUString maOperand2; /// Second operand of 'between' conditions. + sal_Int32 mnEndIndex; /// Index of first character following the condition. +}; + +// ---------------------------------------------------------------------------- + +class ScXMLConditionHelper +{ +public: + /** Parses the next condition in a 'condition' attribute value of e.g. + conditional formatting or data validation. + */ + static void parseCondition( + ScXMLConditionParseResult& rParseResult, + const ::rtl::OUString& rAttribute, + sal_Int32 nStartIndex ); + +private: + ScXMLConditionHelper(); + ~ScXMLConditionHelper(); +}; + +// ============================================================================ + +#endif + diff --git a/sc/source/filter/xml/XMLDDELinksContext.cxx b/sc/source/filter/xml/XMLDDELinksContext.cxx new file mode 100644 index 000000000000..29f4cb7b7594 --- /dev/null +++ b/sc/source/filter/xml/XMLDDELinksContext.cxx @@ -0,0 +1,490 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- +#include "XMLDDELinksContext.hxx" +#include "xmlimprt.hxx" +#include "document.hxx" +#include "scmatrix.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmluconv.hxx> +#include <tools/debug.hxx> + +using namespace com::sun::star; +using namespace xmloff::token; +using ::rtl::OUString; + +//------------------------------------------------------------------ + +ScXMLDDELinksContext::ScXMLDDELinksContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) : + SvXMLImportContext( rImport, nPrfx, rLName ) +{ + // here are no attributes + rImport.LockSolarMutex(); +} + +ScXMLDDELinksContext::~ScXMLDDELinksContext() +{ + GetScImport().UnlockSolarMutex(); +} + +SvXMLImportContext *ScXMLDDELinksContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(rLName, XML_DDE_LINK)) + pContext = new ScXMLDDELinkContext(GetScImport(), nPrefix, rLName, xAttrList); + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDDELinksContext::EndElement() +{ +} + +ScXMLDDELinkContext::ScXMLDDELinkContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + aDDELinkTable(), + aDDELinkRow(), + sApplication(), + sTopic(), + sItem(), + nPosition(-1), + nColumns(0), + nRows(0), + nMode(SC_DDE_DEFAULT) +{ + // here are no attributes +} + +ScXMLDDELinkContext::~ScXMLDDELinkContext() +{ +} + +SvXMLImportContext *ScXMLDDELinkContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + if ((nPrefix == XML_NAMESPACE_OFFICE) && IsXMLToken(rLName, XML_DDE_SOURCE)) + pContext = new ScXMLDDESourceContext(GetScImport(), nPrefix, rLName, xAttrList, this); + else if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(rLName, XML_TABLE)) + pContext = new ScXMLDDETableContext(GetScImport(), nPrefix, rLName, xAttrList, this); + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDDELinkContext::CreateDDELink() +{ + if (GetScImport().GetDocument() && + sApplication.getLength() && + sTopic.getLength() && + sItem.getLength()) + { + String sAppl(sApplication); + String sTop(sTopic); + String sIt(sItem); + GetScImport().GetDocument()->CreateDdeLink(sAppl, sTop, sIt, nMode); + sal_uInt16 nPos; + if(GetScImport().GetDocument()->FindDdeLink(sAppl, sTop, sIt, nMode, nPos)) + nPosition = nPos; + else + nPosition = -1; + DBG_ASSERT(nPosition > -1, "DDE Link not inserted"); + } +} + +void ScXMLDDELinkContext::AddCellToRow(const ScDDELinkCell& aCell) +{ + aDDELinkRow.push_back(aCell); +} + +void ScXMLDDELinkContext::AddRowsToTable(const sal_Int32 nRowsP) +{ + for (sal_Int32 i = 0; i < nRowsP; ++i) + aDDELinkTable.insert(aDDELinkTable.end(), aDDELinkRow.begin(), aDDELinkRow.end()); + aDDELinkRow.clear(); +} + +void ScXMLDDELinkContext::EndElement() +{ + if (nPosition > -1 && nColumns && nRows && GetScImport().GetDocument()) + { + bool bSizeMatch = (static_cast<size_t>(nColumns * nRows) == aDDELinkTable.size()); + DBG_ASSERT( bSizeMatch, "ScXMLDDELinkContext::EndElement: matrix dimension doesn't match cells count"); + // Excel writes bad ODF in that it does not write the + // table:number-columns-repeated attribute of the + // <table:table-column> element, but apparently uses the number of + // <table:table-cell> elements within a <table:table-row> element to + // determine the column count instead. Be lenient ... + if (!bSizeMatch && nColumns == 1) + { + nColumns = aDDELinkTable.size() / nRows; + DBG_ASSERT( static_cast<size_t>(nColumns * nRows) == aDDELinkTable.size(), + "ScXMLDDELinkContext::EndElement: adapted matrix dimension doesn't match either"); + } + ScMatrixRef pMatrix = new ScMatrix( static_cast<SCSIZE>(nColumns), static_cast<SCSIZE>(nRows) ); + sal_Int32 nCol(0); + sal_Int32 nRow(-1); + sal_Int32 nIndex(0); + ScDDELinkCells::iterator aItr(aDDELinkTable.begin()); + ScDDELinkCells::iterator aEndItr(aDDELinkTable.end()); + while (aItr != aEndItr) + { + if (nIndex % nColumns == 0) + { + ++nRow; + nCol = 0; + } + else + ++nCol; + + SCSIZE nScCol( static_cast< SCSIZE >( nCol ) ); + SCSIZE nScRow( static_cast< SCSIZE >( nRow ) ); + if( aItr->bEmpty ) + pMatrix->PutEmpty( nScCol, nScRow ); + else if( aItr->bString ) + pMatrix->PutString( aItr->sValue, nScCol, nScRow ); + else + pMatrix->PutDouble( aItr->fValue, nScCol, nScRow ); + + ++nIndex; + ++aItr; + } + + GetScImport().GetDocument()->SetDdeLinkResultMatrix( static_cast< sal_uInt16 >( nPosition ), pMatrix ); + } +} + +ScXMLDDESourceContext::ScXMLDDESourceContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDDELinkContext* pTempDDELink) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDDELink(pTempDDELink) +{ + if( !xAttrList.is() ) return; + + sal_Int16 nAttrCount = xAttrList->getLength(); + + for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex ) + { + const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex )); + const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex )); + OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); + + if (nPrefix == XML_NAMESPACE_OFFICE) + { + if (IsXMLToken(aLocalName, XML_DDE_APPLICATION)) + pDDELink->SetApplication(sValue); + else if (IsXMLToken(aLocalName, XML_DDE_TOPIC)) + pDDELink->SetTopic(sValue); + else if (IsXMLToken(aLocalName, XML_DDE_ITEM)) + pDDELink->SetItem(sValue); + } + else if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(aLocalName, XML_CONVERSION_MODE)) + { + if (IsXMLToken(sValue, XML_INTO_ENGLISH_NUMBER)) + pDDELink->SetMode(SC_DDE_ENGLISH); + else if (IsXMLToken(sValue, XML_KEEP_TEXT)) + pDDELink->SetMode(SC_DDE_TEXT); + else + pDDELink->SetMode(SC_DDE_DEFAULT); + } + } +} + +ScXMLDDESourceContext::~ScXMLDDESourceContext() +{ +} + +SvXMLImportContext *ScXMLDDESourceContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDDESourceContext::EndElement() +{ + pDDELink->CreateDDELink(); +} + +ScXMLDDETableContext::ScXMLDDETableContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */, + ScXMLDDELinkContext* pTempDDELink) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDDELink(pTempDDELink) +{ + // here are no attributes +} + +ScXMLDDETableContext::~ScXMLDDETableContext() +{ +} + +SvXMLImportContext *ScXMLDDETableContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = NULL; + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(rLName, XML_TABLE_COLUMN)) + pContext = new ScXMLDDEColumnContext(GetScImport(), nPrefix, rLName, xAttrList, pDDELink); + else if (IsXMLToken(rLName, XML_TABLE_ROW)) + pContext = new ScXMLDDERowContext(GetScImport(), nPrefix, rLName, xAttrList, pDDELink); + } + + if (!pContext) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDDETableContext::EndElement() +{ +} + +ScXMLDDEColumnContext::ScXMLDDEColumnContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDDELinkContext* pTempDDELink) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDDELink(pTempDDELink) +{ + if( !xAttrList.is() ) return; + sal_Int32 nCols(1); + + sal_Int16 nAttrCount = xAttrList->getLength(); + + for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex ) + { + const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex )); + const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex )); + OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); + + if (nPrefix == XML_NAMESPACE_TABLE) + if (IsXMLToken(aLocalName, XML_NUMBER_COLUMNS_REPEATED)) + GetScImport().GetMM100UnitConverter().convertNumber(nCols, sValue); + } + pDDELink->AddColumns(nCols); +} + +ScXMLDDEColumnContext::~ScXMLDDEColumnContext() +{ +} + +SvXMLImportContext *ScXMLDDEColumnContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDDEColumnContext::EndElement() +{ +} + +ScXMLDDERowContext::ScXMLDDERowContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDDELinkContext* pTempDDELink) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDDELink(pTempDDELink), + nRows(1) +{ + if( !xAttrList.is() ) return; + + sal_Int16 nAttrCount = xAttrList->getLength(); + + for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex ) + { + const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex )); + const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex )); + OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); + + if (nPrefix == XML_NAMESPACE_TABLE) + if (IsXMLToken(aLocalName, XML_NUMBER_ROWS_REPEATED)) + GetScImport().GetMM100UnitConverter().convertNumber(nRows, sValue); + } + pDDELink->AddRows(nRows); +} + +ScXMLDDERowContext::~ScXMLDDERowContext() +{ +} + +SvXMLImportContext *ScXMLDDERowContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = NULL; + + if (nPrefix == XML_NAMESPACE_TABLE) + if (IsXMLToken(rLName, XML_TABLE_CELL)) + pContext = new ScXMLDDECellContext(GetScImport(), nPrefix, rLName, xAttrList, pDDELink); + + if (!pContext) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDDERowContext::EndElement() +{ + pDDELink->AddRowsToTable(nRows); +} + +ScXMLDDECellContext::ScXMLDDECellContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDDELinkContext* pTempDDELink) : + SvXMLImportContext( rImport, nPrfx, rLName ), + sValue(), + fValue(), + nCells(1), + bString(sal_True), + bString2(sal_True), + bEmpty(sal_True), + pDDELink(pTempDDELink) +{ + if( !xAttrList.is() ) return; + + sal_Int16 nAttrCount = xAttrList->getLength(); + + for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex ) + { + const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex )); + const rtl::OUString& sTempValue (xAttrList->getValueByIndex( nIndex )); + OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); + + if (nPrefix == XML_NAMESPACE_OFFICE) + { + if (IsXMLToken(aLocalName, XML_VALUE_TYPE)) + { + if (IsXMLToken(sTempValue, XML_STRING)) + bString = sal_True; + else + bString = sal_False; + } + else if (IsXMLToken(aLocalName, XML_STRING_VALUE)) + { + sValue = sTempValue; + bEmpty = sal_False; + bString2 = sal_True; + } + else if (IsXMLToken(aLocalName, XML_VALUE)) + { + GetScImport().GetMM100UnitConverter().convertDouble(fValue, sTempValue); + bEmpty = sal_False; + bString2 = sal_False; + } + } + else if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(aLocalName, XML_NUMBER_COLUMNS_REPEATED)) + GetScImport().GetMM100UnitConverter().convertNumber(nCells, sTempValue); + } + } +} + +ScXMLDDECellContext::~ScXMLDDECellContext() +{ +} + +SvXMLImportContext *ScXMLDDECellContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDDECellContext::EndElement() +{ + DBG_ASSERT(bString == bString2, "something wrong with this type"); + ScDDELinkCell aCell; + aCell.sValue = sValue; + aCell.fValue = fValue; + aCell.bEmpty = bEmpty; + aCell.bString = bString2; + for(sal_Int32 i = 0; i < nCells; ++i) + pDDELink->AddCellToRow(aCell); +} diff --git a/sc/source/filter/xml/XMLDDELinksContext.hxx b/sc/source/filter/xml/XMLDDELinksContext.hxx new file mode 100644 index 000000000000..077515a07a4a --- /dev/null +++ b/sc/source/filter/xml/XMLDDELinksContext.hxx @@ -0,0 +1,230 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLDDELINKSCONTEXT_HXX +#define SC_XMLDDELINKSCONTEXT_HXX + +#include <xmloff/xmlictxt.hxx> + +#include <list> + +class ScXMLImport; + +class ScXMLDDELinksContext : public SvXMLImportContext +{ + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } +public: + ScXMLDDELinksContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList); + + virtual ~ScXMLDDELinksContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +struct ScDDELinkCell +{ + rtl::OUString sValue; + double fValue; + sal_Bool bString; + sal_Bool bEmpty; +}; + +typedef std::list<ScDDELinkCell> ScDDELinkCells; + +class ScXMLDDELinkContext : public SvXMLImportContext +{ + ScDDELinkCells aDDELinkTable; + ScDDELinkCells aDDELinkRow; + rtl::OUString sApplication; + rtl::OUString sTopic; + rtl::OUString sItem; + sal_Int32 nPosition; + sal_Int32 nColumns; + sal_Int32 nRows; + sal_uInt8 nMode; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } +public: + ScXMLDDELinkContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList); + + virtual ~ScXMLDDELinkContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + void SetApplication(const rtl::OUString& sValue) { sApplication = sValue; } + void SetTopic(const rtl::OUString& sValue) { sTopic = sValue; } + void SetItem(const rtl::OUString& sValue) { sItem = sValue; } + void SetMode(const sal_uInt8 nValue) { nMode = nValue; } + void CreateDDELink(); + void AddColumns(const sal_Int32 nValue) { nColumns += nValue; } + void AddRows(const sal_Int32 nValue) { nRows += nValue; } + void AddCellToRow(const ScDDELinkCell& aCell); + void AddRowsToTable(const sal_Int32 nRows); + + virtual void EndElement(); +}; + +class ScXMLDDESourceContext : public SvXMLImportContext +{ + ScXMLDDELinkContext* pDDELink; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } +public: + ScXMLDDESourceContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDDELinkContext* pDDELink); + + virtual ~ScXMLDDESourceContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLDDETableContext : public SvXMLImportContext +{ + ScXMLDDELinkContext* pDDELink; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } +public: + ScXMLDDETableContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDDELinkContext* pDDELink); + + virtual ~ScXMLDDETableContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLDDEColumnContext : public SvXMLImportContext +{ + ScXMLDDELinkContext* pDDELink; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } +public: + ScXMLDDEColumnContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDDELinkContext* pDDELink); + + virtual ~ScXMLDDEColumnContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLDDERowContext : public SvXMLImportContext +{ + ScXMLDDELinkContext* pDDELink; + sal_Int32 nRows; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } +public: + ScXMLDDERowContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDDELinkContext* pDDELink); + + virtual ~ScXMLDDERowContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLDDECellContext : public SvXMLImportContext +{ + rtl::OUString sValue; + double fValue; + sal_Int32 nCells; + sal_Bool bString; + sal_Bool bString2; + sal_Bool bEmpty; + + ScXMLDDELinkContext* pDDELink; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } +public: + ScXMLDDECellContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDDELinkContext* pDDELink); + + virtual ~ScXMLDDECellContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +#endif diff --git a/sc/source/filter/xml/XMLDetectiveContext.cxx b/sc/source/filter/xml/XMLDetectiveContext.cxx new file mode 100644 index 000000000000..109cb21abe04 --- /dev/null +++ b/sc/source/filter/xml/XMLDetectiveContext.cxx @@ -0,0 +1,265 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +//___________________________________________________________________ +#include "XMLDetectiveContext.hxx" +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmluconv.hxx> +#include "convuno.hxx" +#include "xmlimprt.hxx" +#include "XMLConverter.hxx" +#include "rangeutl.hxx" + +#include <algorithm> + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace xmloff::token; + + +//___________________________________________________________________ + +ScMyImpDetectiveObj::ScMyImpDetectiveObj() : + aSourceRange(), + eObjType( SC_DETOBJ_NONE ), + bHasError( sal_False ) +{ +} + +//___________________________________________________________________ + +sal_Bool ScMyImpDetectiveOp::operator<(const ScMyImpDetectiveOp& rDetOp) const +{ + return (nIndex < rDetOp.nIndex); +} + +void ScMyImpDetectiveOpArray::Sort() +{ + aDetectiveOpList.sort(); +} + +sal_Bool ScMyImpDetectiveOpArray::GetFirstOp( ScMyImpDetectiveOp& rDetOp ) +{ + if( aDetectiveOpList.empty() ) + return sal_False; + ScMyImpDetectiveOpList::iterator aItr = aDetectiveOpList.begin(); + rDetOp = *aItr; + aDetectiveOpList.erase( aItr ); + return sal_True; +} + + +//___________________________________________________________________ + +ScXMLDetectiveContext::ScXMLDetectiveContext( + ScXMLImport& rImport, + sal_uInt16 nPrfx, + const OUString& rLName, + ScMyImpDetectiveObjVec* pNewDetectiveObjVec ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDetectiveObjVec( pNewDetectiveObjVec ) +{ +} + +ScXMLDetectiveContext::~ScXMLDetectiveContext() +{ +} + +SvXMLImportContext *ScXMLDetectiveContext::CreateChildContext( + sal_uInt16 nPrefix, + const OUString& rLName, + const uno::Reference< xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext* pContext = NULL; + const SvXMLTokenMap& rTokenMap = GetScImport().GetDetectiveElemTokenMap(); + + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_DETECTIVE_ELEM_HIGHLIGHTED: + pContext = new ScXMLDetectiveHighlightedContext( GetScImport(), nPrefix, rLName, xAttrList, pDetectiveObjVec ); + break; + case XML_TOK_DETECTIVE_ELEM_OPERATION: + pContext = new ScXMLDetectiveOperationContext( GetScImport(), nPrefix, rLName, xAttrList ); + break; + } + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDetectiveContext::EndElement() +{ +} + + +//___________________________________________________________________ + +ScXMLDetectiveHighlightedContext::ScXMLDetectiveHighlightedContext( + ScXMLImport& rImport, + sal_uInt16 nPrfx, + const OUString& rLName, + const uno::Reference< xml::sax::XAttributeList >& xAttrList, + ScMyImpDetectiveObjVec* pNewDetectiveObjVec ): + SvXMLImportContext( rImport, nPrfx, rLName ), + pDetectiveObjVec( pNewDetectiveObjVec ), + aDetectiveObj(), + bValid( sal_False ) +{ + if( !xAttrList.is() ) return; + + sal_Int16 nAttrCount = xAttrList->getLength(); + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDetectiveHighlightedAttrTokenMap(); + + for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex ) + { + const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex )); + const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex )); + OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_CELL_RANGE: + { + sal_Int32 nOffset(0); + GetScImport().LockSolarMutex(); + bValid = ScRangeStringConverter::GetRangeFromString( aDetectiveObj.aSourceRange, sValue, GetScImport().GetDocument(), ::formula::FormulaGrammar::CONV_OOO, nOffset ); + GetScImport().UnlockSolarMutex(); + } + break; + case XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_DIRECTION: + aDetectiveObj.eObjType = ScXMLConverter::GetDetObjTypeFromString( sValue ); + break; + case XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_CONTAINS_ERROR: + aDetectiveObj.bHasError = IsXMLToken(sValue, XML_TRUE); + break; + case XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_MARKED_INVALID: + { + if (IsXMLToken(sValue, XML_TRUE)) + aDetectiveObj.eObjType = SC_DETOBJ_CIRCLE; + } + break; + } + } +} + +ScXMLDetectiveHighlightedContext::~ScXMLDetectiveHighlightedContext() +{ +} + +SvXMLImportContext *ScXMLDetectiveHighlightedContext::CreateChildContext( + sal_uInt16 nPrefix, + const OUString& rLName, + const uno::Reference< xml::sax::XAttributeList>& /* xAttrList */ ) +{ + return new SvXMLImportContext( GetImport(), nPrefix, rLName ); +} + +void ScXMLDetectiveHighlightedContext::EndElement() +{ + switch( aDetectiveObj.eObjType ) + { + case SC_DETOBJ_ARROW: + case SC_DETOBJ_TOOTHERTAB: + break; + case SC_DETOBJ_FROMOTHERTAB: + case SC_DETOBJ_CIRCLE: + bValid = sal_True; + break; + default: + bValid = sal_False; + } + if( bValid ) + pDetectiveObjVec->push_back( aDetectiveObj ); +} + + +//___________________________________________________________________ + +ScXMLDetectiveOperationContext::ScXMLDetectiveOperationContext( + ScXMLImport& rImport, + sal_uInt16 nPrfx, + const OUString& rLName, + const uno::Reference< xml::sax::XAttributeList >& xAttrList ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + aDetectiveOp(), + bHasType( sal_False ) +{ + if( !xAttrList.is() ) return; + + sal_Int16 nAttrCount = xAttrList->getLength(); + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDetectiveOperationAttrTokenMap(); + + for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex ) + { + const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex )); + const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex )); + OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_DETECTIVE_OPERATION_ATTR_NAME: + bHasType = ScXMLConverter::GetDetOpTypeFromString( aDetectiveOp.eOpType, sValue ); + break; + case XML_TOK_DETECTIVE_OPERATION_ATTR_INDEX: + { + sal_Int32 nValue; + if( SvXMLUnitConverter::convertNumber( nValue, sValue, 0 ) ) + aDetectiveOp.nIndex = nValue; + } + break; + } + } + ScUnoConversion::FillScAddress( aDetectiveOp.aPosition, rImport.GetTables().GetRealCellPos() ); +} + +ScXMLDetectiveOperationContext::~ScXMLDetectiveOperationContext() +{ +} + +SvXMLImportContext *ScXMLDetectiveOperationContext::CreateChildContext( + sal_uInt16 nPrefix, + const OUString& rLName, + const uno::Reference< xml::sax::XAttributeList>& /* xAttrList */ ) +{ + return new SvXMLImportContext( GetImport(), nPrefix, rLName ); +} + +void ScXMLDetectiveOperationContext::EndElement() +{ + if( bHasType && (aDetectiveOp.nIndex >= 0) ) + GetScImport().GetDetectiveOpArray()->AddDetectiveOp( aDetectiveOp ); +} + diff --git a/sc/source/filter/xml/XMLDetectiveContext.hxx b/sc/source/filter/xml/XMLDetectiveContext.hxx new file mode 100644 index 000000000000..c0b00384f91a --- /dev/null +++ b/sc/source/filter/xml/XMLDetectiveContext.hxx @@ -0,0 +1,175 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLDETECTIVECONTEXT_HXX +#define SC_XMLDETECTIVECONTEXT_HXX + +#include <xmloff/xmlimp.hxx> +#include <com/sun/star/table/CellRangeAddress.hpp> +#include "detfunc.hxx" +#include "detdata.hxx" + +#include <list> + +class ScXMLImport; + + +//___________________________________________________________________ + +struct ScMyImpDetectiveObj +{ + ScRange aSourceRange; + ScDetectiveObjType eObjType; + sal_Bool bHasError; + + ScMyImpDetectiveObj(); +}; + +typedef ::std::vector< ScMyImpDetectiveObj > ScMyImpDetectiveObjVec; + + +//___________________________________________________________________ + +struct ScMyImpDetectiveOp +{ + ScAddress aPosition; + ScDetOpType eOpType; + sal_Int32 nIndex; + + inline ScMyImpDetectiveOp() : nIndex( -1 ) {} + sal_Bool operator<(const ScMyImpDetectiveOp& rDetOp) const; +}; + +typedef ::std::list< ScMyImpDetectiveOp > ScMyImpDetectiveOpList; + +class ScMyImpDetectiveOpArray +{ +private: + ScMyImpDetectiveOpList aDetectiveOpList; + +public: + inline ScMyImpDetectiveOpArray() : + aDetectiveOpList() {} + + inline void AddDetectiveOp( const ScMyImpDetectiveOp& rDetOp ) + { aDetectiveOpList.push_back( rDetOp ); } + + void Sort(); + sal_Bool GetFirstOp( ScMyImpDetectiveOp& rDetOp ); +}; + + +//___________________________________________________________________ + +class ScXMLDetectiveContext : public SvXMLImportContext +{ +private: + ScMyImpDetectiveObjVec* pDetectiveObjVec; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLDetectiveContext( + ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + ScMyImpDetectiveObjVec* pNewDetectiveObjVec + ); + virtual ~ScXMLDetectiveContext(); + + virtual SvXMLImportContext* CreateChildContext( + sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList + ); + virtual void EndElement(); +}; + + +//___________________________________________________________________ + +class ScXMLDetectiveHighlightedContext : public SvXMLImportContext +{ +private: + ScMyImpDetectiveObjVec* pDetectiveObjVec; + ScMyImpDetectiveObj aDetectiveObj; + sal_Bool bValid; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLDetectiveHighlightedContext( + ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList, + ScMyImpDetectiveObjVec* pNewDetectiveObjVec + ); + virtual ~ScXMLDetectiveHighlightedContext(); + + virtual SvXMLImportContext* CreateChildContext( + sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList + ); + virtual void EndElement(); +}; + + +//___________________________________________________________________ + +class ScXMLDetectiveOperationContext : public SvXMLImportContext +{ +private: + ScMyImpDetectiveOp aDetectiveOp; + sal_Bool bHasType; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLDetectiveOperationContext( + ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList + ); + virtual ~ScXMLDetectiveOperationContext(); + + virtual SvXMLImportContext* CreateChildContext( + sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList + ); + virtual void EndElement(); +}; + + +#endif + diff --git a/sc/source/filter/xml/XMLEmptyContext.cxx b/sc/source/filter/xml/XMLEmptyContext.cxx new file mode 100644 index 000000000000..42750bbc8e4f --- /dev/null +++ b/sc/source/filter/xml/XMLEmptyContext.cxx @@ -0,0 +1,63 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- + +#include "XMLEmptyContext.hxx" +#include "xmlimprt.hxx" + +//------------------------------------------------------------------ + +ScXMLEmptyContext::ScXMLEmptyContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName) : + SvXMLImportContext( rImport, nPrfx, rLName ) +{ +} + +ScXMLEmptyContext::~ScXMLEmptyContext() +{ +} + +SvXMLImportContext *ScXMLEmptyContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + SvXMLImportContext *pContext = new ScXMLEmptyContext(GetScImport(), nPrefix, rLName); + + return pContext; +} + +void ScXMLEmptyContext::EndElement() +{ +} diff --git a/sc/source/filter/xml/XMLEmptyContext.hxx b/sc/source/filter/xml/XMLEmptyContext.hxx new file mode 100644 index 000000000000..e2a0303311b8 --- /dev/null +++ b/sc/source/filter/xml/XMLEmptyContext.hxx @@ -0,0 +1,57 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef SC_XMLEMPTYCONTEXT_HXX +#define SC_XMLEMPTYCONTEXT_HXX + +#include <xmloff/xmlictxt.hxx> + +class ScXMLImport; + +class ScXMLEmptyContext : public SvXMLImportContext +{ + rtl::OUString sPrintRanges; + sal_Bool bStartFormPage; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLEmptyContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName); + + virtual ~ScXMLEmptyContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +#endif diff --git a/sc/source/filter/xml/XMLExportDDELinks.cxx b/sc/source/filter/xml/XMLExportDDELinks.cxx new file mode 100644 index 000000000000..a738f93add19 --- /dev/null +++ b/sc/source/filter/xml/XMLExportDDELinks.cxx @@ -0,0 +1,221 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- +#include "XMLExportDDELinks.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmluconv.hxx> +#include "xmlexprt.hxx" +#include "unonames.hxx" +#include "document.hxx" +#include "scmatrix.hxx" +#include <com/sun/star/sheet/XDDELink.hpp> + +class ScMatrix; + +using namespace com::sun::star; +using namespace xmloff::token; + +ScXMLExportDDELinks::ScXMLExportDDELinks(ScXMLExport& rTempExport) + : rExport(rTempExport) +{ +} + +ScXMLExportDDELinks::~ScXMLExportDDELinks() +{ +} + +sal_Bool ScXMLExportDDELinks::CellsEqual(const sal_Bool bPrevEmpty, const sal_Bool bPrevString, const String& sPrevValue, const double& fPrevValue, + const sal_Bool bEmpty, const sal_Bool bString, const String& sValue, const double& fValue) +{ + if (bEmpty == bPrevEmpty) + if (bEmpty) + return sal_True; + else if (bString == bPrevString) + if (bString) + return (sPrevValue == sValue); + else + return (fPrevValue == fValue); + else + return sal_False; + else + return sal_False; +} + +void ScXMLExportDDELinks::WriteCell(const sal_Bool bEmpty, const sal_Bool bString, const String& sValue, const double& fValue, const sal_Int32 nRepeat) +{ + rtl::OUStringBuffer sBuffer; + if (!bEmpty) + { + if (bString) + { + rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING); + rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_STRING_VALUE, rtl::OUString(sValue)); + } + else + { + rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT); + rExport.GetMM100UnitConverter().convertDouble(sBuffer, fValue); + rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE, sBuffer.makeStringAndClear()); + } + } + if (nRepeat > 1) + { + rExport.GetMM100UnitConverter().convertNumber(sBuffer, nRepeat); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, sBuffer.makeStringAndClear()); + } + SvXMLElementExport(rExport, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True); +} + +void ScXMLExportDDELinks::WriteTable(const sal_Int32 nPos) +{ + const ScMatrix* pMatrix(NULL); + if (rExport.GetDocument()) + pMatrix = rExport.GetDocument()->GetDdeLinkResultMatrix( static_cast<sal_uInt16>(nPos) ); + if (pMatrix) + { + SCSIZE nuCol; + SCSIZE nuRow; + pMatrix->GetDimensions( nuCol, nuRow ); + sal_Int32 nRowCount = static_cast<sal_Int32>(nuRow); + sal_Int32 nColCount = static_cast<sal_Int32>(nuCol); + SvXMLElementExport aTableElem(rExport, XML_NAMESPACE_TABLE, XML_TABLE, sal_True, sal_True); + rtl::OUStringBuffer sBuffer; + if (nColCount > 1) + { + rExport.GetMM100UnitConverter().convertNumber(sBuffer, nColCount); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, sBuffer.makeStringAndClear()); + } + { + SvXMLElementExport aElemCol(rExport, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, sal_True, sal_True); + } + sal_Bool bPrevString(sal_True); + sal_Bool bPrevEmpty(sal_True); + double fPrevValue; + String sPrevValue; + sal_Int32 nRepeatColsCount(1); + for(sal_Int32 nRow = 0; nRow < nRowCount; ++nRow) + { + SvXMLElementExport aElemRow(rExport, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True); + for(sal_Int32 nColumn = 0; nColumn < nColCount; ++nColumn) + { + ScMatValType nType = SC_MATVAL_VALUE; + const ScMatrixValue* pMatVal = pMatrix->Get( static_cast<SCSIZE>(nColumn), static_cast<SCSIZE>(nRow), nType ); + sal_Bool bIsString = ScMatrix::IsNonValueType( nType); + + if (nColumn == 0) + { + bPrevEmpty = !pMatVal; + bPrevString = bIsString; + if( bIsString ) + sPrevValue = pMatVal->GetString(); + else + fPrevValue = pMatVal->fVal; + } + else + { + double fValue; + String sValue; + sal_Bool bEmpty(!pMatVal); + sal_Bool bString(bIsString); + if( bIsString ) + sValue = pMatVal->GetString(); + else + fValue = pMatVal->fVal; + + if (CellsEqual(bPrevEmpty, bPrevString, sPrevValue, fPrevValue, + bEmpty, bString, sValue, fValue)) + ++nRepeatColsCount; + else + { + WriteCell(bPrevEmpty, bPrevString, sPrevValue, fPrevValue, nRepeatColsCount); + nRepeatColsCount = 1; + bPrevEmpty = bEmpty; + fPrevValue = fValue; + sPrevValue = sValue; + } + } + } + WriteCell(bPrevEmpty, bPrevString, sPrevValue, fPrevValue, nRepeatColsCount); + nRepeatColsCount = 1; + } + } +} + +void ScXMLExportDDELinks::WriteDDELinks(uno::Reference<sheet::XSpreadsheetDocument>& xSpreadDoc) +{ + uno::Reference <beans::XPropertySet> xPropertySet (xSpreadDoc, uno::UNO_QUERY); + if (xPropertySet.is()) + { + uno::Reference<container::XIndexAccess> xIndex(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DDELINKS))), uno::UNO_QUERY); + if (xIndex.is()) + { + sal_Int32 nCount = xIndex->getCount(); + if (nCount) + { + SvXMLElementExport aElemDDEs(rExport, XML_NAMESPACE_TABLE, XML_DDE_LINKS, sal_True, sal_True); + for (sal_uInt16 nDDELink = 0; nDDELink < nCount; ++nDDELink) + { + uno::Reference<sheet::XDDELink> xDDELink(xIndex->getByIndex(nDDELink), uno::UNO_QUERY); + if (xDDELink.is()) + { + SvXMLElementExport aElemDDE(rExport, XML_NAMESPACE_TABLE, XML_DDE_LINK, sal_True, sal_True); + { + rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_DDE_APPLICATION, xDDELink->getApplication()); + rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_DDE_TOPIC, xDDELink->getTopic()); + rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_DDE_ITEM, xDDELink->getItem()); + rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_AUTOMATIC_UPDATE, XML_TRUE); + sal_uInt8 nMode; + if (rExport.GetDocument() && + rExport.GetDocument()->GetDdeLinkMode(nDDELink, nMode)) + { + switch (nMode) + { + case SC_DDE_ENGLISH : + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONVERSION_MODE, XML_INTO_ENGLISH_NUMBER); + break; + case SC_DDE_TEXT : + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONVERSION_MODE, XML_KEEP_TEXT); + break; + } + } + SvXMLElementExport(rExport, XML_NAMESPACE_OFFICE, XML_DDE_SOURCE, sal_True, sal_True); + } + WriteTable(nDDELink); + } + } + } + } + } +} diff --git a/sc/source/filter/xml/XMLExportDDELinks.hxx b/sc/source/filter/xml/XMLExportDDELinks.hxx new file mode 100644 index 000000000000..245a95934449 --- /dev/null +++ b/sc/source/filter/xml/XMLExportDDELinks.hxx @@ -0,0 +1,52 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLEXPORTDDELINKS_HXX +#define SC_XMLEXPORTDDELINKS_HXX + +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> + +class String; +class ScXMLExport; + +class ScXMLExportDDELinks +{ + ScXMLExport& rExport; + + sal_Bool CellsEqual(const sal_Bool bPrevEmpty, const sal_Bool bPrevString, const String& sPrevValue, const double& fPrevValue, + const sal_Bool bEmpty, const sal_Bool bString, const String& sValue, const double& fValue); + void WriteCell(const sal_Bool bEmpty, const sal_Bool bString, const String& sValue, const double& fValue, const sal_Int32 nRepeat); + void WriteTable(const sal_Int32 nPos); +public: + ScXMLExportDDELinks(ScXMLExport& rExport); + ~ScXMLExportDDELinks(); + void WriteDDELinks(::com::sun::star::uno::Reference < ::com::sun::star::sheet::XSpreadsheetDocument >& xSpreadDoc); +}; + +#endif + + diff --git a/sc/source/filter/xml/XMLExportDataPilot.cxx b/sc/source/filter/xml/XMLExportDataPilot.cxx new file mode 100644 index 000000000000..f8cba5ecf6c3 --- /dev/null +++ b/sc/source/filter/xml/XMLExportDataPilot.cxx @@ -0,0 +1,898 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 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, 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); + } + } + } + } + } +} diff --git a/sc/source/filter/xml/XMLExportDataPilot.hxx b/sc/source/filter/xml/XMLExportDataPilot.hxx new file mode 100644 index 000000000000..600d96aa1d73 --- /dev/null +++ b/sc/source/filter/xml/XMLExportDataPilot.hxx @@ -0,0 +1,80 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLEXPORTDATAPILOT_HXX +#define SC_XMLEXPORTDATAPILOT_HXX + +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include <rtl/ustring.hxx> +#include "global.hxx" +#include "xmloff/xmltoken.hxx" + +class ScXMLExport; +class ScDocument; +class ScDPSaveDimension; +class ScDPSaveData; +class ScDPDimensionSaveData; +class ScDPSaveGroupDimension; +class ScDPSaveNumGroupDimension; +struct ScDPNumGroupInfo; +struct ScQueryParam; + +class ScXMLExportDataPilot +{ + ScXMLExport& rExport; + ScDocument* pDoc; + + rtl::OUString getDPOperatorXML(const ScQueryOp aFilterOperator, const sal_Bool bUseRegularExpressions, + const sal_Bool bIsString, const double dVal, const String& sVal) const; + void WriteDPCondition(const ScQueryEntry& aQueryEntry, sal_Bool bIsCaseSensitive, sal_Bool bUseRegularExpressions); + void WriteDPFilter(const ScQueryParam& aQueryParam); + + void WriteFieldReference(ScDPSaveDimension* pDim); + void WriteSortInfo(ScDPSaveDimension* pDim); + void WriteAutoShowInfo(ScDPSaveDimension* pDim); + void WriteLayoutInfo(ScDPSaveDimension* pDim); + void WriteSubTotals(ScDPSaveDimension* pDim); + void WriteMembers(ScDPSaveDimension* pDim); + void WriteLevels(ScDPSaveDimension* pDim); + void WriteDatePart(sal_Int32 nPart); + void WriteNumGroupInfo(const ScDPNumGroupInfo& pGroupInfo); + void WriteGroupDimAttributes(const ScDPSaveGroupDimension* pGroupDim); + void WriteGroupDimElements(ScDPSaveDimension* pDim, const ScDPDimensionSaveData* pDimData); + void WriteNumGroupDim(const ScDPSaveNumGroupDimension* pNumGroupDim); + 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(); + void WriteDataPilots(const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xSpreaDoc); +}; + +#endif + diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx new file mode 100644 index 000000000000..3c7ee76c41e8 --- /dev/null +++ b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx @@ -0,0 +1,699 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- +#include "XMLExportDatabaseRanges.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/xmluconv.hxx> +#include <xmloff/nmspmap.hxx> +#include "xmlexprt.hxx" +#include "XMLExportIterator.hxx" +#include "XMLConverter.hxx" +#include "unonames.hxx" +#include "dbcolect.hxx" +#include "document.hxx" +#include "globstr.hrc" +#include "XMLExportSharedData.hxx" +#include "rangeutl.hxx" +#include <com/sun/star/sheet/DataImportMode.hpp> +#include <com/sun/star/table/TableSortField.hpp> +#include <com/sun/star/table/TableSortFieldType.hpp> +#include <com/sun/star/sheet/XSubTotalField.hpp> +#include <com/sun/star/sheet/XDatabaseRanges.hpp> +#include <com/sun/star/sheet/XDatabaseRange.hpp> +#include <com/sun/star/table/TableOrientation.hpp> +#include <tools/debug.hxx> +#include <comphelper/extract.hxx> + +//! not found in unonames.hxx +#define SC_USERLIST "UserList" +#define SC_SORTASCENDING "SortAscending" +#define SC_ENABLEUSERSORTLIST "EnableUserSortList" +#define SC_USERSORTLISTINDEX "UserSortListIndex" + +using namespace com::sun::star; +using namespace xmloff::token; + +ScXMLExportDatabaseRanges::ScXMLExportDatabaseRanges(ScXMLExport& rTempExport) + : rExport(rTempExport), + pDoc( NULL ) +{ +} + +ScXMLExportDatabaseRanges::~ScXMLExportDatabaseRanges() +{ +} + +ScMyEmptyDatabaseRangesContainer ScXMLExportDatabaseRanges::GetEmptyDatabaseRanges() +{ + ScMyEmptyDatabaseRangesContainer aSkipRanges; + if (rExport.GetModel().is()) + { + sal_Int32 nSkipRangesCount = 0; + uno::Reference <beans::XPropertySet> xPropertySet (rExport.GetModel(), uno::UNO_QUERY); + if (xPropertySet.is()) + { + uno::Reference <sheet::XDatabaseRanges> xDatabaseRanges(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DATABASERNG))), uno::UNO_QUERY); + rExport.CheckAttrList(); + if (xDatabaseRanges.is()) + { + uno::Sequence <rtl::OUString> aRanges(xDatabaseRanges->getElementNames()); + sal_Int32 nDatabaseRangesCount = aRanges.getLength(); + for (sal_Int32 i = 0; i < nDatabaseRangesCount; ++i) + { + rtl::OUString sDatabaseRangeName(aRanges[i]); + uno::Reference <sheet::XDatabaseRange> xDatabaseRange(xDatabaseRanges->getByName(sDatabaseRangeName), uno::UNO_QUERY); + if (xDatabaseRange.is()) + { + uno::Reference <beans::XPropertySet> xDatabaseRangePropertySet (xDatabaseRange, uno::UNO_QUERY); + if (xDatabaseRangePropertySet.is() && + ::cppu::any2bool(xDatabaseRangePropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_STRIPDAT))))) + { + uno::Sequence <beans::PropertyValue> aImportProperties(xDatabaseRange->getImportDescriptor()); + sal_Int32 nLength = aImportProperties.getLength(); + sheet::DataImportMode nSourceType = sheet::DataImportMode_NONE; + for (sal_Int32 j = 0; j < nLength; ++j) + if (aImportProperties[j].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SRCTYPE))) + aImportProperties[j].Value >>= nSourceType; + if (nSourceType != sheet::DataImportMode_NONE) + { + table::CellRangeAddress aArea = xDatabaseRange->getDataArea(); + aSkipRanges.AddNewEmptyDatabaseRange(aArea); + + // #105276#; set last row/column so default styles are collected + rExport.GetSharedData()->SetLastColumn(aArea.Sheet, aArea.EndColumn); + rExport.GetSharedData()->SetLastRow(aArea.Sheet, aArea.EndRow); + } + } + } + } + if (nSkipRangesCount > 1) + aSkipRanges.Sort(); + } + } + } + return aSkipRanges; +} + +void ScXMLExportDatabaseRanges::WriteImportDescriptor(const uno::Sequence <beans::PropertyValue> aImportDescriptor) +{ + sal_Int32 nProperties = aImportDescriptor.getLength(); + rtl::OUString sDatabaseName; + rtl::OUString sConRes; + rtl::OUString sSourceObject; + sheet::DataImportMode nSourceType = sheet::DataImportMode_NONE; + sal_Bool bNative = sal_False; + for (sal_Int16 i = 0; i < nProperties; ++i) + { + if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_DBNAME))) + aImportDescriptor[i].Value >>= sDatabaseName; + else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CONRES))) + aImportDescriptor[i].Value >>= sConRes; + else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SRCOBJ))) + aImportDescriptor[i].Value >>= sSourceObject; + else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SRCTYPE))) + aImportDescriptor[i].Value >>= nSourceType; + else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ISNATIVE))) + bNative = ::cppu::any2bool(aImportDescriptor[i].Value); + } + switch (nSourceType) + { + case sheet::DataImportMode_NONE : break; + case sheet::DataImportMode_QUERY : + { + if (sDatabaseName.getLength()) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, sDatabaseName); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_QUERY_NAME, sSourceObject); + SvXMLElementExport aElemID(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_QUERY, sal_True, sal_True); + if (sConRes.getLength()) + { + rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sConRes ); + SvXMLElementExport aElemCR(rExport, XML_NAMESPACE_FORM, XML_CONNECTION_RESOURCE, sal_True, sal_True); + } + rExport.CheckAttrList(); + } + break; + case sheet::DataImportMode_TABLE : + { + if (sDatabaseName.getLength()) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, sDatabaseName); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, sSourceObject); + SvXMLElementExport aElemID(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_TABLE, sal_True, sal_True); + if (sConRes.getLength()) + { + rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sConRes ); + SvXMLElementExport aElemCR(rExport, XML_NAMESPACE_FORM, XML_CONNECTION_RESOURCE, sal_True, sal_True); + } + rExport.CheckAttrList(); + } + break; + case sheet::DataImportMode_SQL : + { + if (sDatabaseName.getLength()) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATABASE_NAME, sDatabaseName); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SQL_STATEMENT, sSourceObject); + if (!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); + if (sConRes.getLength()) + { + rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sConRes ); + SvXMLElementExport aElemCR(rExport, XML_NAMESPACE_FORM, XML_CONNECTION_RESOURCE, sal_True, sal_True); + } + rExport.CheckAttrList(); + } + break; + default: + { + // added to avoid warnings + } + } +} + +rtl::OUString ScXMLExportDatabaseRanges::getOperatorXML(const long aFilterOperator, const sal_Bool bUseRegularExpressions) const +{ + switch (aFilterOperator) + { + case sheet::FilterOperator2::EQUAL : + { + if (bUseRegularExpressions) + return GetXMLToken(XML_MATCH); + else + return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("=")); + } + case sheet::FilterOperator2::NOT_EQUAL : + { + if (bUseRegularExpressions) + return GetXMLToken(XML_NOMATCH); + else + return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("!=")); + } + case sheet::FilterOperator2::BOTTOM_PERCENT : + return GetXMLToken(XML_BOTTOM_PERCENT); + case sheet::FilterOperator2::BOTTOM_VALUES : + return GetXMLToken(XML_BOTTOM_VALUES); + case sheet::FilterOperator2::EMPTY : + return GetXMLToken(XML_EMPTY); + case sheet::FilterOperator2::GREATER : + return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">")); + case sheet::FilterOperator2::GREATER_EQUAL : + return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">=")); + case sheet::FilterOperator2::LESS : + return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<")); + case sheet::FilterOperator2::LESS_EQUAL : + return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<=")); + case sheet::FilterOperator2::NOT_EMPTY : + return GetXMLToken(XML_NOEMPTY); + case sheet::FilterOperator2::TOP_PERCENT : + return GetXMLToken(XML_TOP_PERCENT); + case sheet::FilterOperator2::TOP_VALUES : + return GetXMLToken(XML_TOP_VALUES); + case sheet::FilterOperator2::CONTAINS : + return GetXMLToken(XML_CONTAINS); + case sheet::FilterOperator2::DOES_NOT_CONTAIN : + return GetXMLToken(XML_DOES_NOT_CONTAIN); + case sheet::FilterOperator2::BEGINS_WITH : + return GetXMLToken(XML_BEGINS_WITH); + case sheet::FilterOperator2::DOES_NOT_BEGIN_WITH : + return GetXMLToken(XML_DOES_NOT_BEGIN_WITH); + case sheet::FilterOperator2::ENDS_WITH : + return GetXMLToken(XML_ENDS_WITH); + case sheet::FilterOperator2::DOES_NOT_END_WITH : + return GetXMLToken(XML_DOES_NOT_END_WITH); + default: + { + // added to avoid warnings + } + } + return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("=")); +} + +void ScXMLExportDatabaseRanges::WriteCondition(const sheet::TableFilterField2& aFilterField, sal_Bool bIsCaseSensitive, sal_Bool bUseRegularExpressions) +{ + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, rtl::OUString::valueOf(aFilterField.Field)); + if (bIsCaseSensitive) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE); + if (aFilterField.IsNumeric) + { + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_NUMBER); + rtl::OUStringBuffer sBuffer; + rExport.GetMM100UnitConverter().convertDouble(sBuffer, aFilterField.NumericValue); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, sBuffer.makeStringAndClear()); + } + else + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, aFilterField.StringValue); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_OPERATOR, getOperatorXML(aFilterField.Operator, bUseRegularExpressions)); + SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_FILTER_CONDITION, sal_True, sal_True); +} + +void ScXMLExportDatabaseRanges::WriteFilterDescriptor(const uno::Reference <sheet::XSheetFilterDescriptor2>& xSheetFilterDescriptor, const rtl::OUString sDatabaseRangeName) +{ + uno::Sequence< sheet::TableFilterField2 > aTableFilterFields( xSheetFilterDescriptor->getFilterFields2() ); + sal_Int32 nTableFilterFields = aTableFilterFields.getLength(); + if (nTableFilterFields > 0) + { + uno::Reference <beans::XPropertySet> xPropertySet (xSheetFilterDescriptor, uno::UNO_QUERY); + if (xPropertySet.is()) + { + if (::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_COPYOUT))))) + { + table::CellAddress aOutputPosition; + if (xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_OUTPOS))) >>= aOutputPosition) + { + rtl::OUString sOUCellAddress; + ScRangeStringConverter::GetStringFromAddress( sOUCellAddress, aOutputPosition, pDoc, ::formula::FormulaGrammar::CONV_OOO ); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, sOUCellAddress); + } + } + ScDBCollection* pDBCollection = pDoc->GetDBCollection(); + sal_uInt16 nIndex; + pDBCollection->SearchName(sDatabaseRangeName, nIndex); + ScDBData* pDBData = (*pDBCollection)[nIndex]; + ScRange aAdvSource; + if (pDBData->GetAdvancedQuerySource(aAdvSource)) + { + rtl::OUString sOUCellAddress; + ScRangeStringConverter::GetStringFromRange( sOUCellAddress, aAdvSource, pDoc, ::formula::FormulaGrammar::CONV_OOO ); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONDITION_SOURCE_RANGE_ADDRESS, sOUCellAddress); + } + + if (::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SKIPDUP))))) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_DUPLICATES, XML_FALSE); + SvXMLElementExport aElemF(rExport, XML_NAMESPACE_TABLE, XML_FILTER, sal_True, sal_True); + rExport.CheckAttrList(); + sal_Bool bIsCaseSensitive = ::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ISCASE)))); + sal_Bool bUseRegularExpressions = ::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_USEREGEX)))); + sal_Bool bAnd = sal_False; + sal_Bool bOr = sal_False; + for (sal_Int32 i = 1; i < nTableFilterFields; ++i) + { + if (aTableFilterFields[i].Connection == sheet::FilterConnection_AND) + bAnd = sal_True; + else + bOr = sal_True; + } + if (bOr && !bAnd) + { + SvXMLElementExport aElemOr(rExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, sal_True, sal_True); + for (sal_Int32 i = 0; i < nTableFilterFields; ++i) + { + WriteCondition(aTableFilterFields[i], bIsCaseSensitive, bUseRegularExpressions); + } + } + else if (bAnd && !bOr) + { + SvXMLElementExport aElemAnd(rExport, XML_NAMESPACE_TABLE, XML_FILTER_AND, sal_True, sal_True); + for (sal_Int32 i = 0; i < nTableFilterFields; ++i) + { + WriteCondition(aTableFilterFields[i], bIsCaseSensitive, bUseRegularExpressions); + } + } + else if (nTableFilterFields == 1) + { + WriteCondition(aTableFilterFields[0], bIsCaseSensitive, bUseRegularExpressions); + } + else + { + SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_FILTER_OR, sal_True, sal_True); + sheet::TableFilterField2 aPrevFilterField = aTableFilterFields[0]; + sheet::FilterConnection aConnection = aTableFilterFields[1].Connection; + sal_Bool bOpenAndElement; + rtl::OUString aName = rExport.GetNamespaceMap().GetQNameByKey(XML_NAMESPACE_TABLE, GetXMLToken(XML_FILTER_AND)); + if (aConnection == sheet::FilterConnection_AND) + { + rExport.StartElement( aName, sal_True); + bOpenAndElement = sal_True; + } + else + bOpenAndElement = sal_False; + for (sal_Int32 i = 1; i < nTableFilterFields; ++i) + { + if (aConnection != aTableFilterFields[i].Connection) + { + aConnection = aTableFilterFields[i].Connection; + if (aTableFilterFields[i].Connection == sheet::FilterConnection_AND) + { + rExport.StartElement( aName, sal_True ); + bOpenAndElement = sal_True; + WriteCondition(aPrevFilterField, bIsCaseSensitive, bUseRegularExpressions); + aPrevFilterField = aTableFilterFields[i]; + if (i == nTableFilterFields - 1) + { + WriteCondition(aPrevFilterField, bIsCaseSensitive, bUseRegularExpressions); + rExport.EndElement(aName, sal_True); + bOpenAndElement = sal_False; + } + } + else + { + WriteCondition(aPrevFilterField, bIsCaseSensitive, bUseRegularExpressions); + aPrevFilterField = aTableFilterFields[i]; + if (bOpenAndElement) + { + rExport.EndElement(aName, sal_True); + bOpenAndElement = sal_False; + } + if (i == nTableFilterFields - 1) + { + WriteCondition(aPrevFilterField, bIsCaseSensitive, bUseRegularExpressions); + } + } + } + else + { + WriteCondition(aPrevFilterField, bIsCaseSensitive, bUseRegularExpressions); + aPrevFilterField = aTableFilterFields[i]; + if (i == nTableFilterFields - 1) + WriteCondition(aPrevFilterField, bIsCaseSensitive, bUseRegularExpressions); + } + } + if(bOpenAndElement) + rExport.EndElement(aName, sal_True); + } + } + } +} + +void ScXMLExportDatabaseRanges::WriteSortDescriptor(const uno::Sequence <beans::PropertyValue> aSortProperties) +{ + uno::Sequence <table::TableSortField> aSortFields; + sal_Bool bBindFormatsToContent (sal_True); + sal_Bool bCopyOutputData (sal_False); +// sal_Bool bIsCaseSensitive (sal_False); + sal_Bool bIsUserListEnabled (sal_False); + table::CellAddress aOutputPosition; + sal_Int32 nUserListIndex = 0; + sal_Int32 nProperties = aSortProperties.getLength(); + sal_Int32 i; + for (i = 0; i < nProperties; ++i) + { + if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_BINDFMT) == 0) + bBindFormatsToContent = ::cppu::any2bool(aSortProperties[i].Value); + else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_COPYOUT) == 0) + bCopyOutputData = ::cppu::any2bool(aSortProperties[i].Value); +// no longer supported +/* else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_ISCASE) == 0) + bIsCaseSensitive = ::cppu::any2bool(aSortProperties[i].Value);*/ + else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_ISULIST) == 0) + bIsUserListEnabled = ::cppu::any2bool(aSortProperties[i].Value); + else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_OUTPOS) == 0) + aSortProperties[i].Value >>= aOutputPosition; + else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_UINDEX) == 0) + aSortProperties[i].Value >>= nUserListIndex; + else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_SORTFLD) == 0) + aSortProperties[i].Value >>= aSortFields; +// no longer supported +/* else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_COLLLOC) == 0) + aSortProperties[i].Value >>= aCollatorLocale; + else if (aSortProperties[i].Name.compareToAscii(SC_UNONAME_COLLALG) == 0) + aSortProperties[i].Value >>= sCollatorAlgorithm;*/ + } + sal_Int32 nSortFields = aSortFields.getLength(); + if (nSortFields > 0) + { + if (!bBindFormatsToContent) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_BIND_STYLES_TO_CONTENT, XML_FALSE); + if (bCopyOutputData) + { + rtl::OUString sOUCellAddress; + ScRangeStringConverter::GetStringFromAddress( sOUCellAddress, aOutputPosition, pDoc, ::formula::FormulaGrammar::CONV_OOO ); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, sOUCellAddress); + } +// no longer supported +// if (bIsCaseSensitive) +// rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE); + + if (aSortFields[0].IsCaseSensitive) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE); +#ifdef DBG_UTIL + sal_Bool bCaseSensitive(aSortFields[0].IsCaseSensitive); + for (i = 1; i < nSortFields; ++i) + { + DBG_ASSERT(bCaseSensitive == aSortFields[i].IsCaseSensitive, "seems that it is now possible to have every field case sensitive"); + } +#endif +// no longer supported +/* if (aCollatorLocale.Language.getLength()) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_LANGUAGE, aCollatorLocale.Language); + if (aCollatorLocale.Country.getLength()) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_COUNTRY, aCollatorLocale.Country); + if (sCollatorAlgorithm.getLength()) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ALGORITHM, sCollatorAlgorithm);*/ + if (aSortFields[0].CollatorLocale.Language.getLength()) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_LANGUAGE, aSortFields[0].CollatorLocale.Language); + if (aSortFields[0].CollatorLocale.Country.getLength()) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_COUNTRY, aSortFields[0].CollatorLocale.Country); + if (aSortFields[0].CollatorAlgorithm.getLength()) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ALGORITHM, aSortFields[0].CollatorAlgorithm); +#ifdef DBG_UTIL + rtl::OUString sLanguage(aSortFields[0].CollatorLocale.Language); + rtl::OUString sCountry(aSortFields[0].CollatorLocale.Country); + rtl::OUString sAlgorithm(aSortFields[0].CollatorAlgorithm); + for (i = 1; i < nSortFields; ++i) + { + DBG_ASSERT(sLanguage == aSortFields[i].CollatorLocale.Language, "seems that it is now possible to have every field localized"); + DBG_ASSERT(sCountry == aSortFields[i].CollatorLocale.Country, "seems that it is now possible to have every field localized"); + DBG_ASSERT(sAlgorithm == aSortFields[i].CollatorAlgorithm, "seems that it is now possible to have every field localized"); + } +#endif + SvXMLElementExport aElemS(rExport, XML_NAMESPACE_TABLE, XML_SORT, sal_True, sal_True); + rExport.CheckAttrList(); + for (i = 0; i < nSortFields; ++i) + { + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, rtl::OUString::valueOf(aSortFields[i].Field)); + if (!aSortFields[i].IsAscending) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_DESCENDING); + if (!bIsUserListEnabled) + { + switch (aSortFields[i].FieldType) + { + case table::TableSortFieldType_ALPHANUMERIC : + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_TEXT); + break; + case table::TableSortFieldType_AUTOMATIC : + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_AUTOMATIC); + break; + case table::TableSortFieldType_NUMERIC : + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_NUMBER); + break; + default: + { + // added to avoid warnings + } + } + } + else + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_USERLIST)) + rtl::OUString::valueOf(nUserListIndex)); + SvXMLElementExport aElemSb(rExport, XML_NAMESPACE_TABLE, XML_SORT_BY, sal_True, sal_True); + rExport.CheckAttrList(); + } + } +} + +void ScXMLExportDatabaseRanges::WriteSubTotalDescriptor(const com::sun::star::uno::Reference <com::sun::star::sheet::XSubTotalDescriptor> xSubTotalDescriptor, const rtl::OUString sDatabaseRangeName) +{ + uno::Reference <container::XIndexAccess> xIndexAccess (xSubTotalDescriptor, uno::UNO_QUERY); + if (xIndexAccess.is()) + { + sal_Int32 nSubTotalFields = xIndexAccess->getCount(); + if (nSubTotalFields > 0) + { + uno::Reference <beans::XPropertySet> xPropertySet (xSubTotalDescriptor, uno::UNO_QUERY); +// sal_Bool bEnableUserSortList = sal_False; +// sal_Bool bSortAscending = sal_True; +// sal_Int32 nUserSortListIndex = 0; + if (xPropertySet.is()) + { + if (!::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_BINDFMT))))) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_BIND_STYLES_TO_CONTENT, XML_FALSE); + if (::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_INSBRK))))) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PAGE_BREAKS_ON_GROUP_CHANGE, XML_TRUE); + if (::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ISCASE))))) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE); +// bSortAscending = ::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_SORTASCENDING)))); +// if (::cppu::any2bool(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ENABLEUSERSORTLIST))))) +// xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_USERSORTLISTINDEX))) >>= nUserSortListIndex; + } + SvXMLElementExport aElemSTRs(rExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULES, sal_True, sal_True); + rExport.CheckAttrList(); + { + ScDBCollection* pDBCollection = pDoc->GetDBCollection(); + sal_uInt16 nIndex; + pDBCollection->SearchName(sDatabaseRangeName, nIndex); + ScDBData* pDBData = (*pDBCollection)[nIndex]; + ScSubTotalParam aSubTotalParam; + pDBData->GetSubTotalParam(aSubTotalParam); + if (aSubTotalParam.bDoSort) + { + if (!aSubTotalParam.bAscending) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_DESCENDING); + if (aSubTotalParam.bUserDef) + { + rtl::OUString sUserList(RTL_CONSTASCII_USTRINGPARAM(SC_USERLIST)); + sUserList += rtl::OUString::valueOf(aSubTotalParam.nUserIndex); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, sUserList); + } + SvXMLElementExport aElemSGs(rExport, XML_NAMESPACE_TABLE, XML_SORT_GROUPS, sal_True, sal_True); + rExport.CheckAttrList(); + } + } + for (sal_Int32 i = 0; i < nSubTotalFields; ++i) + { + uno::Reference <sheet::XSubTotalField> xSubTotalField(xIndexAccess->getByIndex(i), uno::UNO_QUERY); + if (xSubTotalField.is()) + { + sal_Int32 nGroupColumn = xSubTotalField->getGroupColumn(); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUP_BY_FIELD_NUMBER, rtl::OUString::valueOf(nGroupColumn)); + SvXMLElementExport aElemSTR(rExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULE, sal_True, sal_True); + rExport.CheckAttrList(); + uno::Sequence <sheet::SubTotalColumn> aSubTotalColumns = xSubTotalField->getSubTotalColumns(); + sal_Int32 nSubTotalColumns = aSubTotalColumns.getLength(); + for (sal_Int32 j = 0; j < nSubTotalColumns; ++j) + { + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, rtl::OUString::valueOf(aSubTotalColumns[j].Column)); + rtl::OUString sFunction; + ScXMLConverter::GetStringFromFunction( sFunction, aSubTotalColumns[j].Function ); + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FUNCTION, sFunction); + SvXMLElementExport aElemSTF(rExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_FIELD, sal_True, sal_True); + rExport.CheckAttrList(); + } + } + } + } + } +} + +void ScXMLExportDatabaseRanges::WriteDatabaseRanges(const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xSpreadDoc) +{ + pDoc = rExport.GetDocument(); + if (pDoc) + { + uno::Reference <beans::XPropertySet> xPropertySet (xSpreadDoc, uno::UNO_QUERY); + if (xPropertySet.is()) + { + uno::Reference <sheet::XDatabaseRanges> xDatabaseRanges(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DATABASERNG))), uno::UNO_QUERY); + rExport.CheckAttrList(); + if (xDatabaseRanges.is()) + { + uno::Sequence <rtl::OUString> aRanges(xDatabaseRanges->getElementNames()); + sal_Int32 nDatabaseRangesCount = aRanges.getLength(); + if (nDatabaseRangesCount > 0) + { + SvXMLElementExport aElemDRs(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_RANGES, sal_True, sal_True); + for (sal_Int32 i = 0; i < nDatabaseRangesCount; ++i) + { + rtl::OUString sDatabaseRangeName(aRanges[i]); + uno::Reference <sheet::XDatabaseRange> xDatabaseRange(xDatabaseRanges->getByName(sDatabaseRangeName), uno::UNO_QUERY); + if (xDatabaseRange.is()) + { + rtl::OUString sOUUnbenannt (ScGlobal::GetRscString(STR_DB_NONAME)); + if (sOUUnbenannt != sDatabaseRangeName) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, sDatabaseRangeName); + table::CellRangeAddress aRangeAddress(xDatabaseRange->getDataArea()); + rtl::OUString sOUAddress; + ScRangeStringConverter::GetStringFromRange( sOUAddress, aRangeAddress, pDoc, ::formula::FormulaGrammar::CONV_OOO ); + rExport.AddAttribute (XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, sOUAddress); + ScDBCollection* pDBCollection = pDoc->GetDBCollection(); + sal_uInt16 nIndex; + pDBCollection->SearchName(sDatabaseRangeName, nIndex); + ScDBData* pDBData = (*pDBCollection)[nIndex]; + if (pDBData->HasImportSelection()) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_SELECTION, XML_TRUE); + if (pDBData->HasAutoFilter()) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_FILTER_BUTTONS, XML_TRUE); + uno::Reference <beans::XPropertySet> xPropertySetDatabaseRange (xDatabaseRange, uno::UNO_QUERY); + if (xPropertySetDatabaseRange.is()) + { + if (::cppu::any2bool(xPropertySetDatabaseRange->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_KEEPFORM))))) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ON_UPDATE_KEEP_STYLES, XML_TRUE); + if (::cppu::any2bool(xPropertySetDatabaseRange->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_MOVCELLS))))) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ON_UPDATE_KEEP_SIZE, XML_FALSE); + if (::cppu::any2bool(xPropertySetDatabaseRange->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_STRIPDAT))))) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_HAS_PERSISTENT_DATA, XML_FALSE); + } + + uno::Reference< sheet::XSheetFilterDescriptor2 > xSheetFilterDescriptor( + xDatabaseRange->getFilterDescriptor(), uno::UNO_QUERY ); + uno::Sequence <beans::PropertyValue> aSortProperties(xDatabaseRange->getSortDescriptor()); + if (xSheetFilterDescriptor.is()) + { + uno::Reference <beans::XPropertySet> xFilterProperties (xSheetFilterDescriptor, uno::UNO_QUERY); + if (xFilterProperties.is()) + { + if (!::cppu::any2bool(xFilterProperties->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CONTHDR))))) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONTAINS_HEADER, XML_FALSE); + + // #98317#; there is no orientation on the filter +/* table::TableOrientation eFilterOrient(table::TableOrientation_ROWS); + if (::cppu::any2bool(xFilterProperties->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ORIENT))))) + eFilterOrient = table::TableOrientation_ROWS;*/ + + sal_Bool bSortColumns(sal_True); + sal_Bool bFound(sal_False); + sal_Int32 nProperty(0); + while (!bFound && (nProperty < aSortProperties.getLength())) + { + if (aSortProperties[nProperty].Name.compareToAscii(SC_UNONAME_ISSORTCOLUMNS) == 0) + { + bSortColumns = ::cppu::any2bool(aSortProperties[nProperty].Value); + bFound = sal_True; + } + else + ++nProperty; + } + + if (bSortColumns) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_COLUMN); + } + } + sal_Int32 nRefresh( pDBData->GetRefreshDelay() ); + if( nRefresh ) + { + rtl::OUStringBuffer sBuffer; + SvXMLUnitConverter::convertTime( sBuffer, (double)nRefresh / 86400 ); + rExport.AddAttribute( XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, sBuffer.makeStringAndClear() ); + } + SvXMLElementExport aElemDR(rExport, XML_NAMESPACE_TABLE, XML_DATABASE_RANGE, sal_True, sal_True); + rExport.CheckAttrList(); + WriteImportDescriptor(xDatabaseRange->getImportDescriptor()); + if (xSheetFilterDescriptor.is()) + WriteFilterDescriptor(xSheetFilterDescriptor, sDatabaseRangeName); + WriteSortDescriptor(aSortProperties); + WriteSubTotalDescriptor(xDatabaseRange->getSubTotalDescriptor(), sDatabaseRangeName); + } + } + } + } + } + } +} diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.hxx b/sc/source/filter/xml/XMLExportDatabaseRanges.hxx new file mode 100644 index 000000000000..a581eb1271f1 --- /dev/null +++ b/sc/source/filter/xml/XMLExportDatabaseRanges.hxx @@ -0,0 +1,62 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLEXPORTDATABASERANGES_HXX +#define SC_XMLEXPORTDATABASERANGES_HXX + +#include <com/sun/star/uno/Sequence.h> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/sheet/FilterOperator2.hpp> +#include <com/sun/star/sheet/TableFilterField2.hpp> +#include <com/sun/star/sheet/XSheetFilterDescriptor2.hpp> +#include <com/sun/star/sheet/XSubTotalDescriptor.hpp> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> + +class ScXMLExport; +class ScDocument; +class ScMyEmptyDatabaseRangesContainer; + +class ScXMLExportDatabaseRanges +{ + ScXMLExport& rExport; + ScDocument* pDoc; + + void WriteImportDescriptor(const com::sun::star::uno::Sequence <com::sun::star::beans::PropertyValue> aImportDescriptor); + rtl::OUString getOperatorXML(const long aFilterOperator, const sal_Bool bUseRegularExpressions) const; + void WriteCondition(const com::sun::star::sheet::TableFilterField2& aFilterField, sal_Bool bIsCaseSensitive, sal_Bool bUseRegularExpressions); + void WriteFilterDescriptor(const com::sun::star::uno::Reference <com::sun::star::sheet::XSheetFilterDescriptor2>& xSheetFilterDescriptor, const rtl::OUString sDatabaseRangeName); + void WriteSortDescriptor(const com::sun::star::uno::Sequence <com::sun::star::beans::PropertyValue> aSortProperties); + void WriteSubTotalDescriptor(const com::sun::star::uno::Reference <com::sun::star::sheet::XSubTotalDescriptor> xSubTotalDescriptor, const rtl::OUString sDatabaseRangeName); +public: + ScXMLExportDatabaseRanges(ScXMLExport& rExport); + ~ScXMLExportDatabaseRanges(); + ScMyEmptyDatabaseRangesContainer GetEmptyDatabaseRanges(); + void WriteDatabaseRanges(const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xSpreadDoc); +}; + +#endif + diff --git a/sc/source/filter/xml/XMLExportIterator.cxx b/sc/source/filter/xml/XMLExportIterator.cxx new file mode 100644 index 000000000000..154fdebed95e --- /dev/null +++ b/sc/source/filter/xml/XMLExportIterator.cxx @@ -0,0 +1,892 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- +#include "XMLExportIterator.hxx" +#include <com/sun/star/text/XSimpleText.hpp> +#include <com/sun/star/sheet/XCellAddressable.hpp> +#include <com/sun/star/sheet/CellFlags.hpp> +#include <com/sun/star/sheet/XSheetAnnotationsSupplier.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <tools/debug.hxx> +#include <xmloff/xmlnmspe.hxx> +#include "dociter.hxx" +#include "convuno.hxx" +#include "xmlexprt.hxx" +#include "XMLExportSharedData.hxx" +#include "XMLStylesExportHelper.hxx" +#include "document.hxx" + +#include <algorithm> + +using ::rtl::OUString; +using namespace ::com::sun::star; + +//============================================================================== + +ScMyIteratorBase::ScMyIteratorBase() +{ +} + +ScMyIteratorBase::~ScMyIteratorBase() +{ +} + +void ScMyIteratorBase::UpdateAddress( table::CellAddress& rCellAddress ) +{ + table::CellAddress aNewAddr( rCellAddress ); + if( GetFirstAddress( aNewAddr ) ) + { + if( (aNewAddr.Sheet == rCellAddress.Sheet) && + ((aNewAddr.Row < rCellAddress.Row) || + ((aNewAddr.Row == rCellAddress.Row) && (aNewAddr.Column < rCellAddress.Column))) ) + rCellAddress = aNewAddr; + } +} + + +//============================================================================== + +sal_Bool ScMyShape::operator<(const ScMyShape& aShape) const +{ + if( aAddress.Tab() != aShape.aAddress.Tab() ) + return (aAddress.Tab() < aShape.aAddress.Tab()); + else if( aAddress.Row() != aShape.aAddress.Row() ) + return (aAddress.Row() < aShape.aAddress.Row()); + else + return (aAddress.Col() < aShape.aAddress.Col()); +} + +ScMyShapesContainer::ScMyShapesContainer() + : aShapeList() +{ +} + +ScMyShapesContainer::~ScMyShapesContainer() +{ +} + +void ScMyShapesContainer::AddNewShape( const ScMyShape& aShape ) +{ + aShapeList.push_back(aShape); +} + +sal_Bool ScMyShapesContainer::GetFirstAddress( table::CellAddress& rCellAddress ) +{ + sal_Int32 nTable(rCellAddress.Sheet); + if( !aShapeList.empty() ) + { + ScUnoConversion::FillApiAddress( rCellAddress, aShapeList.begin()->aAddress ); + return (nTable == rCellAddress.Sheet); + } + return sal_False; +} + +void ScMyShapesContainer::SetCellData( ScMyCell& rMyCell ) +{ + rMyCell.aShapeList.clear(); + ScAddress aAddress; + ScUnoConversion::FillScAddress( aAddress, rMyCell.aCellAddress ); + + ScMyShapeList::iterator aItr(aShapeList.begin()); + ScMyShapeList::iterator aEndItr(aShapeList.end()); + while( (aItr != aEndItr) && (aItr->aAddress == aAddress) ) + { + rMyCell.aShapeList.push_back(*aItr); + aItr = aShapeList.erase(aItr); + } + rMyCell.bHasShape = !rMyCell.aShapeList.empty(); +} + +void ScMyShapesContainer::SkipTable(SCTAB nSkip) +{ + ScMyShapeList::iterator aItr = aShapeList.begin(); + while( (aItr != aShapeList.end()) && (aItr->aAddress.Tab() == nSkip) ) + aItr = aShapeList.erase(aItr); +} + +void ScMyShapesContainer::Sort() +{ + aShapeList.sort(); +} + +sal_Bool ScMyNoteShape::operator<(const ScMyNoteShape& aNote) const +{ + if( aPos.Tab() != aNote.aPos.Tab() ) + return (aPos.Tab() < aNote.aPos.Tab()); + else if( aPos.Row() != aNote.aPos.Row() ) + return (aPos.Row() < aNote.aPos.Row()); + else + return (aPos.Col() < aNote.aPos.Col()); +} + +ScMyNoteShapesContainer::ScMyNoteShapesContainer() + : aNoteShapeList() +{ +} + +ScMyNoteShapesContainer::~ScMyNoteShapesContainer() +{ +} + +void ScMyNoteShapesContainer::AddNewNote( const ScMyNoteShape& aNote ) +{ + aNoteShapeList.push_back(aNote); +} + +sal_Bool ScMyNoteShapesContainer::GetFirstAddress( table::CellAddress& rCellAddress ) +{ + sal_Int16 nTable = rCellAddress.Sheet; + if( !aNoteShapeList.empty() ) + { + ScUnoConversion::FillApiAddress( rCellAddress, aNoteShapeList.begin()->aPos ); + return (nTable == rCellAddress.Sheet); + } + return sal_False; +} + +void ScMyNoteShapesContainer::SetCellData( ScMyCell& rMyCell ) +{ + rMyCell.xNoteShape.clear(); + ScAddress aAddress; + ScUnoConversion::FillScAddress( aAddress, rMyCell.aCellAddress ); + + ScMyNoteShapeList::iterator aItr = aNoteShapeList.begin(); + while( (aItr != aNoteShapeList.end()) && (aItr->aPos == aAddress) ) + { + rMyCell.xNoteShape = aItr->xShape; + aItr = aNoteShapeList.erase(aItr); + } +} + +void ScMyNoteShapesContainer::SkipTable(SCTAB nSkip) +{ + ScMyNoteShapeList::iterator aItr = aNoteShapeList.begin(); + while( (aItr != aNoteShapeList.end()) && (aItr->aPos.Tab() == nSkip) ) + aItr = aNoteShapeList.erase(aItr); +} + +void ScMyNoteShapesContainer::Sort() +{ + aNoteShapeList.sort(); +} + +//============================================================================== + +sal_Bool ScMyMergedRange::operator<(const ScMyMergedRange& aRange) const +{ + if( aCellRange.Sheet != aRange.aCellRange.Sheet ) + return (aCellRange.Sheet < aRange.aCellRange.Sheet); + else if( aCellRange.StartRow != aRange.aCellRange.StartRow ) + return (aCellRange.StartRow < aRange.aCellRange.StartRow); + else + return (aCellRange.StartColumn < aRange.aCellRange.StartColumn); +} + + +ScMyMergedRangesContainer::ScMyMergedRangesContainer() + : aRangeList() +{ +} + +ScMyMergedRangesContainer::~ScMyMergedRangesContainer() +{ +} + +void ScMyMergedRangesContainer::AddRange(const table::CellRangeAddress aMergedRange) +{ + sal_Int32 nStartRow(aMergedRange.StartRow); + sal_Int32 nEndRow(aMergedRange.EndRow); + + ScMyMergedRange aRange; + aRange.bIsFirst = sal_True; + aRange.aCellRange = aMergedRange; + aRange.aCellRange.EndRow = nStartRow; + aRange.nRows = nEndRow - nStartRow + 1; + aRangeList.push_back( aRange ); + + aRange.bIsFirst = sal_False; + aRange.nRows = 0; + for( sal_Int32 nRow = nStartRow + 1; nRow <= nEndRow; ++nRow ) + { + aRange.aCellRange.StartRow = aRange.aCellRange.EndRow = nRow; + aRangeList.push_back(aRange); + } +} + +sal_Bool ScMyMergedRangesContainer::GetFirstAddress( table::CellAddress& rCellAddress ) +{ + sal_Int32 nTable(rCellAddress.Sheet); + if( !aRangeList.empty() ) + { + ScUnoConversion::FillApiStartAddress( rCellAddress, aRangeList.begin()->aCellRange ); + return (nTable == rCellAddress.Sheet); + } + return sal_False; +} + +void ScMyMergedRangesContainer::SetCellData( ScMyCell& rMyCell ) +{ + rMyCell.bIsMergedBase = rMyCell.bIsCovered = sal_False; + ScMyMergedRangeList::iterator aItr(aRangeList.begin()); + if( aItr != aRangeList.end() ) + { + table::CellAddress aFirstAddress; + ScUnoConversion::FillApiStartAddress( aFirstAddress, aItr->aCellRange ); + if( aFirstAddress == rMyCell.aCellAddress ) + { + rMyCell.aMergeRange = aItr->aCellRange; + if (aItr->bIsFirst) + rMyCell.aMergeRange.EndRow = rMyCell.aMergeRange.StartRow + aItr->nRows - 1; + rMyCell.bIsMergedBase = aItr->bIsFirst; + rMyCell.bIsCovered = !aItr->bIsFirst; + if( aItr->aCellRange.StartColumn < aItr->aCellRange.EndColumn ) + { + ++(aItr->aCellRange.StartColumn); + aItr->bIsFirst = sal_False; + } + else + aRangeList.erase(aItr); + } + } +} + +void ScMyMergedRangesContainer::SkipTable(SCTAB nSkip) +{ + ScMyMergedRangeList::iterator aItr = aRangeList.begin(); + while( (aItr != aRangeList.end()) && (aItr->aCellRange.Sheet == nSkip) ) + aItr = aRangeList.erase(aItr); +} + +void ScMyMergedRangesContainer::Sort() +{ + aRangeList.sort(); +} + +//============================================================================== + +sal_Bool ScMyAreaLink::Compare( const ScMyAreaLink& rAreaLink ) const +{ + return (GetRowCount() == rAreaLink.GetRowCount()) && + (sFilter == rAreaLink.sFilter) && + (sFilterOptions == rAreaLink.sFilterOptions) && + (sURL == rAreaLink.sURL) && + (sSourceStr == rAreaLink.sSourceStr); +} + +sal_Bool ScMyAreaLink::operator<(const ScMyAreaLink& rAreaLink ) const +{ + if( aDestRange.Sheet != rAreaLink.aDestRange.Sheet ) + return (aDestRange.Sheet < rAreaLink.aDestRange.Sheet); + else if( aDestRange.StartRow != rAreaLink.aDestRange.StartRow ) + return (aDestRange.StartRow < rAreaLink.aDestRange.StartRow); + else + return (aDestRange.StartColumn < rAreaLink.aDestRange.StartColumn); +} + +ScMyAreaLinksContainer::ScMyAreaLinksContainer() : + aAreaLinkList() +{ +} + +ScMyAreaLinksContainer::~ScMyAreaLinksContainer() +{ +} + +sal_Bool ScMyAreaLinksContainer::GetFirstAddress( table::CellAddress& rCellAddress ) +{ + sal_Int32 nTable(rCellAddress.Sheet); + if( !aAreaLinkList.empty() ) + { + ScUnoConversion::FillApiStartAddress( rCellAddress, aAreaLinkList.begin()->aDestRange ); + return (nTable == rCellAddress.Sheet); + } + return sal_False; +} + +void ScMyAreaLinksContainer::SetCellData( ScMyCell& rMyCell ) +{ + rMyCell.bHasAreaLink = sal_False; + ScMyAreaLinkList::iterator aItr(aAreaLinkList.begin()); + if( aItr != aAreaLinkList.end() ) + { + table::CellAddress aAddress; + ScUnoConversion::FillApiStartAddress( aAddress, aItr->aDestRange ); + if( aAddress == rMyCell.aCellAddress ) + { + rMyCell.bHasAreaLink = sal_True; + rMyCell.aAreaLink = *aItr; + aItr = aAreaLinkList.erase( aItr ); + sal_Bool bFound = sal_True; + while (aItr != aAreaLinkList.end() && bFound) + { + ScUnoConversion::FillApiStartAddress( aAddress, aItr->aDestRange ); + if (aAddress == rMyCell.aCellAddress) + { + DBG_ERROR("more than one linked range on one cell"); + aItr = aAreaLinkList.erase( aItr ); + } + else + bFound = sal_False; + } + } + } +} + +void ScMyAreaLinksContainer::SkipTable(SCTAB nSkip) +{ + ScMyAreaLinkList::iterator aItr = aAreaLinkList.begin(); + while( (aItr != aAreaLinkList.end()) && (aItr->aDestRange.Sheet == nSkip) ) + aItr = aAreaLinkList.erase(aItr); +} + +void ScMyAreaLinksContainer::Sort() +{ + aAreaLinkList.sort(); +} + +//============================================================================== + +ScMyCellRangeAddress::ScMyCellRangeAddress(const table::CellRangeAddress& rRange) + : table::CellRangeAddress(rRange) +{ +} + +sal_Bool ScMyCellRangeAddress::operator<(const ScMyCellRangeAddress& rRange ) const +{ + if( Sheet != rRange.Sheet ) + return (Sheet < rRange.Sheet); + else if( StartRow != rRange.StartRow ) + return (StartRow < rRange.StartRow); + else + return (StartColumn < rRange.StartColumn); +} + +ScMyEmptyDatabaseRangesContainer::ScMyEmptyDatabaseRangesContainer() + : aDatabaseList() +{ +} + +ScMyEmptyDatabaseRangesContainer::~ScMyEmptyDatabaseRangesContainer() +{ +} + +void ScMyEmptyDatabaseRangesContainer::AddNewEmptyDatabaseRange(const table::CellRangeAddress& aCellRange) +{ + sal_Int32 nStartRow(aCellRange.StartRow); + sal_Int32 nEndRow(aCellRange.EndRow); + ScMyCellRangeAddress aRange( aCellRange ); + for( sal_Int32 nRow = nStartRow; nRow <= nEndRow; ++nRow ) + { + aRange.StartRow = aRange.EndRow = nRow; + aDatabaseList.push_back( aRange ); + } +} + +sal_Bool ScMyEmptyDatabaseRangesContainer::GetFirstAddress( table::CellAddress& rCellAddress ) +{ + sal_Int32 nTable(rCellAddress.Sheet); + if( !aDatabaseList.empty() ) + { + ScUnoConversion::FillApiStartAddress( rCellAddress, *(aDatabaseList.begin()) ); + return (nTable == rCellAddress.Sheet); + } + return sal_False; +} + +void ScMyEmptyDatabaseRangesContainer::SetCellData( ScMyCell& rMyCell ) +{ + rMyCell.bHasEmptyDatabase = sal_False; + ScMyEmptyDatabaseRangeList::iterator aItr(aDatabaseList.begin()); + if( aItr != aDatabaseList.end() ) + { + table::CellAddress aFirstAddress; + ScUnoConversion::FillApiStartAddress( aFirstAddress, *aItr ); + if( aFirstAddress == rMyCell.aCellAddress ) + { + rMyCell.bHasEmptyDatabase = sal_True; + if( aItr->StartColumn < aItr->EndColumn ) + ++(aItr->StartColumn); + else + aDatabaseList.erase(aItr); + } + } +} + +void ScMyEmptyDatabaseRangesContainer::SkipTable(SCTAB nSkip) +{ + ScMyEmptyDatabaseRangeList::iterator aItr = aDatabaseList.begin(); + while( (aItr != aDatabaseList.end()) && (aItr->Sheet == nSkip) ) + aItr = aDatabaseList.erase(aItr); +} + +void ScMyEmptyDatabaseRangesContainer::Sort() +{ + aDatabaseList.sort(); +} + +//============================================================================== + +sal_Bool ScMyDetectiveObj::operator<( const ScMyDetectiveObj& rDetObj) const +{ + if( aPosition.Sheet != rDetObj.aPosition.Sheet ) + return (aPosition.Sheet < rDetObj.aPosition.Sheet); + else if( aPosition.Row != rDetObj.aPosition.Row ) + return (aPosition.Row < rDetObj.aPosition.Row); + else + return (aPosition.Column < rDetObj.aPosition.Column); +} + +ScMyDetectiveObjContainer::ScMyDetectiveObjContainer() : + aDetectiveObjList() +{ +} + +ScMyDetectiveObjContainer::~ScMyDetectiveObjContainer() +{ +} + +void ScMyDetectiveObjContainer::AddObject( ScDetectiveObjType eObjType, const SCTAB nSheet, + const ScAddress& rPosition, const ScRange& rSourceRange, + sal_Bool bHasError ) +{ + if( (eObjType == SC_DETOBJ_ARROW) || + (eObjType == SC_DETOBJ_FROMOTHERTAB) || + (eObjType == SC_DETOBJ_TOOTHERTAB) || + (eObjType == SC_DETOBJ_CIRCLE) ) + { + ScMyDetectiveObj aDetObj; + aDetObj.eObjType = eObjType; + if( eObjType == SC_DETOBJ_TOOTHERTAB ) + ScUnoConversion::FillApiAddress( aDetObj.aPosition, rSourceRange.aStart ); + else + ScUnoConversion::FillApiAddress( aDetObj.aPosition, rPosition ); + ScUnoConversion::FillApiRange( aDetObj.aSourceRange, rSourceRange ); + + // #111064#; take the sheet where the object is found and not the sheet given in the ranges, because they are not always true + if (eObjType != SC_DETOBJ_FROMOTHERTAB) + { + // if the ObjType == SC_DETOBJ_FROMOTHERTAB then the SourceRange is not used and so it has not to be tested and changed + DBG_ASSERT(aDetObj.aPosition.Sheet == aDetObj.aSourceRange.Sheet, "It seems to be possible to have different sheets"); + aDetObj.aSourceRange.Sheet = nSheet; + } + aDetObj.aPosition.Sheet = nSheet; + + aDetObj.bHasError = bHasError; + aDetectiveObjList.push_back( aDetObj ); + } +} + +sal_Bool ScMyDetectiveObjContainer::GetFirstAddress( table::CellAddress& rCellAddress ) +{ + sal_Int32 nTable(rCellAddress.Sheet); + if( !aDetectiveObjList.empty() ) + { + rCellAddress = aDetectiveObjList.begin()->aPosition; + return (nTable == rCellAddress.Sheet); + } + return sal_False; +} + +void ScMyDetectiveObjContainer::SetCellData( ScMyCell& rMyCell ) +{ + rMyCell.aDetectiveObjVec.clear(); + ScMyDetectiveObjList::iterator aItr(aDetectiveObjList.begin()); + ScMyDetectiveObjList::iterator aEndItr(aDetectiveObjList.end()); + while( (aItr != aEndItr) && (aItr->aPosition == rMyCell.aCellAddress) ) + { + rMyCell.aDetectiveObjVec.push_back( *aItr ); + aItr = aDetectiveObjList.erase( aItr ); + } + rMyCell.bHasDetectiveObj = (rMyCell.aDetectiveObjVec.size() != 0); +} + +void ScMyDetectiveObjContainer::SkipTable(SCTAB nSkip) +{ + ScMyDetectiveObjList::iterator aItr = aDetectiveObjList.begin(); + while( (aItr != aDetectiveObjList.end()) && (aItr->aPosition.Sheet == nSkip) ) + aItr = aDetectiveObjList.erase(aItr); +} + +void ScMyDetectiveObjContainer::Sort() +{ + aDetectiveObjList.sort(); +} + +//============================================================================== + +sal_Bool ScMyDetectiveOp::operator<( const ScMyDetectiveOp& rDetOp) const +{ + if( aPosition.Sheet != rDetOp.aPosition.Sheet ) + return (aPosition.Sheet < rDetOp.aPosition.Sheet); + else if( aPosition.Row != rDetOp.aPosition.Row ) + return (aPosition.Row < rDetOp.aPosition.Row); + else + return (aPosition.Column < rDetOp.aPosition.Column); +} + +ScMyDetectiveOpContainer::ScMyDetectiveOpContainer() : + aDetectiveOpList() +{ +} + +ScMyDetectiveOpContainer::~ScMyDetectiveOpContainer() +{ +} + +void ScMyDetectiveOpContainer::AddOperation( ScDetOpType eOpType, const ScAddress& rPosition, sal_uInt32 nIndex ) +{ + ScMyDetectiveOp aDetOp; + aDetOp.eOpType = eOpType; + ScUnoConversion::FillApiAddress( aDetOp.aPosition, rPosition ); + aDetOp.nIndex = nIndex; + aDetectiveOpList.push_back( aDetOp ); +} + +sal_Bool ScMyDetectiveOpContainer::GetFirstAddress( table::CellAddress& rCellAddress ) +{ + sal_Int32 nTable(rCellAddress.Sheet); + if( !aDetectiveOpList.empty() ) + { + rCellAddress = aDetectiveOpList.begin()->aPosition; + return (nTable == rCellAddress.Sheet); + } + return sal_False; +} + +void ScMyDetectiveOpContainer::SetCellData( ScMyCell& rMyCell ) +{ + rMyCell.aDetectiveOpVec.clear(); + ScMyDetectiveOpList::iterator aItr(aDetectiveOpList.begin()); + ScMyDetectiveOpList::iterator aEndItr(aDetectiveOpList.end()); + while( (aItr != aEndItr) && (aItr->aPosition == rMyCell.aCellAddress) ) + { + rMyCell.aDetectiveOpVec.push_back( *aItr ); + aItr = aDetectiveOpList.erase( aItr ); + } + rMyCell.bHasDetectiveOp = (rMyCell.aDetectiveOpVec.size() != 0); +} + +void ScMyDetectiveOpContainer::SkipTable(SCTAB nSkip) +{ + ScMyDetectiveOpList::iterator aItr = aDetectiveOpList.begin(); + while( (aItr != aDetectiveOpList.end()) && (aItr->aPosition.Sheet == nSkip) ) + aItr = aDetectiveOpList.erase(aItr); +} + +void ScMyDetectiveOpContainer::Sort() +{ + aDetectiveOpList.sort(); +} + +//============================================================================== + +ScMyCell::ScMyCell() : + aShapeList(), + aDetectiveObjVec(), + nValidationIndex(-1), + pBaseCell(NULL), + bIsAutoStyle( sal_False ), + bHasShape( sal_False ), + bIsMergedBase( sal_False ), + bIsCovered( sal_False ), + bHasAreaLink( sal_False ), + bHasEmptyDatabase( sal_False ), + bHasDetectiveObj( sal_False ), + bHasDetectiveOp( sal_False ), + bIsEditCell( sal_False ), + bKnowWhetherIsEditCell( sal_False ), + bHasStringValue( sal_False ), + bHasDoubleValue( sal_False ), + bHasXText( sal_False ), + bIsMatrixBase( sal_False ), + bIsMatrixCovered( sal_False ), + bHasAnnotation( sal_False ) +{ +} + +ScMyCell::~ScMyCell() +{ +} + +//============================================================================== + +sal_Bool ScMyExportAnnotation::operator<(const ScMyExportAnnotation& rAnno) const +{ + if( aCellAddress.Row != rAnno.aCellAddress.Row ) + return (aCellAddress.Row < rAnno.aCellAddress.Row); + else + return (aCellAddress.Column < rAnno.aCellAddress.Column); +} + + +ScMyNotEmptyCellsIterator::ScMyNotEmptyCellsIterator(ScXMLExport& rTempXMLExport) + : pShapes(NULL), + pNoteShapes(NULL), + pEmptyDatabaseRanges(NULL), + pMergedRanges(NULL), + pAreaLinks(NULL), + pDetectiveObj(NULL), + pDetectiveOp(NULL), + rExport(rTempXMLExport), + pCellItr(NULL), + nCurrentTable(SCTAB_MAX) +{ +} + +ScMyNotEmptyCellsIterator::~ScMyNotEmptyCellsIterator() +{ + Clear(); +} + +void ScMyNotEmptyCellsIterator::Clear() +{ + if (pCellItr) + delete pCellItr; + if (!aAnnotations.empty()) + { + DBG_ERROR("not all Annotations saved"); + aAnnotations.clear(); + } + pCellItr = NULL; + pShapes = NULL; + pNoteShapes = NULL; + pMergedRanges = NULL; + pAreaLinks = NULL; + pEmptyDatabaseRanges = NULL; + pDetectiveObj = NULL; + pDetectiveOp = NULL; + nCurrentTable = SCTAB_MAX; +} + +void ScMyNotEmptyCellsIterator::UpdateAddress( table::CellAddress& rAddress ) +{ + if( pCellItr->ReturnNext( nCellCol, nCellRow ) ) + { + rAddress.Column = nCellCol; + rAddress.Row = nCellRow; + } +} + +void ScMyNotEmptyCellsIterator::SetCellData( ScMyCell& rMyCell, table::CellAddress& rAddress ) +{ + rMyCell.aCellAddress = rAddress; + rMyCell.bHasStringValue = sal_False; + rMyCell.bHasDoubleValue = sal_False; + rMyCell.bHasXText = sal_False; + rMyCell.bKnowWhetherIsEditCell = sal_False; + rMyCell.bIsEditCell = sal_False; + if( (nCellCol == rAddress.Column) && (nCellRow == rAddress.Row) ) + pCellItr->GetNext( nCellCol, nCellRow ); +} + +void ScMyNotEmptyCellsIterator::SetMatrixCellData( ScMyCell& rMyCell ) +{ + rMyCell.bIsMatrixCovered = sal_False; + rMyCell.bIsMatrixBase = sal_False; + + sal_Bool bIsMatrixBase(sal_False); + + ScAddress aScAddress; + ScUnoConversion::FillScAddress( aScAddress, rMyCell.aCellAddress ); + CellType eCalcType = rExport.GetDocument()->GetCellType( aScAddress ); + switch (eCalcType) + { + case CELLTYPE_VALUE: + rMyCell.nType = table::CellContentType_VALUE; + break; + case CELLTYPE_STRING: + case CELLTYPE_EDIT: + rMyCell.nType = table::CellContentType_TEXT; + break; + case CELLTYPE_FORMULA: + rMyCell.nType = table::CellContentType_FORMULA; + break; + default: + rMyCell.nType = table::CellContentType_EMPTY; + } + + if (rMyCell.nType == table::CellContentType_FORMULA) + if( rExport.IsMatrix( aScAddress, rMyCell.aMatrixRange, bIsMatrixBase ) ) + { + rMyCell.bIsMatrixBase = bIsMatrixBase; + rMyCell.bIsMatrixCovered = !bIsMatrixBase; + } +} + +void ScMyNotEmptyCellsIterator::HasAnnotation(ScMyCell& aCell) +{ + aCell.bHasAnnotation = sal_False; + if (!aAnnotations.empty()) + { + ScMyExportAnnotationList::iterator aItr(aAnnotations.begin()); + if ((aCell.aCellAddress.Column == aItr->aCellAddress.Column) && + (aCell.aCellAddress.Row == aItr->aCellAddress.Row)) + { + aCell.xAnnotation.set(aItr->xAnnotation); + uno::Reference<text::XSimpleText> xSimpleText(aCell.xAnnotation, uno::UNO_QUERY); + if (aCell.xAnnotation.is() && xSimpleText.is()) + { + aCell.sAnnotationText = xSimpleText->getString(); + if (aCell.sAnnotationText.getLength()) + aCell.bHasAnnotation = sal_True; + } + aAnnotations.erase(aItr); + } + } + + // test - bypass the API + // if (xCellRange.is()) + // aCell.xCell.set(xCellRange->getCellByPosition(aCell.aCellAddress.Column, aCell.aCellAddress.Row)); +} + +void ScMyNotEmptyCellsIterator::SetCurrentTable(const SCTAB nTable, + uno::Reference<sheet::XSpreadsheet>& rxTable) +{ + DBG_ASSERT(aAnnotations.empty(), "not all Annotations saved"); + aLastAddress.Row = 0; + aLastAddress.Column = 0; + aLastAddress.Sheet = nTable; + if (nCurrentTable != nTable) + { + nCurrentTable = nTable; + if (pCellItr) + delete pCellItr; + pCellItr = new ScHorizontalCellIterator(rExport.GetDocument(), nCurrentTable, 0, 0, + static_cast<SCCOL>(rExport.GetSharedData()->GetLastColumn(nCurrentTable)), static_cast<SCROW>(rExport.GetSharedData()->GetLastRow(nCurrentTable))); + xTable.set(rxTable); + xCellRange.set(xTable, uno::UNO_QUERY); + uno::Reference<sheet::XSheetAnnotationsSupplier> xSheetAnnotationsSupplier (xTable, uno::UNO_QUERY); + if (xSheetAnnotationsSupplier.is()) + { + uno::Reference<container::XEnumerationAccess> xAnnotationAccess ( xSheetAnnotationsSupplier->getAnnotations(), uno::UNO_QUERY); + if (xAnnotationAccess.is()) + { + uno::Reference<container::XEnumeration> xAnnotations(xAnnotationAccess->createEnumeration()); + if (xAnnotations.is()) + { + while (xAnnotations->hasMoreElements()) + { + ScMyExportAnnotation aAnnotation; + aAnnotation.xAnnotation.set(xAnnotations->nextElement(), uno::UNO_QUERY); + if (aAnnotation.xAnnotation.is()) + { + aAnnotation.aCellAddress = aAnnotation.xAnnotation->getPosition(); + aAnnotations.push_back(aAnnotation); + } + } + if (!aAnnotations.empty()) + aAnnotations.sort(); + } + } + } + } +} + +void ScMyNotEmptyCellsIterator::SkipTable(SCTAB nSkip) +{ + // Skip entries for a sheet that is copied instead of saving normally. + // Cells (including aAnnotations) are handled separately in SetCurrentTable. + + if( pShapes ) + pShapes->SkipTable(nSkip); + if( pNoteShapes ) + pNoteShapes->SkipTable(nSkip); + if( pEmptyDatabaseRanges ) + pEmptyDatabaseRanges->SkipTable(nSkip); + if( pMergedRanges ) + pMergedRanges->SkipTable(nSkip); + if( pAreaLinks ) + pAreaLinks->SkipTable(nSkip); + if( pDetectiveObj ) + pDetectiveObj->SkipTable(nSkip); + if( pDetectiveOp ) + pDetectiveOp->SkipTable(nSkip); +} + +sal_Bool ScMyNotEmptyCellsIterator::GetNext(ScMyCell& aCell, ScFormatRangeStyles* pCellStyles) +{ + table::CellAddress aAddress( nCurrentTable, MAXCOL + 1, MAXROW + 1 ); + + UpdateAddress( aAddress ); + if( pShapes ) + pShapes->UpdateAddress( aAddress ); + if( pNoteShapes ) + pNoteShapes->UpdateAddress( aAddress ); + if( pEmptyDatabaseRanges ) + pEmptyDatabaseRanges->UpdateAddress( aAddress ); + if( pMergedRanges ) + pMergedRanges->UpdateAddress( aAddress ); + if( pAreaLinks ) + pAreaLinks->UpdateAddress( aAddress ); + if( pDetectiveObj ) + pDetectiveObj->UpdateAddress( aAddress ); + if( pDetectiveOp ) + pDetectiveOp->UpdateAddress( aAddress ); + + sal_Bool bFoundCell((aAddress.Column <= MAXCOL) && (aAddress.Row <= MAXROW)); + if( bFoundCell ) + { + SetCellData( aCell, aAddress ); + if( pShapes ) + pShapes->SetCellData( aCell ); + if( pNoteShapes ) + pNoteShapes->SetCellData( aCell ); + if( pEmptyDatabaseRanges ) + pEmptyDatabaseRanges->SetCellData( aCell ); + if( pMergedRanges ) + pMergedRanges->SetCellData( aCell ); + if( pAreaLinks ) + pAreaLinks->SetCellData( aCell ); + if( pDetectiveObj ) + pDetectiveObj->SetCellData( aCell ); + if( pDetectiveOp ) + pDetectiveOp->SetCellData( aCell ); + + HasAnnotation( aCell ); + SetMatrixCellData( aCell ); + sal_Bool bIsAutoStyle; + // Ranges before the previous cell are not needed by ExportFormatRanges anymore and can be removed + sal_Int32 nRemoveBeforeRow = aLastAddress.Row; + aCell.nStyleIndex = pCellStyles->GetStyleNameIndex(aCell.aCellAddress.Sheet, + aCell.aCellAddress.Column, aCell.aCellAddress.Row, + bIsAutoStyle, aCell.nValidationIndex, aCell.nNumberFormat, nRemoveBeforeRow); + aLastAddress = aCell.aCellAddress; + aCell.bIsAutoStyle = bIsAutoStyle; + + //#102799#; if the cell is in a DatabaseRange which should saved empty, the cell should have the type empty + if (aCell.bHasEmptyDatabase) + aCell.nType = table::CellContentType_EMPTY; + } + return bFoundCell; +} + diff --git a/sc/source/filter/xml/XMLExportIterator.hxx b/sc/source/filter/xml/XMLExportIterator.hxx new file mode 100644 index 000000000000..dfd3a4d59ac1 --- /dev/null +++ b/sc/source/filter/xml/XMLExportIterator.hxx @@ -0,0 +1,413 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLEXPORTITERATOR_HXX +#define SC_XMLEXPORTITERATOR_HXX + +#include <vector> +#include <list> +#include <com/sun/star/sheet/XSpreadsheet.hpp> +#include <com/sun/star/table/CellAddress.hpp> +#include <com/sun/star/table/CellRangeAddress.hpp> +#include <com/sun/star/table/XCell.hpp> +#include <com/sun/star/text/XText.hpp> +#include <com/sun/star/sheet/XSheetAnnotation.hpp> +#include <com/sun/star/drawing/XShape.hpp> +#include "global.hxx" +#include "detfunc.hxx" +#include "detdata.hxx" + +class ScHorizontalCellIterator; +struct ScMyCell; +class ScXMLExport; +class ScFormatRangeStyles; +class ScBaseCell; + +//============================================================================== + +class ScMyIteratorBase +{ +protected: + virtual sal_Bool GetFirstAddress( ::com::sun::star::table::CellAddress& rCellAddress ) = 0; + +public: + ScMyIteratorBase(); + virtual ~ScMyIteratorBase(); + + virtual void SetCellData( ScMyCell& rMyCell ) = 0; + virtual void Sort() = 0; + + virtual void UpdateAddress( ::com::sun::star::table::CellAddress& rCellAddress ); +}; + +//============================================================================== + +struct ScMyShape +{ + ScAddress aAddress; + ScAddress aEndAddress; + com::sun::star::uno::Reference<com::sun::star::drawing::XShape> xShape; + + sal_Bool operator<(const ScMyShape& aShape) const; +}; + +typedef std::list<ScMyShape> ScMyShapeList; + +class ScMyShapesContainer : ScMyIteratorBase +{ +private: + ScMyShapeList aShapeList; +protected: + virtual sal_Bool GetFirstAddress( ::com::sun::star::table::CellAddress& rCellAddress ); +public: + ScMyShapesContainer(); + virtual ~ScMyShapesContainer(); + + using ScMyIteratorBase::UpdateAddress; + void AddNewShape(const ScMyShape& aShape); + sal_Bool HasShapes() { return !aShapeList.empty(); } + const ScMyShapeList* GetShapes() { return &aShapeList; } + virtual void SetCellData( ScMyCell& rMyCell ); + virtual void Sort(); + void SkipTable(SCTAB nSkip); +}; + +struct ScMyNoteShape +{ + com::sun::star::uno::Reference<com::sun::star::drawing::XShape> xShape; + ScAddress aPos; + + sal_Bool operator<(const ScMyNoteShape& aNote) const; +}; + +typedef std::list<ScMyNoteShape> ScMyNoteShapeList; + +class ScMyNoteShapesContainer : ScMyIteratorBase +{ +private: + ScMyNoteShapeList aNoteShapeList; +protected: + virtual sal_Bool GetFirstAddress( ::com::sun::star::table::CellAddress& rCellAddress ); +public: + ScMyNoteShapesContainer(); + virtual ~ScMyNoteShapesContainer(); + + using ScMyIteratorBase::UpdateAddress; + void AddNewNote(const ScMyNoteShape& aNote); + sal_Bool HasNotes() { return !aNoteShapeList.empty(); } + const ScMyNoteShapeList* GetNotes() { return &aNoteShapeList; } + virtual void SetCellData( ScMyCell& rMyCell ); + virtual void Sort(); + void SkipTable(SCTAB nSkip); +}; + +//============================================================================== + +struct ScMyMergedRange +{ + com::sun::star::table::CellRangeAddress aCellRange; + sal_Int32 nRows; + sal_Bool bIsFirst; + sal_Bool operator<(const ScMyMergedRange& aRange) const; +}; + +typedef std::list<ScMyMergedRange> ScMyMergedRangeList; + +class ScMyMergedRangesContainer : ScMyIteratorBase +{ +private: + ScMyMergedRangeList aRangeList; +protected: + virtual sal_Bool GetFirstAddress( ::com::sun::star::table::CellAddress& rCellAddress ); +public: + ScMyMergedRangesContainer(); + virtual ~ScMyMergedRangesContainer(); + void AddRange(const com::sun::star::table::CellRangeAddress aMergedRange); + + using ScMyIteratorBase::UpdateAddress; + virtual void SetCellData( ScMyCell& rMyCell ); + virtual void Sort(); // + remove doublets + void SkipTable(SCTAB nSkip); +}; + +//============================================================================== + +struct ScMyAreaLink +{ + ::rtl::OUString sFilter; + ::rtl::OUString sFilterOptions; + ::rtl::OUString sURL; + ::rtl::OUString sSourceStr; + ::com::sun::star::table::CellRangeAddress aDestRange; + sal_Int32 nRefresh; + + inline ScMyAreaLink() : nRefresh( 0 ) {} + + inline sal_Int32 GetColCount() const { return aDestRange.EndColumn - aDestRange.StartColumn + 1; } + inline sal_Int32 GetRowCount() const { return aDestRange.EndRow - aDestRange.StartRow + 1; } + + sal_Bool Compare( const ScMyAreaLink& rAreaLink ) const; + sal_Bool operator<(const ScMyAreaLink& rAreaLink ) const; +}; + +typedef ::std::list< ScMyAreaLink > ScMyAreaLinkList; + +class ScMyAreaLinksContainer : ScMyIteratorBase +{ +private: + ScMyAreaLinkList aAreaLinkList; +protected: + virtual sal_Bool GetFirstAddress( ::com::sun::star::table::CellAddress& rCellAddress ); +public: + ScMyAreaLinksContainer(); + virtual ~ScMyAreaLinksContainer(); + + inline void AddNewAreaLink( const ScMyAreaLink& rAreaLink ) + { aAreaLinkList.push_back( rAreaLink ); } + + using ScMyIteratorBase::UpdateAddress; + virtual void SetCellData( ScMyCell& rMyCell ); + virtual void Sort(); + void SkipTable(SCTAB nSkip); +}; + +//============================================================================== + +struct ScMyCellRangeAddress : com::sun::star::table::CellRangeAddress +{ + ScMyCellRangeAddress(const com::sun::star::table::CellRangeAddress& rRange); + sal_Bool operator<(const ScMyCellRangeAddress& rCellRangeAddress ) const; +}; + +typedef std::list<ScMyCellRangeAddress> ScMyEmptyDatabaseRangeList; + +class ScMyEmptyDatabaseRangesContainer : ScMyIteratorBase +{ +private: + ScMyEmptyDatabaseRangeList aDatabaseList; +protected: + virtual sal_Bool GetFirstAddress( ::com::sun::star::table::CellAddress& rCellAddress ); +public: + ScMyEmptyDatabaseRangesContainer(); + virtual ~ScMyEmptyDatabaseRangesContainer(); + void AddNewEmptyDatabaseRange(const com::sun::star::table::CellRangeAddress& aCellRangeAddress); + + using ScMyIteratorBase::UpdateAddress; + virtual void SetCellData( ScMyCell& rMyCell ); + virtual void Sort(); + void SkipTable(SCTAB nSkip); +}; + +//============================================================================== + +struct ScMyDetectiveObj +{ + ::com::sun::star::table::CellAddress aPosition; + ::com::sun::star::table::CellRangeAddress aSourceRange; + ScDetectiveObjType eObjType; + sal_Bool bHasError; + sal_Bool operator<(const ScMyDetectiveObj& rDetObj) const; +}; + +typedef ::std::list< ScMyDetectiveObj > ScMyDetectiveObjList; +typedef ::std::vector< ScMyDetectiveObj > ScMyDetectiveObjVec; + +class ScMyDetectiveObjContainer : ScMyIteratorBase +{ +private: + ScMyDetectiveObjList aDetectiveObjList; +protected: + virtual sal_Bool GetFirstAddress( ::com::sun::star::table::CellAddress& rCellAddress ); +public: + ScMyDetectiveObjContainer(); + virtual ~ScMyDetectiveObjContainer(); + + void AddObject( + ScDetectiveObjType eObjType, + const SCTAB nSheet, + const ScAddress& rPosition, + const ScRange& rSourceRange, + sal_Bool bHasError ); + + using ScMyIteratorBase::UpdateAddress; + virtual void SetCellData( ScMyCell& rMyCell ); + virtual void Sort(); + void SkipTable(SCTAB nSkip); +}; + +//============================================================================== + +struct ScMyDetectiveOp +{ + ::com::sun::star::table::CellAddress aPosition; + ScDetOpType eOpType; + sal_Int32 nIndex; + sal_Bool operator<(const ScMyDetectiveOp& rDetOp) const; +}; + +typedef ::std::list< ScMyDetectiveOp > ScMyDetectiveOpList; +typedef ::std::vector< ScMyDetectiveOp > ScMyDetectiveOpVec; + +class ScMyDetectiveOpContainer : ScMyIteratorBase +{ +private: + ScMyDetectiveOpList aDetectiveOpList; +protected: + virtual sal_Bool GetFirstAddress( ::com::sun::star::table::CellAddress& rCellAddress ); +public: + ScMyDetectiveOpContainer(); + virtual ~ScMyDetectiveOpContainer(); + + void AddOperation( ScDetOpType eOpType, const ScAddress& rPosition, sal_uInt32 nIndex ); + + using ScMyIteratorBase::UpdateAddress; + virtual void SetCellData( ScMyCell& rMyCell ); + virtual void Sort(); + void SkipTable(SCTAB nSkip); +}; + +//============================================================================== + +// contains data to export for the current cell position +struct ScMyCell +{ +// com::sun::star::uno::Reference<com::sun::star::table::XCell> xCell; +// com::sun::star::uno::Reference<com::sun::star::text::XText> xText; + com::sun::star::uno::Reference<com::sun::star::sheet::XSheetAnnotation> xAnnotation; + com::sun::star::uno::Reference<com::sun::star::drawing::XShape> xNoteShape; + com::sun::star::table::CellAddress aCellAddress; + com::sun::star::table::CellRangeAddress aMergeRange; + com::sun::star::table::CellRangeAddress aMatrixRange; + + rtl::OUString sStringValue; + rtl::OUString sAnnotationText; + + ScMyAreaLink aAreaLink; + ScMyShapeList aShapeList; + ScMyDetectiveObjVec aDetectiveObjVec; + ScMyDetectiveOpVec aDetectiveOpVec; + + double fValue; + sal_Int32 nValidationIndex; + sal_Int32 nStyleIndex; + sal_Int32 nNumberFormat; + com::sun::star::table::CellContentType nType; + + ScBaseCell* pBaseCell; + + sal_Bool bIsAutoStyle; + + sal_Bool bHasShape; + sal_Bool bIsMergedBase; + sal_Bool bIsCovered; + sal_Bool bHasAreaLink; + sal_Bool bHasEmptyDatabase; + sal_Bool bHasDetectiveObj; + sal_Bool bHasDetectiveOp; + + sal_Bool bIsEditCell; + sal_Bool bKnowWhetherIsEditCell; + sal_Bool bHasStringValue; + sal_Bool bHasDoubleValue; + sal_Bool bHasXText; + + sal_Bool bIsMatrixBase; + sal_Bool bIsMatrixCovered; + sal_Bool bHasAnnotation; + + ScMyCell(); + ~ScMyCell(); +}; + +//============================================================================== + +struct ScMyExportAnnotation +{ + com::sun::star::uno::Reference<com::sun::star::sheet::XSheetAnnotation> xAnnotation; + com::sun::star::table::CellAddress aCellAddress; + sal_Bool operator<(const ScMyExportAnnotation& rAnno) const; +}; + +typedef ::std::list< ScMyExportAnnotation > ScMyExportAnnotationList; + +class ScMyNotEmptyCellsIterator +{ + com::sun::star::uno::Reference<com::sun::star::sheet::XSpreadsheet> xTable; + com::sun::star::uno::Reference<com::sun::star::table::XCellRange> xCellRange; + com::sun::star::table::CellAddress aLastAddress; + ScMyExportAnnotationList aAnnotations; + + ScMyShapesContainer* pShapes; + ScMyNoteShapesContainer* pNoteShapes; + ScMyEmptyDatabaseRangesContainer* pEmptyDatabaseRanges; + ScMyMergedRangesContainer* pMergedRanges; + ScMyAreaLinksContainer* pAreaLinks; + ScMyDetectiveObjContainer* pDetectiveObj; + ScMyDetectiveOpContainer* pDetectiveOp; + + ScXMLExport& rExport; + ScHorizontalCellIterator* pCellItr; + + SCCOL nCellCol; + SCROW nCellRow; + SCTAB nCurrentTable; + + void UpdateAddress( ::com::sun::star::table::CellAddress& rAddress ); + void SetCellData( ScMyCell& rMyCell, ::com::sun::star::table::CellAddress& rAddress ); + + void SetMatrixCellData( ScMyCell& rMyCell ); + void HasAnnotation( ScMyCell& aCell ); +public: + ScMyNotEmptyCellsIterator(ScXMLExport& rExport); + ~ScMyNotEmptyCellsIterator(); + + void Clear(); + + inline void SetShapes(ScMyShapesContainer* pNewShapes) + { pShapes = pNewShapes; } + inline void SetNoteShapes(ScMyNoteShapesContainer* pNewNoteShapes) + { pNoteShapes = pNewNoteShapes; } + inline void SetEmptyDatabaseRanges(ScMyEmptyDatabaseRangesContainer* pNewEmptyDatabaseRanges) + { pEmptyDatabaseRanges = pNewEmptyDatabaseRanges; } + inline void SetMergedRanges(ScMyMergedRangesContainer* pNewMergedRanges) + { pMergedRanges = pNewMergedRanges; } + inline void SetAreaLinks(ScMyAreaLinksContainer* pNewAreaLinks) + { pAreaLinks = pNewAreaLinks; } + inline void SetDetectiveObj(ScMyDetectiveObjContainer* pNewDetectiveObj) + { pDetectiveObj = pNewDetectiveObj; } + inline void SetDetectiveOp(ScMyDetectiveOpContainer* pNewDetectiveOp) + { pDetectiveOp = pNewDetectiveOp; } + + void SetCurrentTable(const SCTAB nTable, + com::sun::star::uno::Reference<com::sun::star::sheet::XSpreadsheet>& rxTable); + void SkipTable(SCTAB nSkip); + + sal_Bool GetNext(ScMyCell& aCell, ScFormatRangeStyles* pCellStyles); +}; + +#endif + diff --git a/sc/source/filter/xml/XMLExportSharedData.cxx b/sc/source/filter/xml/XMLExportSharedData.cxx new file mode 100644 index 000000000000..eede3aa73499 --- /dev/null +++ b/sc/source/filter/xml/XMLExportSharedData.cxx @@ -0,0 +1,163 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- +#include "XMLExportSharedData.hxx" +#include "XMLExportIterator.hxx" +#include <tools/debug.hxx> + +using namespace com::sun::star; + +ScMySharedData::ScMySharedData(const sal_Int32 nTempTableCount) : + nLastColumns(nTempTableCount, 0), + nLastRows(nTempTableCount, 0), + pTableShapes(NULL), + pDrawPages(NULL), + pShapesContainer(NULL), + pDetectiveObjContainer(new ScMyDetectiveObjContainer()), + pNoteShapes(NULL), + nTableCount(nTempTableCount) +{ +} + +ScMySharedData::~ScMySharedData() +{ + if (pShapesContainer) + delete pShapesContainer; + if (pTableShapes) + delete pTableShapes; + if (pDrawPages) + delete pDrawPages; + if (pDetectiveObjContainer) + delete pDetectiveObjContainer; + if (pNoteShapes) + delete pNoteShapes; +} + +void ScMySharedData::SetLastColumn(const sal_Int32 nTable, const sal_Int32 nCol) +{ + if(nCol > nLastColumns[nTable]) nLastColumns[nTable] = nCol; +} + +sal_Int32 ScMySharedData::GetLastColumn(const sal_Int32 nTable) +{ + return nLastColumns[nTable]; +} + +void ScMySharedData::SetLastRow(const sal_Int32 nTable, const sal_Int32 nRow) +{ + if(nRow > nLastRows[nTable]) nLastRows[nTable] = nRow; +} + +sal_Int32 ScMySharedData::GetLastRow(const sal_Int32 nTable) +{ + return nLastRows[nTable]; +} + +void ScMySharedData::AddDrawPage(const ScMyDrawPage& aDrawPage, const sal_Int32 nTable) +{ + if (!pDrawPages) + pDrawPages = new ScMyDrawPages(nTableCount, ScMyDrawPage()); + (*pDrawPages)[nTable] = aDrawPage; +} + +void ScMySharedData::SetDrawPageHasForms(const sal_Int32 nTable, sal_Bool bHasForms) +{ + DBG_ASSERT(pDrawPages, "DrawPages not collected"); + if (pDrawPages) + (*pDrawPages)[nTable].bHasForms = bHasForms; +} + +uno::Reference<drawing::XDrawPage> ScMySharedData::GetDrawPage(const sal_Int32 nTable) +{ + DBG_ASSERT(pDrawPages, "DrawPages not collected"); + if (pDrawPages) + return (*pDrawPages)[nTable].xDrawPage; + else + return uno::Reference<drawing::XDrawPage>(); +} + +sal_Bool ScMySharedData::HasForm(const sal_Int32 nTable, uno::Reference<drawing::XDrawPage>& xDrawPage) +{ + sal_Bool bResult(sal_False); + if (pDrawPages) + { + if ((*pDrawPages)[nTable].bHasForms) + { + bResult = sal_True; + xDrawPage = (*pDrawPages)[nTable].xDrawPage; + } + } + return bResult; +} + +void ScMySharedData::AddNewShape(const ScMyShape& aMyShape) +{ + if (!pShapesContainer) + pShapesContainer = new ScMyShapesContainer(); + pShapesContainer->AddNewShape(aMyShape); +} + +void ScMySharedData::SortShapesContainer() +{ + if (pShapesContainer) + pShapesContainer->Sort(); +} + +sal_Bool ScMySharedData::HasShapes() +{ + return ((pShapesContainer && pShapesContainer->HasShapes()) || + (pTableShapes && !pTableShapes->empty())); +} + +void ScMySharedData::AddTableShape(const sal_Int32 nTable, const uno::Reference<drawing::XShape>& xShape) +{ + if (!pTableShapes) + pTableShapes = new ScMyTableShapes(nTableCount); + (*pTableShapes)[nTable].push_back(xShape); +} + +void ScMySharedData::AddNoteObj(const uno::Reference<drawing::XShape>& xShape, const ScAddress& rPos) +{ + if (!pNoteShapes) + pNoteShapes = new ScMyNoteShapesContainer(); + ScMyNoteShape aNote; + aNote.xShape = xShape; + aNote.aPos = rPos; + pNoteShapes->AddNewNote(aNote); +} + +void ScMySharedData::SortNoteShapes() +{ + if (pNoteShapes) + pNoteShapes->Sort(); +} diff --git a/sc/source/filter/xml/XMLExportSharedData.hxx b/sc/source/filter/xml/XMLExportSharedData.hxx new file mode 100644 index 000000000000..e808101805fd --- /dev/null +++ b/sc/source/filter/xml/XMLExportSharedData.hxx @@ -0,0 +1,90 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLEXPORTSHAREDDATA_HXX +#define SC_XMLEXPORTSHAREDDATA_HXX + +#include "global.hxx" +#include <com/sun/star/drawing/XDrawPage.hpp> + +#include <vector> +#include <list> + +struct ScMyDrawPage +{ + com::sun::star::uno::Reference<com::sun::star::drawing::XDrawPage> xDrawPage; + sal_Bool bHasForms; + + ScMyDrawPage() : bHasForms(sal_False) {} +}; + +typedef std::list< com::sun::star::uno::Reference<com::sun::star::drawing::XShape> > ScMyTableXShapes; +typedef std::vector<ScMyTableXShapes> ScMyTableShapes; +typedef std::vector<ScMyDrawPage> ScMyDrawPages; + +class ScMyShapesContainer; +class ScMyDetectiveObjContainer; +struct ScMyShape; +class ScMyNoteShapesContainer; + +class ScMySharedData +{ + std::vector<sal_Int32> nLastColumns; + std::vector<sal_Int32> nLastRows; + ScMyTableShapes* pTableShapes; + ScMyDrawPages* pDrawPages; + ScMyShapesContainer* pShapesContainer; + ScMyDetectiveObjContainer* pDetectiveObjContainer; + ScMyNoteShapesContainer* pNoteShapes; + sal_Int32 nTableCount; +public: + ScMySharedData(const sal_Int32 nTableCount); + ~ScMySharedData(); + + void SetLastColumn(const sal_Int32 nTable, const sal_Int32 nCol); + void SetLastRow(const sal_Int32 nTable, const sal_Int32 nRow); + sal_Int32 GetLastColumn(const sal_Int32 nTable); + sal_Int32 GetLastRow(const sal_Int32 nTable); + void AddDrawPage(const ScMyDrawPage& aDrawPage, const sal_Int32 nTable); + void SetDrawPageHasForms(const sal_Int32 nTable, sal_Bool bHasForms); + com::sun::star::uno::Reference<com::sun::star::drawing::XDrawPage> GetDrawPage(const sal_Int32 nTable); + sal_Bool HasDrawPage() { return pDrawPages != NULL; } + sal_Bool HasForm(const sal_Int32 nTable, com::sun::star::uno::Reference<com::sun::star::drawing::XDrawPage>& xDrawPage); + void AddNewShape(const ScMyShape& aMyShape); + void SortShapesContainer(); + ScMyShapesContainer* GetShapesContainer() { return pShapesContainer; } + sal_Bool HasShapes(); + void AddTableShape(const sal_Int32 nTable, const com::sun::star::uno::Reference<com::sun::star::drawing::XShape>& xShape); + ScMyTableShapes* GetTableShapes() { return pTableShapes; } + ScMyDetectiveObjContainer* GetDetectiveObjContainer() { return pDetectiveObjContainer; } + void AddNoteObj(const com::sun::star::uno::Reference<com::sun::star::drawing::XShape>& xShape, const ScAddress& rPos); + void SortNoteShapes(); + ScMyNoteShapesContainer* GetNoteShapes() { return pNoteShapes; } +}; + +#endif + diff --git a/sc/source/filter/xml/XMLStylesExportHelper.cxx b/sc/source/filter/xml/XMLStylesExportHelper.cxx new file mode 100644 index 000000000000..66f3ea613a3a --- /dev/null +++ b/sc/source/filter/xml/XMLStylesExportHelper.cxx @@ -0,0 +1,1267 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + +// INCLUDE --------------------------------------------------------------- +#include "XMLStylesExportHelper.hxx" +#include "global.hxx" +#include "unonames.hxx" +#include "XMLConverter.hxx" +#include "xmlexprt.hxx" +#include "document.hxx" +#include "rangeutl.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/XMLEventExport.hxx> +#include <xmloff/nmspmap.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/sheet/XSheetCondition.hpp> +#include <com/sun/star/sheet/TableValidationVisibility.hpp> +#include <comphelper/extract.hxx> +#include <sfx2/app.hxx> + +#include <algorithm> + +using namespace com::sun::star; +using namespace xmloff::token; + +ScMyValidation::ScMyValidation() + : sName(), + sErrorMessage(), + sErrorTitle(), + sImputMessage(), + sImputTitle(), + sFormula1(), + sFormula2(), + bShowErrorMessage(sal_False), + bShowImputMessage(sal_False), + bIgnoreBlanks(sal_False) +{ +} + +ScMyValidation::~ScMyValidation() +{ +} + +sal_Bool ScMyValidation::IsEqual(const ScMyValidation& aVal) const +{ + if (aVal.bIgnoreBlanks == bIgnoreBlanks && + aVal.bShowImputMessage == bShowImputMessage && + aVal.bShowErrorMessage == bShowErrorMessage && + aVal.aBaseCell.Sheet == aBaseCell.Sheet && + aVal.aBaseCell.Column == aBaseCell.Column && + aVal.aBaseCell.Row == aBaseCell.Row && + aVal.aAlertStyle == aAlertStyle && + aVal.aValidationType == aValidationType && + aVal.aOperator == aOperator && + aVal.sErrorTitle == sErrorTitle && + aVal.sImputTitle == sImputTitle && + aVal.sErrorMessage == sErrorMessage && + aVal.sImputMessage == sImputMessage && + aVal.sFormula1 == sFormula1 && + aVal.sFormula2 == sFormula2) + return sal_True; + else + return sal_False; +} + +ScMyValidationsContainer::ScMyValidationsContainer() + : aValidationVec(), + sEmptyString(), + sERRALSTY(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ERRALSTY)), + sIGNOREBL(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_IGNOREBL)), + sSHOWLIST(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SHOWLIST)), + sTYPE(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_TYPE)), + sSHOWINP(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SHOWINP)), + sSHOWERR(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SHOWERR)), + sINPTITLE(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_INPTITLE)), + sINPMESS(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_INPMESS)), + sERRTITLE(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ERRTITLE)), + sERRMESS(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ERRMESS)), + sOnError(RTL_CONSTASCII_USTRINGPARAM("OnError")), + sEventType(RTL_CONSTASCII_USTRINGPARAM("EventType")), + sStarBasic(RTL_CONSTASCII_USTRINGPARAM("StarBasic")), + sScript(RTL_CONSTASCII_USTRINGPARAM("Script")), + sLibrary(RTL_CONSTASCII_USTRINGPARAM("Library")), + sMacroName(RTL_CONSTASCII_USTRINGPARAM("MacroName")) +{ +} + +ScMyValidationsContainer::~ScMyValidationsContainer() +{ +} + +sal_Bool ScMyValidationsContainer::AddValidation(const uno::Any& aTempAny, + sal_Int32& nValidationIndex) +{ + sal_Bool bAdded(sal_False); + uno::Reference<beans::XPropertySet> xPropertySet(aTempAny, uno::UNO_QUERY); + if (xPropertySet.is()) + { + rtl::OUString sErrorMessage; + xPropertySet->getPropertyValue(sERRMESS) >>= sErrorMessage; + rtl::OUString sErrorTitle; + xPropertySet->getPropertyValue(sERRTITLE) >>= sErrorTitle; + rtl::OUString sImputMessage; + xPropertySet->getPropertyValue(sINPMESS) >>= sImputMessage; + rtl::OUString sImputTitle; + xPropertySet->getPropertyValue(sINPTITLE) >>= sImputTitle; + sal_Bool bShowErrorMessage = ::cppu::any2bool(xPropertySet->getPropertyValue(sSHOWERR)); + sal_Bool bShowImputMessage = ::cppu::any2bool(xPropertySet->getPropertyValue(sSHOWINP)); + sheet::ValidationType aValidationType; + xPropertySet->getPropertyValue(sTYPE) >>= aValidationType; + if (bShowErrorMessage || bShowImputMessage || aValidationType != sheet::ValidationType_ANY || + sErrorMessage.getLength() || sErrorTitle.getLength() || sImputMessage.getLength() || sImputTitle.getLength()) + { + ScMyValidation aValidation; + aValidation.sErrorMessage = sErrorMessage; + aValidation.sErrorTitle = sErrorTitle; + aValidation.sImputMessage = sImputMessage; + aValidation.sImputTitle = sImputTitle; + aValidation.bShowErrorMessage = bShowErrorMessage; + aValidation.bShowImputMessage = bShowImputMessage; + aValidation.aValidationType = aValidationType; + aValidation.bIgnoreBlanks = ::cppu::any2bool(xPropertySet->getPropertyValue(sIGNOREBL)); + xPropertySet->getPropertyValue(sSHOWLIST) >>= aValidation.nShowList; + xPropertySet->getPropertyValue(sERRALSTY) >>= aValidation.aAlertStyle; + uno::Reference<sheet::XSheetCondition> xCondition(xPropertySet, uno::UNO_QUERY); + if (xCondition.is()) + { + aValidation.sFormula1 = xCondition->getFormula1(); + aValidation.sFormula2 = xCondition->getFormula2(); + aValidation.aOperator = xCondition->getOperator(); + aValidation.aBaseCell = xCondition->getSourcePosition(); + } + //ScMyValidationRange aValidationRange; + sal_Bool bEqualFound(sal_False); + sal_Int32 i(0); + sal_Int32 nCount(aValidationVec.size()); + while (i < nCount && !bEqualFound) + { + bEqualFound = aValidationVec[i].IsEqual(aValidation); + if (!bEqualFound) + ++i; + } + if (bEqualFound) + nValidationIndex = i; + else + { + sal_Int32 nNameIndex(nCount + 1); + rtl::OUString sCount(rtl::OUString::valueOf(nNameIndex)); + rtl::OUString sPrefix(RTL_CONSTASCII_USTRINGPARAM("val")); + aValidation.sName += sPrefix; + aValidation.sName += sCount; + aValidationVec.push_back(aValidation); + nValidationIndex = nCount; + bAdded = sal_True; + } + } + } + return bAdded; +} + +rtl::OUString ScMyValidationsContainer::GetCondition(ScXMLExport& rExport, const ScMyValidation& aValidation) +{ + /* ATTENTION! Should the condition to not write sheet::ValidationType_ANY + * ever be changed, adapt the conditional call of + * MarkUsedExternalReferences() in + * ScTableValidationObj::ScTableValidationObj() accordingly! */ + rtl::OUString sCondition; + if (aValidation.aValidationType != sheet::ValidationType_ANY) + { + switch (aValidation.aValidationType) + { + //case sheet::ValidationType_CUSTOM + case sheet::ValidationType_DATE : + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-date()")); + break; + case sheet::ValidationType_DECIMAL : + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-decimal-number()")); + break; + case sheet::ValidationType_LIST : + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-in-list(")); + sCondition += aValidation.sFormula1; + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")")); + break; + case sheet::ValidationType_TEXT_LEN : + if (aValidation.aOperator != sheet::ConditionOperator_BETWEEN && + aValidation.aOperator != sheet::ConditionOperator_NOT_BETWEEN) + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-text-length()")); + break; + case sheet::ValidationType_TIME : + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-time()")); + break; + case sheet::ValidationType_WHOLE : + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-whole-number()")); + break; + default: + { + // added to avoid warnings + } + } + if (aValidation.aValidationType != sheet::ValidationType_LIST && + (aValidation.sFormula1.getLength() || + (aValidation.aOperator == sheet::ConditionOperator_BETWEEN && + aValidation.aOperator == sheet::ConditionOperator_NOT_BETWEEN && + aValidation.sFormula2.getLength()))) + { + if (aValidation.aValidationType != sheet::ValidationType_TEXT_LEN) + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" and ")); + if (aValidation.aOperator != sheet::ConditionOperator_BETWEEN && + aValidation.aOperator != sheet::ConditionOperator_NOT_BETWEEN) + { + if (aValidation.aValidationType != sheet::ValidationType_TEXT_LEN) + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content()")); + switch (aValidation.aOperator) + { + case sheet::ConditionOperator_EQUAL : + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("=")); + break; + case sheet::ConditionOperator_GREATER : + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">")); + break; + case sheet::ConditionOperator_GREATER_EQUAL : + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">=")); + break; + case sheet::ConditionOperator_LESS : + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<")); + break; + case sheet::ConditionOperator_LESS_EQUAL : + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<=")); + break; + case sheet::ConditionOperator_NOT_EQUAL : + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("!=")); + break; + default: + { + // added to avoid warnings + } + } + sCondition += aValidation.sFormula1; + } + else + { + if (aValidation.aValidationType == sheet::ValidationType_TEXT_LEN) + { + if (aValidation.aOperator == sheet::ConditionOperator_BETWEEN) + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-text-length-is-between(")); + else + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-text-length-is-not-between(")); + } + else + { + if (aValidation.aOperator == sheet::ConditionOperator_BETWEEN) + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-between(")); + else + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-not-between(")); + } + sCondition += aValidation.sFormula1; + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(",")); + sCondition += aValidation.sFormula2; + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")")); + } + } + else + if (aValidation.aValidationType == sheet::ValidationType_TEXT_LEN) + sCondition = rtl::OUString(); + } + if (sCondition.getLength()) + { + const formula::FormulaGrammar::Grammar eGrammar = rExport.GetDocument()->GetStorageGrammar(); + sal_uInt16 nNamespacePrefix = (eGrammar == formula::FormulaGrammar::GRAM_ODFF ? XML_NAMESPACE_OF : XML_NAMESPACE_OOOC); + sCondition = rExport.GetNamespaceMap().GetQNameByKey( nNamespacePrefix, sCondition, sal_False ); + } + + return sCondition; +} + +rtl::OUString ScMyValidationsContainer::GetBaseCellAddress(ScDocument* pDoc, const table::CellAddress& aCell) +{ + rtl::OUString sAddress; + ScRangeStringConverter::GetStringFromAddress( sAddress, aCell, pDoc, ::formula::FormulaGrammar::CONV_OOO ); + return sAddress; +} + +void ScMyValidationsContainer::WriteMessage(ScXMLExport& rExport, + const rtl::OUString& sTitle, const rtl::OUString& sOUMessage, + const sal_Bool bShowMessage, const sal_Bool bIsHelpMessage) +{ + if (sTitle.getLength()) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TITLE, sTitle); + if (bShowMessage) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TRUE); + else + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, XML_FALSE); + SvXMLElementExport* pMessage(NULL); + if (bIsHelpMessage) + pMessage = new SvXMLElementExport(rExport, XML_NAMESPACE_TABLE, XML_HELP_MESSAGE, sal_True, sal_True); + else + pMessage = new SvXMLElementExport(rExport, XML_NAMESPACE_TABLE, XML_ERROR_MESSAGE, sal_True, sal_True); + if (sOUMessage.getLength()) + { + sal_Int32 i(0); + rtl::OUStringBuffer sTemp; + String sMessage(sOUMessage); + rtl::OUString sText (sMessage.ConvertLineEnd(LINEEND_LF)); + sal_Bool bPrevCharWasSpace(sal_True); + while(i < sText.getLength()) + { + if ((sText[i] == '\n')) + { + SvXMLElementExport aElemP(rExport, XML_NAMESPACE_TEXT, XML_P, sal_True, sal_False); + rExport.GetTextParagraphExport()->exportText(sTemp.makeStringAndClear(), bPrevCharWasSpace); + } + else + sTemp.append(sText[i]); + ++i; + } + if (sTemp.getLength()) + { + SvXMLElementExport aElemP(rExport, XML_NAMESPACE_TEXT, XML_P, sal_True, sal_False); + rExport.GetTextParagraphExport()->exportText(sTemp.makeStringAndClear(), bPrevCharWasSpace); + } + } + if (pMessage) + delete pMessage; +} + +void ScMyValidationsContainer::WriteValidations(ScXMLExport& rExport) +{ + if (aValidationVec.size()) + { + SvXMLElementExport aElemVs(rExport, XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATIONS, sal_True, sal_True); + ScMyValidationVec::iterator aItr(aValidationVec.begin()); + ScMyValidationVec::iterator aEndItr(aValidationVec.end()); + while (aItr != aEndItr) + { + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, aItr->sName); + rtl::OUString sCondition(GetCondition(rExport, *aItr)); + if (sCondition.getLength()) + { + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CONDITION, sCondition); + if (aItr->bIgnoreBlanks) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ALLOW_EMPTY_CELL, XML_TRUE); + else + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ALLOW_EMPTY_CELL, XML_FALSE); + if (aItr->aValidationType == sheet::ValidationType_LIST) + { + switch (aItr->nShowList) + { + case sheet::TableValidationVisibility::INVISIBLE: + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_LIST, XML_NO); + break; + case sheet::TableValidationVisibility::UNSORTED: + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_LIST, XML_UNSORTED); + break; + case sheet::TableValidationVisibility::SORTEDASCENDING: + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_LIST, XML_SORTED_ASCENDING); + break; + default: + DBG_ERROR("unknown ListType"); + } + } + } + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_BASE_CELL_ADDRESS, GetBaseCellAddress(rExport.GetDocument(), aItr->aBaseCell)); + SvXMLElementExport aElemV(rExport, XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION, sal_True, sal_True); + if (aItr->bShowImputMessage || aItr->sImputMessage.getLength() || aItr->sImputTitle.getLength()) + { + WriteMessage(rExport, aItr->sImputTitle, aItr->sImputMessage, aItr->bShowImputMessage, sal_True); + } + if (aItr->bShowErrorMessage || aItr->sErrorMessage.getLength() || aItr->sErrorTitle.getLength()) + { + switch (aItr->aAlertStyle) + { + case sheet::ValidationAlertStyle_INFO : + { + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MESSAGE_TYPE, XML_INFORMATION); + WriteMessage(rExport, aItr->sErrorTitle, aItr->sErrorMessage, aItr->bShowErrorMessage, sal_False); + } + break; + case sheet::ValidationAlertStyle_WARNING : + { + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MESSAGE_TYPE, XML_WARNING); + WriteMessage(rExport, aItr->sErrorTitle, aItr->sErrorMessage, aItr->bShowErrorMessage, sal_False); + } + break; + case sheet::ValidationAlertStyle_STOP : + { + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MESSAGE_TYPE, XML_STOP); + WriteMessage(rExport, aItr->sErrorTitle, aItr->sErrorMessage, aItr->bShowErrorMessage, sal_False); + } + break; + case sheet::ValidationAlertStyle_MACRO : + { + { + //rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, aItr->sErrorTitle); + if (aItr->bShowErrorMessage) + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_EXECUTE, XML_TRUE); + else + rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_EXECUTE, XML_FALSE); + SvXMLElementExport aEMElem(rExport, XML_NAMESPACE_TABLE, XML_ERROR_MACRO, sal_True, sal_True); + } + { + // #i47525# for a script URL the type and the property name for the URL + // are both "Script", for a simple macro name the type is "StarBasic" + // and the property name is "MacroName". + bool bScriptURL = SfxApplication::IsXScriptURL( aItr->sErrorTitle ); + + uno::Sequence<beans::PropertyValue> aSeq(3); + beans::PropertyValue* pArr(aSeq.getArray()); + pArr[0].Name = sEventType; + pArr[0].Value <<= bScriptURL ? sScript : sStarBasic; + pArr[1].Name = sLibrary; + pArr[1].Value <<= sEmptyString; + pArr[2].Name = bScriptURL ? sScript : sMacroName; + pArr[2].Value <<= aItr->sErrorTitle; + + // 2) export the sequence + rExport.GetEventExport().ExportSingleEvent( aSeq, sOnError); + } + } + break; + default: + { + // added to avoid warnings + } + } + } + ++aItr; + } + } +} + +const rtl::OUString& ScMyValidationsContainer::GetValidationName(const sal_Int32 nIndex) +{ + DBG_ASSERT( static_cast<size_t>(nIndex) < aValidationVec.size(), "out of range" ); + return aValidationVec[nIndex].sName; +} + +//============================================================================== + +sal_Int32 ScMyDefaultStyles::GetStyleNameIndex(const ScFormatRangeStyles* pCellStyles, + const sal_Int32 nTable, const sal_Int32 nPos, + const sal_Int32 i, const sal_Bool bRow, sal_Bool& bIsAutoStyle) +{ + if (bRow) + return pCellStyles->GetStyleNameIndex(nTable, nPos, i, + bIsAutoStyle); + else + return pCellStyles->GetStyleNameIndex(nTable, i, nPos, + bIsAutoStyle); +} + +void ScMyDefaultStyles::FillDefaultStyles(const sal_Int32 nTable, + const sal_Int32 nLastRow, const sal_Int32 nLastCol, + const ScFormatRangeStyles* pCellStyles, ScDocument* pDoc, + const sal_Bool bRow) +{ + if (pDoc) + { + SCTAB nTab = static_cast<SCTAB>(nTable); + sal_Int32 nPos; + sal_Int32 nLast; + ScMyDefaultStyleList* pDefaults; + if (bRow) + { + pDefaults = pRowDefaults; + nLast = nLastRow; + } + else + { + pDefaults = pColDefaults; + nLast = nLastCol; + } + sal_Bool bPrevAutoStyle(sal_False); + sal_Bool bIsAutoStyle; + sal_Bool bResult; + sal_Int32 nPrevIndex(0); + sal_Int32 nIndex; + sal_Int32 nRepeat(0); + sal_Int32 nEmptyRepeat(0); + for (sal_Int32 i = nLast; i >= 0; --i) + { + if (bRow) + { + SCCOL nCol; + bResult = pDoc->GetRowDefault(nTab, + static_cast<SCROW>(i), static_cast<SCCOL>(nLastCol), nCol); + nPos = static_cast<sal_Int32>(nCol); + } + else + { + SCROW nRow; + bResult = pDoc->GetColDefault(nTab, + static_cast<SCCOL>(i), static_cast<SCROW>(nLastRow), nRow); + nPos = static_cast<sal_Int32>(nRow); + } + if (bResult) + { + nEmptyRepeat = 0; + if (!nRepeat) + { + nPrevIndex = GetStyleNameIndex(pCellStyles, nTab, nPos, i, + bRow, bPrevAutoStyle); + (*pDefaults)[i].nIndex = nPrevIndex; + (*pDefaults)[i].bIsAutoStyle = bPrevAutoStyle; + nRepeat = 1; + } + else + { + nIndex = GetStyleNameIndex(pCellStyles, nTab, nPos, i, + bRow, bIsAutoStyle); + if ((nIndex != nPrevIndex) || (bIsAutoStyle != bPrevAutoStyle)) + { + nRepeat = 1; + nPrevIndex = GetStyleNameIndex(pCellStyles, nTab, nPos, i, + bRow, bPrevAutoStyle); + (*pDefaults)[i].nIndex = nPrevIndex; + (*pDefaults)[i].bIsAutoStyle = bPrevAutoStyle; + } + else + { + (*pDefaults)[i].nIndex = nPrevIndex; + (*pDefaults)[i].bIsAutoStyle = bPrevAutoStyle; + ++nRepeat; + if (nRepeat > 1) + (*pDefaults)[i].nRepeat = nRepeat; + } + } + } + else + { + nRepeat = 0; + if (!nEmptyRepeat) + nEmptyRepeat = 1; + else + { + ++nEmptyRepeat; + if (nEmptyRepeat > 1) + (*pDefaults)[i].nRepeat = nEmptyRepeat; + } + } + } + } +} + +void ScMyDefaultStyles::FillDefaultStyles(const sal_Int32 nTable, + const sal_Int32 nLastRow, const sal_Int32 nLastCol, + const ScFormatRangeStyles* pCellStyles, ScDocument* pDoc) +{ + if (pRowDefaults) + delete pRowDefaults; + pRowDefaults = new ScMyDefaultStyleList(nLastRow + 1); + FillDefaultStyles(nTable, nLastRow, nLastCol, pCellStyles, pDoc, sal_True); + if (pColDefaults) + delete pColDefaults; + pColDefaults = new ScMyDefaultStyleList(nLastCol + 1); + FillDefaultStyles(nTable, nLastRow, nLastCol, pCellStyles, pDoc, sal_False); +} + +ScMyDefaultStyles::~ScMyDefaultStyles() +{ + if (pRowDefaults) + delete pRowDefaults; + if (pColDefaults) + delete pColDefaults; +} + +ScMyRowFormatRange::ScMyRowFormatRange() + : nStartColumn(0), + nRepeatColumns(0), + nRepeatRows(0), + nIndex(-1), + nValidationIndex(-1), + bIsAutoStyle(sal_True) +{ +} + +sal_Bool ScMyRowFormatRange::operator< (const ScMyRowFormatRange& rRange) const +{ + return (nStartColumn < rRange.nStartColumn); +} + +ScRowFormatRanges::ScRowFormatRanges() + : aRowFormatRanges(), + pRowDefaults(NULL), + pColDefaults(NULL), + nSize(0) +{ +} + +ScRowFormatRanges::ScRowFormatRanges(const ScRowFormatRanges* pRanges) + : aRowFormatRanges(pRanges->aRowFormatRanges), + pRowDefaults(pRanges->pRowDefaults), + pColDefaults(pRanges->pColDefaults), + nSize(pRanges->nSize) +{ +} + +ScRowFormatRanges::~ScRowFormatRanges() +{ +} + +void ScRowFormatRanges::Clear() +{ + aRowFormatRanges.clear(); + nSize = 0; +} + +void ScRowFormatRanges::AddRange(const sal_Int32 nPrevStartCol, const sal_Int32 nRepeat, const sal_Int32 nPrevIndex, + const sal_Bool bPrevAutoStyle, const ScMyRowFormatRange& rFormatRange) +{ + sal_Int32 nIndex(-1); + if ((nPrevIndex != rFormatRange.nIndex) || + (bPrevAutoStyle != rFormatRange.bIsAutoStyle)) + nIndex = rFormatRange.nIndex; + + sal_Bool bInserted(sal_False); + if (!aRowFormatRanges.empty()) + { + ScMyRowFormatRange* pRange(&aRowFormatRanges.back()); + if (pRange) + { + if ((nPrevStartCol == (pRange->nStartColumn + pRange->nRepeatColumns)) && + (pRange->bIsAutoStyle == rFormatRange.bIsAutoStyle) && + (pRange->nIndex == nIndex) && + (pRange->nValidationIndex == rFormatRange.nValidationIndex)) + { + if (rFormatRange.nRepeatRows < pRange->nRepeatRows) + pRange->nRepeatRows = rFormatRange.nRepeatRows; + pRange->nRepeatColumns += nRepeat; + bInserted = sal_True; + } + } + } + if (!bInserted) + { + ScMyRowFormatRange aRange; + aRange.nStartColumn = nPrevStartCol; + aRange.nRepeatColumns = nRepeat; + aRange.nRepeatRows = rFormatRange.nRepeatRows; + aRange.nValidationIndex = rFormatRange.nValidationIndex; + aRange.bIsAutoStyle = rFormatRange.bIsAutoStyle; + aRange.nIndex = nIndex; + aRowFormatRanges.push_back(aRange); + ++nSize; + } +} + +void ScRowFormatRanges::AddRange(ScMyRowFormatRange& rFormatRange, + const sal_Int32 nRow) +{ + DBG_ASSERT(pRowDefaults, "no row defaults"); + DBG_ASSERT(pColDefaults, "no column defaults"); + sal_uInt32 nEnd (rFormatRange.nRepeatRows + nRow - 1); + sal_Int32 nPrevIndex((*pRowDefaults)[nRow].nIndex); + sal_Bool bPrevAutoStyle((*pRowDefaults)[nRow].bIsAutoStyle); + sal_uInt32 i(nRow + 1); + sal_Bool bReady(sal_False); + while ((i < nEnd) && !bReady && (i < pRowDefaults->size())) + { + if ((nPrevIndex != (*pRowDefaults)[i].nIndex) || + (bPrevAutoStyle != (*pRowDefaults)[i].bIsAutoStyle)) + bReady = sal_True; + else + i += (*pRowDefaults)[i].nRepeat; + } + if (i > nEnd) + i = nEnd; + if (bReady) + rFormatRange.nRepeatRows = i - nRow + 1; + if (nPrevIndex == -1) + { + nPrevIndex = (*pColDefaults)[rFormatRange.nStartColumn].nIndex; + bPrevAutoStyle = (*pColDefaults)[rFormatRange.nStartColumn].bIsAutoStyle; + sal_uInt32 nPrevStartCol(rFormatRange.nStartColumn); + sal_uInt32 nRepeat((*pColDefaults)[rFormatRange.nStartColumn].nRepeat); + nEnd = rFormatRange.nStartColumn + rFormatRange.nRepeatColumns; + for(i = nPrevStartCol + nRepeat; i < nEnd; i += (*pColDefaults)[i].nRepeat) + { + DBG_ASSERT(sal_uInt32(nPrevStartCol + nRepeat) <= nEnd, "something wents wrong"); + if ((nPrevIndex != (*pColDefaults)[i].nIndex) || + (bPrevAutoStyle != (*pColDefaults)[i].bIsAutoStyle)) + { + AddRange(nPrevStartCol, nRepeat, nPrevIndex, bPrevAutoStyle, rFormatRange); + nPrevStartCol = i; + nRepeat = (*pColDefaults)[i].nRepeat; + nPrevIndex = (*pColDefaults)[i].nIndex; + bPrevAutoStyle = (*pColDefaults)[i].bIsAutoStyle; + } + else + nRepeat += (*pColDefaults)[i].nRepeat; + } + if (sal_uInt32(nPrevStartCol + nRepeat) > nEnd) + nRepeat = nEnd - nPrevStartCol; + AddRange(nPrevStartCol, nRepeat, nPrevIndex, bPrevAutoStyle, rFormatRange); + } + else if ((nPrevIndex == rFormatRange.nIndex) && + (bPrevAutoStyle == rFormatRange.bIsAutoStyle)) + { + rFormatRange.nIndex = -1; + aRowFormatRanges.push_back(rFormatRange); + ++nSize; + } +} + +sal_Bool ScRowFormatRanges::GetNext(ScMyRowFormatRange& aFormatRange) +{ + ScMyRowFormatRangesList::iterator aItr(aRowFormatRanges.begin()); + if (aItr != aRowFormatRanges.end()) + { + aFormatRange = (*aItr); + aRowFormatRanges.erase(aItr); + --nSize; + return sal_True; + } + return sal_False; +} + +sal_Int32 ScRowFormatRanges::GetMaxRows() +{ + ScMyRowFormatRangesList::iterator aItr(aRowFormatRanges.begin()); + ScMyRowFormatRangesList::iterator aEndItr(aRowFormatRanges.end()); + sal_Int32 nMaxRows = MAXROW + 1; + if (aItr != aEndItr) + while (aItr != aEndItr) + { + if ((*aItr).nRepeatRows < nMaxRows) + nMaxRows = (*aItr).nRepeatRows; + ++aItr; + } + else + { + DBG_ERROR("no ranges found"); + } + return nMaxRows; +} + +sal_Int32 ScRowFormatRanges::GetSize() +{ + return nSize; +} + +void ScRowFormatRanges::Sort() +{ + aRowFormatRanges.sort(); +} + +// ============================================================================ +ScMyFormatRange::ScMyFormatRange() + : nStyleNameIndex(-1), + nValidationIndex(-1), + bIsAutoStyle(sal_True) +{ +} + +sal_Bool ScMyFormatRange::operator<(const ScMyFormatRange& rRange) const +{ + if (aRangeAddress.StartRow < rRange.aRangeAddress.StartRow) + return sal_True; + else + if (aRangeAddress.StartRow == rRange.aRangeAddress.StartRow) + return (aRangeAddress.StartColumn < rRange.aRangeAddress.StartColumn); + else + return sal_False; +} + +ScFormatRangeStyles::ScFormatRangeStyles() + : aTables(), + aStyleNames(), + aAutoStyleNames() +{ +} + +ScFormatRangeStyles::~ScFormatRangeStyles() +{ + ScMyOUStringVec::iterator i(aStyleNames.begin()); + ScMyOUStringVec::iterator endi(aStyleNames.end()); + while (i != endi) + { + delete *i; + ++i; + } + i = aAutoStyleNames.begin(); + endi = aAutoStyleNames.end(); + while (i != endi) + { + delete *i; + ++i; + } + ScMyFormatRangeListVec::iterator j(aTables.begin()); + ScMyFormatRangeListVec::iterator endj(aTables.end()); + while (j != endj) + { + delete *j; + ++j; + } +} + +void ScFormatRangeStyles::AddNewTable(const sal_Int32 nTable) +{ + sal_Int32 nSize = aTables.size() - 1; + if (nTable > nSize) + for (sal_Int32 i = nSize; i < nTable; ++i) + { + ScMyFormatRangeAddresses* aRangeAddresses(new ScMyFormatRangeAddresses); + aTables.push_back(aRangeAddresses); + } +} + +sal_Bool ScFormatRangeStyles::AddStyleName(rtl::OUString* rpString, sal_Int32& rIndex, const sal_Bool bIsAutoStyle) +{ + if (bIsAutoStyle) + { + aAutoStyleNames.push_back(rpString); + rIndex = aAutoStyleNames.size() - 1; + return sal_True; + } + else + { + sal_Int32 nCount(aStyleNames.size()); + sal_Bool bFound(sal_False); + sal_Int32 i(nCount - 1); + while ((i >= 0) && (!bFound)) + { + if (aStyleNames.at(i)->equals(*rpString)) + bFound = sal_True; + else + i--; + } + if (bFound) + { + rIndex = i; + return sal_False; + } + else + { + aStyleNames.push_back(rpString); + rIndex = aStyleNames.size() - 1; + return sal_True; + } + } +} + +sal_Int32 ScFormatRangeStyles::GetIndexOfStyleName(const rtl::OUString& rString, const rtl::OUString& rPrefix, sal_Bool& bIsAutoStyle) +{ + sal_Int32 nPrefixLength(rPrefix.getLength()); + rtl::OUString sTemp(rString.copy(nPrefixLength)); + sal_Int32 nIndex(sTemp.toInt32()); + if (nIndex > 0 && static_cast<size_t>(nIndex-1) < aAutoStyleNames.size() && aAutoStyleNames.at(nIndex - 1)->equals(rString)) + { + bIsAutoStyle = sal_True; + return nIndex - 1; + } + else + { + sal_Int32 i(0); + sal_Bool bFound(sal_False); + while (!bFound && static_cast<size_t>(i) < aStyleNames.size()) + { + if (aStyleNames[i]->equals(rString)) + bFound = sal_True; + else + ++i; + } + if (bFound) + { + bIsAutoStyle = sal_False; + return i; + } + else + { + i = 0; + while (!bFound && static_cast<size_t>(i) < aAutoStyleNames.size()) + { + if (aAutoStyleNames[i]->equals(rString)) + bFound = sal_True; + else + ++i; + } + if (bFound) + { + bIsAutoStyle = sal_True; + return i; + } + else + return -1; + } + } +} + +sal_Int32 ScFormatRangeStyles::GetStyleNameIndex(const sal_Int32 nTable, + const sal_Int32 nColumn, const sal_Int32 nRow, sal_Bool& bIsAutoStyle) const +{ + DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table"); + ScMyFormatRangeAddresses* pFormatRanges(aTables[nTable]); + ScMyFormatRangeAddresses::iterator aItr(pFormatRanges->begin()); + ScMyFormatRangeAddresses::iterator aEndItr(pFormatRanges->end()); + while (aItr != aEndItr) + { + if (((*aItr).aRangeAddress.StartColumn <= nColumn) && + ((*aItr).aRangeAddress.EndColumn >= nColumn) && + ((*aItr).aRangeAddress.StartRow <= nRow) && + ((*aItr).aRangeAddress.EndRow >= nRow)) + { + bIsAutoStyle = aItr->bIsAutoStyle; + return (*aItr).nStyleNameIndex; + } + else + ++aItr; + } + return -1; +} + +sal_Int32 ScFormatRangeStyles::GetStyleNameIndex(const sal_Int32 nTable, const sal_Int32 nColumn, const sal_Int32 nRow, + sal_Bool& bIsAutoStyle, sal_Int32& nValidationIndex, sal_Int32& nNumberFormat, const sal_Int32 nRemoveBeforeRow) +{ + DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table"); + ScMyFormatRangeAddresses* pFormatRanges(aTables[nTable]); + ScMyFormatRangeAddresses::iterator aItr(pFormatRanges->begin()); + ScMyFormatRangeAddresses::iterator aEndItr(pFormatRanges->end()); + while (aItr != aEndItr) + { + if (((*aItr).aRangeAddress.StartColumn <= nColumn) && + ((*aItr).aRangeAddress.EndColumn >= nColumn) && + ((*aItr).aRangeAddress.StartRow <= nRow) && + ((*aItr).aRangeAddress.EndRow >= nRow)) + { + bIsAutoStyle = aItr->bIsAutoStyle; + nValidationIndex = aItr->nValidationIndex; + nNumberFormat = aItr->nNumberFormat; + if (((*pRowDefaults)[nRow].nIndex != -1)) + { + if (((*pRowDefaults)[nRow].nIndex == (*aItr).nStyleNameIndex) && + ((*pRowDefaults)[nRow].bIsAutoStyle == (*aItr).bIsAutoStyle)) + return -1; + else + return (*aItr).nStyleNameIndex; + } + else if (((*pColDefaults)[nColumn].nIndex != -1) && + ((*pColDefaults)[nColumn].nIndex == (*aItr).nStyleNameIndex) && + ((*pColDefaults)[nColumn].bIsAutoStyle == (*aItr).bIsAutoStyle)) + return -1; + else + return (*aItr).nStyleNameIndex; + } + else + { + if ((*aItr).aRangeAddress.EndRow < nRemoveBeforeRow) + aItr = pFormatRanges->erase(aItr); + else + ++aItr; + } + } + return -1; +} + +void ScFormatRangeStyles::GetFormatRanges(const sal_Int32 nStartColumn, const sal_Int32 nEndColumn, const sal_Int32 nRow, + const sal_Int32 nTable, ScRowFormatRanges* pRowFormatRanges) +{ + sal_Int32 nTotalColumns(nEndColumn - nStartColumn + 1); + DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table"); + ScMyFormatRangeAddresses* pFormatRanges(aTables[nTable]); + ScMyFormatRangeAddresses::iterator aItr(pFormatRanges->begin()); + ScMyFormatRangeAddresses::iterator aEndItr(pFormatRanges->end()); + sal_Int32 nColumns = 0; + while (aItr != aEndItr && nColumns < nTotalColumns) + { +#if OSL_DEBUG_LEVEL > 1 + table::CellRangeAddress aTempRangeAddress((*aItr).aRangeAddress); +#endif + if (((*aItr).aRangeAddress.StartRow <= nRow) && + ((*aItr).aRangeAddress.EndRow >= nRow)) + { + if ((((*aItr).aRangeAddress.StartColumn <= nStartColumn) && + ((*aItr).aRangeAddress.EndColumn >= nStartColumn)) || + (((*aItr).aRangeAddress.StartColumn <= nEndColumn) && + ((*aItr).aRangeAddress.EndColumn >= nEndColumn)) || + (((*aItr).aRangeAddress.StartColumn >= nStartColumn) && + ((*aItr).aRangeAddress.EndColumn <= nEndColumn))) + { + ScMyRowFormatRange aRange; + aRange.nIndex = aItr->nStyleNameIndex; + aRange.nValidationIndex = aItr->nValidationIndex; + aRange.bIsAutoStyle = aItr->bIsAutoStyle; + if ((aItr->aRangeAddress.StartColumn < nStartColumn) && + (aItr->aRangeAddress.EndColumn >= nStartColumn)) + { + if (aItr->aRangeAddress.EndColumn >= nEndColumn) + aRange.nRepeatColumns = nTotalColumns; + else + aRange.nRepeatColumns = aItr->aRangeAddress.EndColumn - nStartColumn + 1; + aRange.nStartColumn = nStartColumn; + } + else if ((aItr->aRangeAddress.StartColumn >= nStartColumn) && + (aItr->aRangeAddress.EndColumn <= nEndColumn)) + { + aRange.nRepeatColumns = aItr->aRangeAddress.EndColumn - aItr->aRangeAddress.StartColumn + 1; + aRange.nStartColumn = aItr->aRangeAddress.StartColumn; + } + else if ((aItr->aRangeAddress.StartColumn >= nStartColumn) && + (aItr->aRangeAddress.StartColumn <= nEndColumn) && + (aItr->aRangeAddress.EndColumn > nEndColumn)) + { + aRange.nRepeatColumns = nEndColumn - aItr->aRangeAddress.StartColumn + 1; + aRange.nStartColumn = aItr->aRangeAddress.StartColumn; + } + aRange.nRepeatRows = aItr->aRangeAddress.EndRow - nRow + 1; + pRowFormatRanges->AddRange(aRange, nRow); + nColumns += aRange.nRepeatColumns; + } + ++aItr; + } + else + if(aItr->aRangeAddress.EndRow < nRow) + aItr = pFormatRanges->erase(aItr); + else + ++aItr; + } + pRowFormatRanges->Sort(); +} + +void ScFormatRangeStyles::AddRangeStyleName(const table::CellRangeAddress aCellRangeAddress, + const sal_Int32 nStringIndex, const sal_Bool bIsAutoStyle, const sal_Int32 nValidationIndex, + const sal_Int32 nNumberFormat) +{ + ScMyFormatRange aFormatRange; + aFormatRange.aRangeAddress = aCellRangeAddress; + aFormatRange.nStyleNameIndex = nStringIndex; + aFormatRange.nValidationIndex = nValidationIndex; + aFormatRange.nNumberFormat = nNumberFormat; + aFormatRange.bIsAutoStyle = bIsAutoStyle; + DBG_ASSERT(static_cast<size_t>(aCellRangeAddress.Sheet) < aTables.size(), "wrong table"); + ScMyFormatRangeAddresses* pFormatRanges(aTables[aCellRangeAddress.Sheet]); + pFormatRanges->push_back(aFormatRange); +} + +rtl::OUString* ScFormatRangeStyles::GetStyleNameByIndex(const sal_Int32 nIndex, const sal_Bool bIsAutoStyle) +{ + if (bIsAutoStyle) + return aAutoStyleNames[nIndex]; + else + return aStyleNames[nIndex]; +} + +void ScFormatRangeStyles::Sort() +{ + sal_Int32 nTables = aTables.size(); + for (sal_Int16 i = 0; i < nTables; ++i) + if (!aTables[i]->empty()) + aTables[i]->sort(); +} + +//=========================================================================== + +ScColumnRowStylesBase::ScColumnRowStylesBase() + : aStyleNames() +{ +} + +ScColumnRowStylesBase::~ScColumnRowStylesBase() +{ + ScMyOUStringVec::iterator i(aStyleNames.begin()); + ScMyOUStringVec::iterator endi(aStyleNames.end()); + while (i != endi) + { + delete *i; + ++i; + } +} + +sal_Int32 ScColumnRowStylesBase::AddStyleName(rtl::OUString* pString) +{ + aStyleNames.push_back(pString); + return aStyleNames.size() - 1; +} + +sal_Int32 ScColumnRowStylesBase::GetIndexOfStyleName(const rtl::OUString& rString, const rtl::OUString& rPrefix) +{ + sal_Int32 nPrefixLength(rPrefix.getLength()); + rtl::OUString sTemp(rString.copy(nPrefixLength)); + sal_Int32 nIndex(sTemp.toInt32()); + if (nIndex > 0 && static_cast<size_t>(nIndex-1) < aStyleNames.size() && aStyleNames.at(nIndex - 1)->equals(rString)) + return nIndex - 1; + else + { + sal_Int32 i(0); + sal_Bool bFound(sal_False); + while (!bFound && static_cast<size_t>(i) < aStyleNames.size()) + { + if (aStyleNames.at(i)->equals(rString)) + bFound = sal_True; + else + ++i; + } + if (bFound) + return i; + else + return -1; + } +} + +rtl::OUString* ScColumnRowStylesBase::GetStyleNameByIndex(const sal_Int32 nIndex) +{ + if ( nIndex < 0 || nIndex >= sal::static_int_cast<sal_Int32>( aStyleNames.size() ) ) + { + // #123981# should no longer happen, use first style then + DBG_ERRORFILE("GetStyleNameByIndex: invalid index"); + return aStyleNames[0]; + } + + return aStyleNames[nIndex]; +} + +//=========================================================================== + +ScColumnStyles::ScColumnStyles() + : ScColumnRowStylesBase(), + aTables() +{ +} + +ScColumnStyles::~ScColumnStyles() +{ +} + +void ScColumnStyles::AddNewTable(const sal_Int32 nTable, const sal_Int32 nFields) +{ + sal_Int32 nSize(aTables.size() - 1); + if (nTable > nSize) + for (sal_Int32 i = nSize; i < nTable; ++i) + { + ScMyColumnStyleVec aFieldsVec(nFields + 1, ScColumnStyle()); + aTables.push_back(aFieldsVec); + } +} + +sal_Int32 ScColumnStyles::GetStyleNameIndex(const sal_Int32 nTable, const sal_Int32 nField, + sal_Bool& bIsVisible) +{ + DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table"); + if (static_cast<size_t>(nField) < aTables[nTable].size()) + { + bIsVisible = aTables[nTable][nField].bIsVisible; + return aTables[nTable][nField].nIndex; + } + else + { + bIsVisible = aTables[nTable][aTables[nTable].size() - 1].bIsVisible; + return aTables[nTable][aTables[nTable].size() - 1].nIndex; + } +} + +void ScColumnStyles::AddFieldStyleName(const sal_Int32 nTable, const sal_Int32 nField, + const sal_Int32 nStringIndex, const sal_Bool bIsVisible) +{ + DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table"); + DBG_ASSERT(aTables[nTable].size() >= static_cast<sal_uInt32>(nField), "wrong field"); + ScColumnStyle aStyle; + aStyle.nIndex = nStringIndex; + aStyle.bIsVisible = bIsVisible; + if (aTables[nTable].size() == static_cast<sal_uInt32>(nField)) + aTables[nTable].push_back(aStyle); + aTables[nTable][nField] = aStyle; +} + +rtl::OUString* ScColumnStyles::GetStyleName(const sal_Int32 nTable, const sal_Int32 nField) +{ + sal_Bool bTemp; + return GetStyleNameByIndex(GetStyleNameIndex(nTable, nField, bTemp)); +} + +//=========================================================================== + +ScRowStyles::ScRowStyles() + : ScColumnRowStylesBase(), + aTables() +{ +} + +ScRowStyles::~ScRowStyles() +{ +} + +void ScRowStyles::AddNewTable(const sal_Int32 nTable, const sal_Int32 nFields) +{ + sal_Int32 nSize(aTables.size() - 1); + if (nTable > nSize) + for (sal_Int32 i = nSize; i < nTable; ++i) + { + ScMysalInt32Vec aFieldsVec(nFields + 1, -1); + aTables.push_back(aFieldsVec); + } +} + +sal_Int32 ScRowStyles::GetStyleNameIndex(const sal_Int32 nTable, const sal_Int32 nField) +{ + DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table"); + if (static_cast<size_t>(nField) < aTables[nTable].size()) + return aTables[nTable][nField]; + else + return aTables[nTable][aTables[nTable].size() - 1]; +} + +void ScRowStyles::AddFieldStyleName(const sal_Int32 nTable, const sal_Int32 nField, + const sal_Int32 nStringIndex) +{ + DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table"); + DBG_ASSERT(aTables[nTable].size() >= static_cast<size_t>(nField), "wrong field"); + if (aTables[nTable].size() == static_cast<size_t>(nField)) + aTables[nTable].push_back(nStringIndex); + else + aTables[nTable][nField] = nStringIndex; +} + +void ScRowStyles::AddFieldStyleName(const sal_Int32 nTable, const sal_Int32 nStartField, + const sal_Int32 nStringIndex, const sal_Int32 nEndField) +{ + DBG_ASSERT( nStartField <= nEndField, "bad field range"); + DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table"); + DBG_ASSERT(aTables[nTable].size() >= static_cast<size_t>(nStartField), "wrong field"); + ScMysalInt32Vec& rTable = aTables[nTable]; + size_t nSize = rTable.size(); + if (nSize == static_cast<size_t>(nStartField)) + rTable.insert( rTable.end(), static_cast<size_t>(nEndField - nStartField + 1), nStringIndex); + else + { + size_t nField = static_cast<size_t>(nStartField); + for ( ; nField < nSize && nField <= static_cast<size_t>(nEndField); ++nField) + rTable[nField] = nStringIndex; + if (nField <= static_cast<size_t>(nEndField)) + rTable.insert( rTable.end(), static_cast<size_t>(nEndField - nField + 1), nStringIndex); + } +} + +rtl::OUString* ScRowStyles::GetStyleName(const sal_Int32 nTable, const sal_Int32 nField) +{ + return GetStyleNameByIndex(GetStyleNameIndex(nTable, nField)); +} diff --git a/sc/source/filter/xml/XMLStylesExportHelper.hxx b/sc/source/filter/xml/XMLStylesExportHelper.hxx new file mode 100644 index 000000000000..79b19b7ce9ab --- /dev/null +++ b/sc/source/filter/xml/XMLStylesExportHelper.hxx @@ -0,0 +1,294 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLSTYLESEXPORTHELPER_HXX +#define SC_XMLSTYLESEXPORTHELPER_HXX + +#include <vector> +#include <list> +#include <com/sun/star/uno/Any.h> +#include <com/sun/star/table/CellRangeAddress.hpp> +#include <com/sun/star/table/CellAddress.hpp> +#include <com/sun/star/sheet/ConditionOperator.hpp> +#include <com/sun/star/sheet/ValidationAlertStyle.hpp> +#include <com/sun/star/sheet/ValidationType.hpp> + +class ScDocument; +class ScXMLExport; + +struct ScMyValidation +{ + rtl::OUString sName; + rtl::OUString sErrorMessage; + rtl::OUString sErrorTitle; + rtl::OUString sImputMessage; + rtl::OUString sImputTitle; + rtl::OUString sFormula1; + rtl::OUString sFormula2; + com::sun::star::table::CellAddress aBaseCell; + com::sun::star::sheet::ValidationAlertStyle aAlertStyle; + com::sun::star::sheet::ValidationType aValidationType; + com::sun::star::sheet::ConditionOperator aOperator; + sal_Int16 nShowList; + sal_Bool bShowErrorMessage; + sal_Bool bShowImputMessage; + sal_Bool bIgnoreBlanks; + + ScMyValidation(); + ~ScMyValidation(); + + sal_Bool IsEqual(const ScMyValidation& aVal) const; +}; + +typedef std::vector<ScMyValidation> ScMyValidationVec; + +class ScMyValidationsContainer +{ +private: + ScMyValidationVec aValidationVec; + const rtl::OUString sEmptyString; + const rtl::OUString sERRALSTY; + const rtl::OUString sIGNOREBL; + const rtl::OUString sSHOWLIST; + const rtl::OUString sTYPE; + const rtl::OUString sSHOWINP; + const rtl::OUString sSHOWERR; + const rtl::OUString sINPTITLE; + const rtl::OUString sINPMESS; + const rtl::OUString sERRTITLE; + const rtl::OUString sERRMESS; + const rtl::OUString sOnError; + const rtl::OUString sEventType; + const rtl::OUString sStarBasic; + const rtl::OUString sScript; + const rtl::OUString sLibrary; + const rtl::OUString sMacroName; + +public: + ScMyValidationsContainer(); + ~ScMyValidationsContainer(); + sal_Bool AddValidation(const com::sun::star::uno::Any& aAny, + sal_Int32& nValidationIndex); + rtl::OUString GetCondition(ScXMLExport& rExport, const ScMyValidation& aValidation); + rtl::OUString GetBaseCellAddress(ScDocument* pDoc, const com::sun::star::table::CellAddress& aCell); + void WriteMessage(ScXMLExport& rExport, + const rtl::OUString& sTitle, const rtl::OUString& sMessage, + const sal_Bool bShowMessage, const sal_Bool bIsHelpMessage); + void WriteValidations(ScXMLExport& rExport); + const rtl::OUString& GetValidationName(const sal_Int32 nIndex); +}; + +//============================================================================== + +struct ScMyDefaultStyle +{ + sal_Int32 nIndex; + sal_Int32 nRepeat; + sal_Bool bIsAutoStyle; + + ScMyDefaultStyle() : nIndex(-1), nRepeat(1), + bIsAutoStyle(sal_True) {} +}; + +typedef std::vector<ScMyDefaultStyle> ScMyDefaultStyleList; + +class ScFormatRangeStyles; + +class ScMyDefaultStyles +{ + ScMyDefaultStyleList* pRowDefaults; + ScMyDefaultStyleList* pColDefaults; + + sal_Int32 GetStyleNameIndex(const ScFormatRangeStyles* pCellStyles, + const sal_Int32 nTable, const sal_Int32 nPos, + const sal_Int32 i, const sal_Bool bRow, sal_Bool& bIsAutoStyle); + void FillDefaultStyles(const sal_Int32 nTable, + const sal_Int32 nLastRow, const sal_Int32 nLastCol, + const ScFormatRangeStyles* pCellStyles, ScDocument* pDoc, + const sal_Bool bRow); +public: + ScMyDefaultStyles() : pRowDefaults(NULL), pColDefaults(NULL) {} + ~ScMyDefaultStyles(); + + void FillDefaultStyles(const sal_Int32 nTable, + const sal_Int32 nLastRow, const sal_Int32 nLastCol, + const ScFormatRangeStyles* pCellStyles, ScDocument* pDoc); + + const ScMyDefaultStyleList* GetRowDefaults() { return pRowDefaults; } + const ScMyDefaultStyleList* GetColDefaults() { return pColDefaults; } +}; + +struct ScMyRowFormatRange +{ + sal_Int32 nStartColumn; + sal_Int32 nRepeatColumns; + sal_Int32 nRepeatRows; + sal_Int32 nIndex; + sal_Int32 nValidationIndex; + sal_Bool bIsAutoStyle; + + ScMyRowFormatRange(); + sal_Bool operator<(const ScMyRowFormatRange& rRange) const; +}; + +typedef std::list<ScMyRowFormatRange> ScMyRowFormatRangesList; + +class ScRowFormatRanges +{ + ScMyRowFormatRangesList aRowFormatRanges; + const ScMyDefaultStyleList* pRowDefaults; + const ScMyDefaultStyleList* pColDefaults; + sal_uInt32 nSize; + + void AddRange(const sal_Int32 nPrevStartCol, const sal_Int32 nRepeat, const sal_Int32 nPrevIndex, + const sal_Bool bPrevAutoStyle, const ScMyRowFormatRange& rFormatRange); + +public: + ScRowFormatRanges(); + ScRowFormatRanges(const ScRowFormatRanges* pRanges); + ~ScRowFormatRanges(); + + void SetRowDefaults(const ScMyDefaultStyleList* pDefaults) { pRowDefaults = pDefaults; } + void SetColDefaults(const ScMyDefaultStyleList* pDefaults) { pColDefaults = pDefaults; } + void Clear(); + void AddRange(ScMyRowFormatRange& rFormatRange, const sal_Int32 nStartRow); + sal_Bool GetNext(ScMyRowFormatRange& rFormatRange); + sal_Int32 GetMaxRows(); + sal_Int32 GetSize(); + void Sort(); +}; + +typedef std::vector<rtl::OUString*> ScMyOUStringVec; + +struct ScMyFormatRange +{ + com::sun::star::table::CellRangeAddress aRangeAddress; + sal_Int32 nStyleNameIndex; + sal_Int32 nValidationIndex; + sal_Int32 nNumberFormat; + sal_Bool bIsAutoStyle; + + ScMyFormatRange(); + sal_Bool operator< (const ScMyFormatRange& rRange) const; +}; + +typedef std::list<ScMyFormatRange> ScMyFormatRangeAddresses; +typedef std::vector<ScMyFormatRangeAddresses*> ScMyFormatRangeListVec; + +class ScFormatRangeStyles +{ + ScMyFormatRangeListVec aTables; + ScMyOUStringVec aStyleNames; + ScMyOUStringVec aAutoStyleNames; + const ScMyDefaultStyleList* pRowDefaults; + const ScMyDefaultStyleList* pColDefaults; + +public: + ScFormatRangeStyles(); + ~ScFormatRangeStyles(); + + void SetRowDefaults(const ScMyDefaultStyleList* pDefaults) { pRowDefaults = pDefaults; } + void SetColDefaults(const ScMyDefaultStyleList* pDefaults) { pColDefaults = pDefaults; } + void AddNewTable(const sal_Int32 nTable); + sal_Bool AddStyleName(rtl::OUString* pString, sal_Int32& rIndex, const sal_Bool bIsAutoStyle = sal_True); + sal_Int32 GetIndexOfStyleName(const rtl::OUString& rString, const rtl::OUString& rPrefix, sal_Bool& bIsAutoStyle); + // does not delete ranges + sal_Int32 GetStyleNameIndex(const sal_Int32 nTable, const sal_Int32 nColumn, const sal_Int32 nRow, + sal_Bool& bIsAutoStyle) const; + // deletes not necessary ranges if wanted + sal_Int32 GetStyleNameIndex(const sal_Int32 nTable, const sal_Int32 nColumn, const sal_Int32 nRow, + sal_Bool& bIsAutoStyle, sal_Int32& nValidationIndex, sal_Int32& nNumberFormat, const sal_Int32 nRemoveBeforeRow); + void GetFormatRanges(const sal_Int32 nStartColumn, const sal_Int32 nEndColumn, const sal_Int32 nRow, + const sal_Int32 nTable, ScRowFormatRanges* pFormatRanges); + void AddRangeStyleName(const com::sun::star::table::CellRangeAddress aCellRangeAddress, const sal_Int32 nStringIndex, + const sal_Bool bIsAutoStyle, const sal_Int32 nValidationIndex, const sal_Int32 nNumberFormat); + rtl::OUString* GetStyleNameByIndex(const sal_Int32 nIndex, const sal_Bool bIsAutoStyle); + void Sort(); +}; + +class ScColumnRowStylesBase +{ + ScMyOUStringVec aStyleNames; + +public: + ScColumnRowStylesBase(); + virtual ~ScColumnRowStylesBase(); + + virtual void AddNewTable(const sal_Int32 nTable, const sal_Int32 nFields) = 0; + sal_Int32 AddStyleName(rtl::OUString* pString); + sal_Int32 GetIndexOfStyleName(const rtl::OUString& rString, const rtl::OUString& rPrefix); + virtual rtl::OUString* GetStyleName(const sal_Int32 nTable, const sal_Int32 nField) = 0; + rtl::OUString* GetStyleNameByIndex(const sal_Int32 nIndex); +}; + +struct ScColumnStyle +{ + sal_Int32 nIndex; + sal_Bool bIsVisible; + + ScColumnStyle() : nIndex(-1), bIsVisible(sal_True) {} +}; + + +typedef std::vector<ScColumnStyle> ScMyColumnStyleVec; +typedef std::vector<ScMyColumnStyleVec> ScMyColumnVectorVec; + +class ScColumnStyles : public ScColumnRowStylesBase +{ + ScMyColumnVectorVec aTables; + +public: + ScColumnStyles(); + ~ScColumnStyles(); + + virtual void AddNewTable(const sal_Int32 nTable, const sal_Int32 nFields); + sal_Int32 GetStyleNameIndex(const sal_Int32 nTable, const sal_Int32 nField, + sal_Bool& bIsVisible); + void AddFieldStyleName(const sal_Int32 nTable, const sal_Int32 nField, const sal_Int32 nStringIndex, const sal_Bool bIsVisible); + virtual rtl::OUString* GetStyleName(const sal_Int32 nTable, const sal_Int32 nField); +}; + +typedef std::vector<sal_Int32> ScMysalInt32Vec; +typedef std::vector<ScMysalInt32Vec> ScMyRowVectorVec; + +class ScRowStyles : public ScColumnRowStylesBase +{ + ScMyRowVectorVec aTables; + +public: + ScRowStyles(); + ~ScRowStyles(); + + virtual void AddNewTable(const sal_Int32 nTable, const sal_Int32 nFields); + sal_Int32 GetStyleNameIndex(const sal_Int32 nTable, const sal_Int32 nField); + void AddFieldStyleName(const sal_Int32 nTable, const sal_Int32 nField, const sal_Int32 nStringIndex); + void AddFieldStyleName(const sal_Int32 nTable, const sal_Int32 nStartField, const sal_Int32 nStringIndex, const sal_Int32 nEndField); + virtual rtl::OUString* GetStyleName(const sal_Int32 nTable, const sal_Int32 nField); +}; + +#endif + diff --git a/sc/source/filter/xml/XMLStylesImportHelper.cxx b/sc/source/filter/xml/XMLStylesImportHelper.cxx new file mode 100644 index 000000000000..492c7a63ee30 --- /dev/null +++ b/sc/source/filter/xml/XMLStylesImportHelper.cxx @@ -0,0 +1,587 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- +#include "XMLStylesImportHelper.hxx" +#include "xmlimprt.hxx" +#include <tools/debug.hxx> +#include <com/sun/star/util/NumberFormat.hpp> + +using namespace com::sun::star; + +void ScMyStyleNumberFormats::AddStyleNumberFormat(const rtl::OUString& rStyleName, const sal_Int32 nNumberFormat) +{ + aSet.insert(ScMyStyleNumberFormat(rStyleName, nNumberFormat)); +} + +sal_Int32 ScMyStyleNumberFormats::GetStyleNumberFormat(const rtl::OUString& rStyleName) +{ + ScMyStyleNumberFormat aStyleNumberFormat(rStyleName); + ScMyStyleNumberFormatSet::iterator aItr(aSet.find(aStyleNumberFormat)); + if (aItr == aSet.end()) + return -1; + else + return aItr->nNumberFormat; +} + +ScMyStyleRanges::ScMyStyleRanges() + : + pTextList(NULL), + pNumberList(NULL), + pTimeList(NULL), + pDateTimeList(NULL), + pPercentList(NULL), + pLogicalList(NULL), + pUndefinedList(NULL), + pCurrencyList(NULL) +{ +} + +ScMyStyleRanges::~ScMyStyleRanges() +{ + if (pTextList) + delete pTextList; + if (pNumberList) + delete pNumberList; + if (pTimeList) + delete pTimeList; + if (pDateTimeList) + delete pDateTimeList; + if (pPercentList) + delete pPercentList; + if (pLogicalList) + delete pLogicalList; + if (pUndefinedList) + delete pUndefinedList; + if (pCurrencyList) + delete pCurrencyList; +} + +void ScMyStyleRanges::AddRange(const ScRange& rRange, ScRangeList* pList, + const rtl::OUString* pStyleName, const sal_Int16 nType, + ScXMLImport& rImport, const sal_uInt32 nMaxRanges) +{ + pList->Join(rRange); + DBG_ASSERT(nMaxRanges > 0, "MaxRanges to less"); + if (pList->Count() > nMaxRanges) + { + sal_Int32 nCount(pList->Count()); + ScRange* pRange(NULL); + for (sal_Int32 i = 0; i < nCount; ++i) + { + pRange = pList->GetObject(i); + if (pRange && (pRange->aEnd.Row() + 1 < rRange.aStart.Row())) + { + rImport.SetStyleToRange(*pRange, pStyleName, nType, NULL); + delete pRange; + pRange = NULL; + pList->Remove(i); + } + } + } +} + +void ScMyStyleRanges::AddCurrencyRange(const ScRange& rRange, ScRangeListRef xList, + const rtl::OUString* pStyleName, const rtl::OUString* pCurrency, + ScXMLImport& rImport, const sal_uInt32 nMaxRanges) +{ + xList->Join(rRange); + DBG_ASSERT(nMaxRanges > 0, "MaxRanges to less"); + if (xList->Count() > nMaxRanges) + { + sal_Int32 nCount(xList->Count()); + ScRange* pRange(NULL); + for (sal_Int32 i = 0; i < nCount; ++i) + { + pRange = xList->GetObject(i); + if (pRange && (pRange->aEnd.Row() + 1 < rRange.aStart.Row())) + { + rImport.SetStyleToRange(*pRange, pStyleName, util::NumberFormat::CURRENCY, pCurrency); + delete pRange; + pRange = NULL; + xList->Remove(i); + } + } + } +} + +void ScMyStyleRanges::AddRange(const ScRange& rRange, + const rtl::OUString* pStyleName, const sal_Int16 nType, + ScXMLImport& rImport, const sal_uInt32 nMaxRanges) +{ + switch (nType) + { + case util::NumberFormat::NUMBER: + { + if (!pNumberList) + pNumberList = new ScRangeList(); + AddRange(rRange, pNumberList, pStyleName, nType, rImport, nMaxRanges); + } + break; + case util::NumberFormat::TEXT: + { + if (!pTextList) + pTextList = new ScRangeList(); + AddRange(rRange, pTextList, pStyleName, nType, rImport, nMaxRanges); + } + break; + case util::NumberFormat::TIME: + { + if (!pTimeList) + pTimeList = new ScRangeList(); + AddRange(rRange, pTimeList, pStyleName, nType, rImport, nMaxRanges); + } + break; + case util::NumberFormat::DATETIME: + { + if (!pDateTimeList) + pDateTimeList = new ScRangeList(); + AddRange(rRange, pDateTimeList, pStyleName, nType, rImport, nMaxRanges); + } + break; + case util::NumberFormat::PERCENT: + { + if (!pPercentList) + pPercentList = new ScRangeList(); + AddRange(rRange, pPercentList, pStyleName, nType, rImport, nMaxRanges); + } + break; + case util::NumberFormat::LOGICAL: + { + if (!pLogicalList) + pLogicalList = new ScRangeList(); + AddRange(rRange, pLogicalList, pStyleName, nType, rImport, nMaxRanges); + } + break; + case util::NumberFormat::UNDEFINED: + { + if (!pUndefinedList) + pUndefinedList = new ScRangeList(); + AddRange(rRange, pUndefinedList, pStyleName, nType, rImport, nMaxRanges); + } + break; + default: + { + DBG_ERROR("wrong type"); + } + break; + } +} + +void ScMyStyleRanges::AddCurrencyRange(const ScRange& rRange, + const rtl::OUString* pStyleName, const rtl::OUString* pCurrency, + ScXMLImport& rImport, const sal_uInt32 nMaxRanges) +{ + if (!pCurrencyList) + pCurrencyList = new ScMyCurrencyStylesSet(); + ScMyCurrencyStyle aStyle; + if (pCurrency) + aStyle.sCurrency = *pCurrency; + ScMyCurrencyStylesSet::iterator aItr(pCurrencyList->find(aStyle)); + if (aItr == pCurrencyList->end()) + { + std::pair<ScMyCurrencyStylesSet::iterator, bool> aPair(pCurrencyList->insert(aStyle)); + if (aPair.second) + { + aItr = aPair.first; + AddCurrencyRange(rRange, aItr->xRanges, pStyleName, pCurrency, rImport, nMaxRanges); + } + } + else + aItr->xRanges->Join(rRange); +} + +void ScMyStyleRanges::InsertColRow(const ScRange& rRange, const SCsCOL nDx, const SCsROW nDy, + const SCsTAB nDz, ScDocument* pDoc) +{ + UpdateRefMode aRefMode(URM_INSDEL); + if (pNumberList) + pNumberList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz); + if (pTextList) + pTextList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz); + if (pTimeList) + pTimeList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz); + if (pDateTimeList) + pDateTimeList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz); + if (pPercentList) + pPercentList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz); + if (pLogicalList) + pLogicalList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz); + if (pUndefinedList) + pUndefinedList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz); + if (pCurrencyList) + { + ScMyCurrencyStylesSet::iterator aItr(pCurrencyList->begin()); + ScMyCurrencyStylesSet::iterator aEndItr(pCurrencyList->end()); + while (aItr != aEndItr) + { + aItr->xRanges->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz); + ++aItr; + } + } +} + +void ScMyStyleRanges::InsertRow(const sal_Int32 nRow, const sal_Int32 nTab, ScDocument* pDoc) +{ + InsertColRow(ScRange(0, static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab), + MAXCOL, MAXROW, static_cast<SCTAB>(nTab)), 0, 1, 0, pDoc); +} + +void ScMyStyleRanges::InsertCol(const sal_Int32 nCol, const sal_Int32 nTab, ScDocument* pDoc) +{ + InsertColRow(ScRange(static_cast<SCCOL>(nCol), 0, static_cast<SCTAB>(nTab), + MAXCOL, MAXROW, static_cast<SCTAB>(nTab)), 1, 0, 0, pDoc); +} + +void ScMyStyleRanges::SetStylesToRanges(ScRangeList* pList, + const rtl::OUString* pStyleName, const sal_Int16 nCellType, + const rtl::OUString* pCurrency, ScXMLImport& rImport) +{ + sal_Int32 nCount(pList->Count()); + for (sal_Int32 i = 0; i < nCount; ++i) + rImport.SetStyleToRange(*pList->GetObject(i), pStyleName, nCellType, pCurrency); +} + +void ScMyStyleRanges::SetStylesToRanges(ScRangeListRef xList, + const rtl::OUString* pStyleName, const sal_Int16 nCellType, + const rtl::OUString* pCurrency, ScXMLImport& rImport) +{ + sal_Int32 nCount(xList->Count()); + for (sal_Int32 i = 0; i < nCount; ++i) + rImport.SetStyleToRange(*xList->GetObject(i), pStyleName, nCellType, pCurrency); +} + +void ScMyStyleRanges::SetStylesToRanges(const rtl::OUString* pStyleName, ScXMLImport& rImport) +{ + if (pNumberList) + SetStylesToRanges(pNumberList, pStyleName, util::NumberFormat::NUMBER, NULL, rImport); + if (pTextList) + SetStylesToRanges(pTextList, pStyleName, util::NumberFormat::TEXT, NULL, rImport); + if (pTimeList) + SetStylesToRanges(pTimeList, pStyleName, util::NumberFormat::TIME, NULL, rImport); + if (pDateTimeList) + SetStylesToRanges(pDateTimeList, pStyleName, util::NumberFormat::DATETIME, NULL, rImport); + if (pPercentList) + SetStylesToRanges(pPercentList, pStyleName, util::NumberFormat::PERCENT, NULL, rImport); + if (pLogicalList) + SetStylesToRanges(pLogicalList, pStyleName, util::NumberFormat::LOGICAL, NULL, rImport); + if (pUndefinedList) + SetStylesToRanges(pUndefinedList, pStyleName, util::NumberFormat::UNDEFINED, NULL, rImport); + if (pCurrencyList) + { + ScMyCurrencyStylesSet::iterator aItr(pCurrencyList->begin()); + ScMyCurrencyStylesSet::iterator aEndItr(pCurrencyList->end()); + while (aItr != aEndItr) + { + SetStylesToRanges(aItr->xRanges, pStyleName, util::NumberFormat::CURRENCY, &aItr->sCurrency, rImport); + ++aItr; + } + } +} + +//---------------------------------------------------------------------------- + +ScMyStylesImportHelper::ScMyStylesImportHelper(ScXMLImport& rTempImport) + : + aRowDefaultStyle(aCellStyles.end()), + rImport(rTempImport), + pStyleName(NULL), + pPrevStyleName(NULL), + pCurrency(NULL), + pPrevCurrency(NULL), + nMaxRanges(0), + bPrevRangeAdded(sal_True) +{ +} + +ScMyStylesImportHelper::~ScMyStylesImportHelper() +{ + if (pPrevStyleName) + delete pPrevStyleName; + if (pPrevCurrency) + delete pPrevCurrency; + if (pStyleName) + delete pStyleName; + if (pCurrency) + delete pCurrency; +} + +void ScMyStylesImportHelper::ResetAttributes() +{ + if (pPrevStyleName) + delete pPrevStyleName; + if (pPrevCurrency) + delete pPrevCurrency; + pPrevStyleName = pStyleName; + pPrevCurrency = pCurrency; + nPrevCellType = nCellType; + pStyleName = NULL; + pCurrency = NULL; + nCellType = 0; +} + +ScMyStylesSet::iterator ScMyStylesImportHelper::GetIterator(const rtl::OUString* pStyleNameP) +{ + ScMyStyle aStyle; + if (pStyleNameP) + aStyle.sStyleName = *pStyleNameP; + else + { + DBG_ERROR("here is no stylename given"); + } + ScMyStylesSet::iterator aItr(aCellStyles.find(aStyle)); + if (aItr == aCellStyles.end()) + { + std::pair<ScMyStylesSet::iterator, bool> aPair(aCellStyles.insert(aStyle)); + if (aPair.second) + aItr = aPair.first; + else + { + DBG_ERROR("not possible to insert style"); + return aCellStyles.end(); + } + } + return aItr; +} + +void ScMyStylesImportHelper::AddDefaultRange(const ScRange& rRange) +{ + DBG_ASSERT(aRowDefaultStyle != aCellStyles.end(), "no row default style"); + if (!aRowDefaultStyle->sStyleName.getLength()) + { + SCCOL nStartCol(rRange.aStart.Col()); + SCCOL nEndCol(rRange.aEnd.Col()); + if (aColDefaultStyles.size() > sal::static_int_cast<sal_uInt32>(nStartCol)) + { + ScMyStylesSet::iterator aPrevItr(aColDefaultStyles[nStartCol]); + DBG_ASSERT(aColDefaultStyles.size() > sal::static_int_cast<sal_uInt32>(nEndCol), "to much columns"); + for (SCCOL i = nStartCol + 1; (i <= nEndCol) && (i < sal::static_int_cast<SCCOL>(aColDefaultStyles.size())); ++i) + { + if (aPrevItr != aColDefaultStyles[i]) + { + DBG_ASSERT(aPrevItr != aCellStyles.end(), "no column default style"); + ScRange aRange(rRange); + aRange.aStart.SetCol(nStartCol); + aRange.aEnd.SetCol(i - 1); + if (pPrevStyleName) + delete pPrevStyleName; + pPrevStyleName = new rtl::OUString(aPrevItr->sStyleName); + AddSingleRange(aRange); + nStartCol = i; + aPrevItr = aColDefaultStyles[i]; + } + } + if (aPrevItr != aCellStyles.end()) + { + ScRange aRange(rRange); + aRange.aStart.SetCol(nStartCol); + if (pPrevStyleName) + delete pPrevStyleName; + pPrevStyleName = new rtl::OUString(aPrevItr->sStyleName); + AddSingleRange(aRange); + } + else + { + DBG_ERRORFILE("no column default style"); + } + } + else + { + DBG_ERRORFILE("to much columns"); + } + } + else + { + if (pPrevStyleName) + delete pPrevStyleName; + pPrevStyleName = new rtl::OUString(aRowDefaultStyle->sStyleName); + AddSingleRange(rRange); + } +} + +void ScMyStylesImportHelper::AddSingleRange(const ScRange& rRange) +{ + if (nMaxRanges == 0) + nMaxRanges = aColDefaultStyles.size(); + ScMyStylesSet::iterator aItr(GetIterator(pPrevStyleName)); + if (aItr != aCellStyles.end()) + { + if (nPrevCellType != util::NumberFormat::CURRENCY) + aItr->xRanges->AddRange(rRange, pPrevStyleName, nPrevCellType, + rImport, nMaxRanges); + else + aItr->xRanges->AddCurrencyRange(rRange, pPrevStyleName, pPrevCurrency, + rImport, nMaxRanges); + } +} + +void ScMyStylesImportHelper::AddRange() +{ + if (pPrevStyleName && pPrevStyleName->getLength()) + AddSingleRange(aPrevRange); + else + AddDefaultRange(aPrevRange); + ResetAttributes(); +} + +void ScMyStylesImportHelper::AddColumnStyle(const rtl::OUString& sStyleName, const sal_Int32 nColumn, const sal_Int32 nRepeat) +{ + (void)nColumn; // avoid warning in product version + DBG_ASSERT(static_cast<sal_uInt32>(nColumn) == aColDefaultStyles.size(), "some columns are absent"); + ScMyStylesSet::iterator aItr(GetIterator(&sStyleName)); + DBG_ASSERT(aItr != aCellStyles.end(), "no column default style"); + aColDefaultStyles.reserve(aColDefaultStyles.size() + nRepeat); + for (sal_Int32 i = 0; i < nRepeat; ++i) + aColDefaultStyles.push_back(aItr); +} + +void ScMyStylesImportHelper::SetRowStyle(const rtl::OUString& sStyleName) +{ + aRowDefaultStyle = GetIterator(&sStyleName); +} + +void ScMyStylesImportHelper::SetAttributes(rtl::OUString* pStyleNameP, + rtl::OUString* pCurrencyP, const sal_Int16 nCellTypeP) +{ + if (this->pStyleName) + delete this->pStyleName; + if (this->pCurrency) + delete this->pCurrency; + this->pStyleName = pStyleNameP; + this->pCurrency = pCurrencyP; + this->nCellType = nCellTypeP; +} + +void ScMyStylesImportHelper::AddRange(const ScRange& rRange) +{ + if (!bPrevRangeAdded) + { + sal_Bool bAddRange(sal_False); + if (nCellType == nPrevCellType && + IsEqual(pStyleName, pPrevStyleName) && + IsEqual(pCurrency, pPrevCurrency)) + { + if (rRange.aStart.Row() == aPrevRange.aStart.Row()) + { + if (rRange.aEnd.Row() == aPrevRange.aEnd.Row()) + { + DBG_ASSERT(aPrevRange.aEnd.Col() + 1 == rRange.aStart.Col(), "something wents wrong"); + aPrevRange.aEnd.SetCol(rRange.aEnd.Col()); + } + else + bAddRange = sal_True; + } + else + { + if (rRange.aStart.Col() == aPrevRange.aStart.Col() && + rRange.aEnd.Col() == aPrevRange.aEnd.Col()) + { + DBG_ASSERT(aPrevRange.aEnd.Row() + 1 == rRange.aStart.Row(), "something wents wrong"); + aPrevRange.aEnd.SetRow(rRange.aEnd.Row()); + } + else + bAddRange = sal_True; + } + } + else + bAddRange = sal_True; + if (bAddRange) + { + AddRange(); + aPrevRange = rRange; + } + } + else + { + aPrevRange = rRange; + ResetAttributes(); + bPrevRangeAdded = sal_False; + } +} + +void ScMyStylesImportHelper::AddCell(const com::sun::star::table::CellAddress& rAddress) +{ + ScAddress aScAddress( static_cast<SCCOL>(rAddress.Column), static_cast<SCROW>(rAddress.Row), rAddress.Sheet ); + ScRange aScRange( aScAddress, aScAddress ); + AddRange(aScRange); +} + +void ScMyStylesImportHelper::InsertRow(const sal_Int32 nRow, const sal_Int32 nTab, ScDocument* pDoc) +{ + rImport.LockSolarMutex(); + ScMyStylesSet::iterator aItr(aCellStyles.begin()); + ScMyStylesSet::iterator aEndItr(aCellStyles.end()); + while (aItr != aEndItr) + { + aItr->xRanges->InsertRow(nRow, nTab, pDoc); + ++aItr; + } + rImport.UnlockSolarMutex(); +} + +void ScMyStylesImportHelper::InsertCol(const sal_Int32 nCol, const sal_Int32 nTab, ScDocument* pDoc) +{ + rImport.LockSolarMutex(); + ScMyStylesSet::iterator aItr(aCellStyles.begin()); + ScMyStylesSet::iterator aEndItr(aCellStyles.end()); + while (aItr != aEndItr) + { + aItr->xRanges->InsertCol(nCol, nTab, pDoc); + ++aItr; + } + rImport.UnlockSolarMutex(); +} + +void ScMyStylesImportHelper::EndTable() +{ + if (!bPrevRangeAdded) + { + AddRange(); + bPrevRangeAdded = sal_True; + } + nMaxRanges = 0; +} + +void ScMyStylesImportHelper::SetStylesToRanges() +{ + ScMyStylesSet::iterator aItr(aCellStyles.begin()); + ScMyStylesSet::iterator aEndItr(aCellStyles.end()); + while (aItr != aEndItr) + { + aItr->xRanges->SetStylesToRanges(&aItr->sStyleName, rImport); + ++aItr; + } + aColDefaultStyles.clear(); + aCellStyles.clear(); + nMaxRanges = 0; +} + diff --git a/sc/source/filter/xml/XMLStylesImportHelper.hxx b/sc/source/filter/xml/XMLStylesImportHelper.hxx new file mode 100644 index 000000000000..3a15dbeff52a --- /dev/null +++ b/sc/source/filter/xml/XMLStylesImportHelper.hxx @@ -0,0 +1,195 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLSTYLESIMPORTHELPER_HXX +#define SC_XMLSTYLESIMPORTHELPER_HXX + +#include "rangelst.hxx" +#include <rtl/ustring.hxx> +#include <com/sun/star/table/CellRangeAddress.hpp> +#include <com/sun/star/table/CellAddress.hpp> + +#include <set> +#include <vector> + +class ScXMLImport; + +struct ScMyStyleNumberFormat +{ + rtl::OUString sStyleName; + sal_Int32 nNumberFormat; + + ScMyStyleNumberFormat() : nNumberFormat(-1) {} + ScMyStyleNumberFormat(const rtl::OUString& rStyleName) : + sStyleName(rStyleName), nNumberFormat(-1) {} + ScMyStyleNumberFormat(const rtl::OUString& rStyleName, const sal_Int32 nFormat) : + sStyleName(rStyleName), nNumberFormat(nFormat) {} +}; + +struct LessStyleNumberFormat +{ + sal_Bool operator() (const ScMyStyleNumberFormat& rValue1, const ScMyStyleNumberFormat& rValue2) const + { + return rValue1.sStyleName < rValue2.sStyleName; + } +}; + +typedef std::set< ScMyStyleNumberFormat, LessStyleNumberFormat > ScMyStyleNumberFormatSet; + +class ScMyStyleNumberFormats +{ + ScMyStyleNumberFormatSet aSet; + +public: + void AddStyleNumberFormat(const rtl::OUString& rStyleName, const sal_Int32 nNumberFormat); + sal_Int32 GetStyleNumberFormat(const rtl::OUString& rStyleName); +}; + +struct ScMyCurrencyStyle +{ + rtl::OUString sCurrency; + ScRangeListRef xRanges; + + ScMyCurrencyStyle() : xRanges(new ScRangeList()) {} + ~ScMyCurrencyStyle() {} +}; + +struct LessCurrencyStyle +{ + sal_Bool operator() (const ScMyCurrencyStyle& rValue1, const ScMyCurrencyStyle& rValue2) const + { + return rValue1.sCurrency < rValue2.sCurrency; + } +}; + +typedef std::set<ScMyCurrencyStyle, LessCurrencyStyle> ScMyCurrencyStylesSet; + +class ScMyStyleRanges : public SvRefBase +{ + ScRangeList* pTextList; + ScRangeList* pNumberList; + ScRangeList* pTimeList; + ScRangeList* pDateTimeList; + ScRangeList* pPercentList; + ScRangeList* pLogicalList; + ScRangeList* pUndefinedList; + ScMyCurrencyStylesSet* pCurrencyList; + + void AddRange(const ScRange& rRange, ScRangeList* pList, + const rtl::OUString* pStyleName, const sal_Int16 nType, + ScXMLImport& rImport, const sal_uInt32 nMaxRanges); + void AddCurrencyRange(const ScRange& rRange, ScRangeListRef xList, + const rtl::OUString* pStyleName, const rtl::OUString* pCurrency, + ScXMLImport& rImport, const sal_uInt32 nMaxRanges); + void InsertColRow(const ScRange& rRange, const SCsCOL nDx, const SCsROW nDy, + const SCsTAB nDz, ScDocument* pDoc); + void SetStylesToRanges(ScRangeList* pList, + const rtl::OUString* pStyleName, const sal_Int16 nCellType, + const rtl::OUString* pCurrency, ScXMLImport& rImport); + void SetStylesToRanges(ScRangeListRef xList, + const rtl::OUString* pStyleName, const sal_Int16 nCellType, + const rtl::OUString* pCurrency, ScXMLImport& rImport); +public: + ScMyStyleRanges(); + ~ScMyStyleRanges(); + void AddRange(const ScRange& rRange, + const rtl::OUString* pStyleName, const sal_Int16 nType, + ScXMLImport& rImport, const sal_uInt32 nMaxRanges); + void AddCurrencyRange(const ScRange& rRange, + const rtl::OUString* pStyleName, const rtl::OUString* pCurrency, + ScXMLImport& rImport, const sal_uInt32 nMaxRanges); + void InsertRow(const sal_Int32 nRow, const sal_Int32 nTab, ScDocument* pDoc); + void InsertCol(const sal_Int32 nCol, const sal_Int32 nTab, ScDocument* pDoc); + void SetStylesToRanges(const rtl::OUString* pStyleName, ScXMLImport& rImport); +}; +SV_DECL_IMPL_REF( ScMyStyleRanges ); + +struct ScMyStyle +{ + rtl::OUString sStyleName; + ScMyStyleRangesRef xRanges; + + ScMyStyle() : xRanges(new ScMyStyleRanges()) {} + ~ScMyStyle() {} +}; + +struct LessStyle +{ + sal_Bool operator() (const ScMyStyle& rValue1, const ScMyStyle& rValue2) const + { + return rValue1.sStyleName < rValue2.sStyleName; + } +}; + +typedef std::set<ScMyStyle, LessStyle> ScMyStylesSet; +typedef std::vector<ScMyStylesSet::iterator> ScMyStyles; + +class ScMyStylesImportHelper +{ + ScMyStylesSet aCellStyles; + ScMyStyles aColDefaultStyles; + ScMyStylesSet::iterator aRowDefaultStyle; + ScXMLImport& rImport; + rtl::OUString* pStyleName; + rtl::OUString* pPrevStyleName; + rtl::OUString* pCurrency; + rtl::OUString* pPrevCurrency; + ScRange aPrevRange; + sal_uInt32 nMaxRanges; + sal_Int16 nCellType; + sal_Int16 nPrevCellType; + sal_Bool bPrevRangeAdded; + + void ResetAttributes(); + ScMyStylesSet::iterator GetIterator(const rtl::OUString* pStyleName); + void AddDefaultRange(const ScRange& rRange); + void AddSingleRange(const ScRange& rRange); + void AddRange(); + sal_Bool IsEqual(const rtl::OUString* pFirst, const rtl::OUString* pSecond) + { + return ((pFirst && pSecond && pFirst->equals(*pSecond)) || + (!pFirst && !pSecond) || + (!pFirst && pSecond && !pSecond->getLength()) || + (!pSecond && pFirst && !pFirst->getLength())); + } +public: + ScMyStylesImportHelper(ScXMLImport& rImport); + ~ScMyStylesImportHelper(); + void AddColumnStyle(const rtl::OUString& rStyleName, const sal_Int32 nColumn, const sal_Int32 nRepeat); + void SetRowStyle(const rtl::OUString& rStyleName); + void SetAttributes(rtl::OUString* pStyleName, + rtl::OUString* pCurrency, const sal_Int16 nCellType); + void AddRange(const ScRange& rRange); + void AddCell(const com::sun::star::table::CellAddress& rAddress); + void InsertRow(const sal_Int32 nRow, const sal_Int32 nTab, ScDocument* pDoc); // a row is inserted before nRow + void InsertCol(const sal_Int32 nCol, const sal_Int32 nTab, ScDocument* pDoc); // a col is inserted before nCol + void EndTable(); + void SetStylesToRanges(); +}; + +#endif + diff --git a/sc/source/filter/xml/XMLTableHeaderFooterContext.cxx b/sc/source/filter/xml/XMLTableHeaderFooterContext.cxx new file mode 100644 index 000000000000..fb0b1235007e --- /dev/null +++ b/sc/source/filter/xml/XMLTableHeaderFooterContext.cxx @@ -0,0 +1,268 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" +#include <com/sun/star/text/XText.hpp> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmlnmspe.hxx> +#include "XMLTableHeaderFooterContext.hxx" +#include <xmloff/xmltoken.hxx> +#include <comphelper/extract.hxx> + +#include "unonames.hxx" + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::xml::sax; +using namespace ::com::sun::star::text; +using namespace ::com::sun::star::beans; +using namespace xmloff::token; + + +TYPEINIT1( XMLTableHeaderFooterContext, SvXMLImportContext ); + +XMLTableHeaderFooterContext::XMLTableHeaderFooterContext( SvXMLImport& rImport, sal_uInt16 nPrfx, + const OUString& rLName, + const uno::Reference< + xml::sax::XAttributeList > & xAttrList, + const Reference < XPropertySet > & rPageStylePropSet, + sal_Bool bFooter, sal_Bool bLft ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + xPropSet( rPageStylePropSet ), + sOn( OUString::createFromAscii( bFooter ? SC_UNO_PAGE_FTRON : SC_UNO_PAGE_HDRON ) ), + sShareContent( OUString::createFromAscii( bFooter ? SC_UNO_PAGE_FTRSHARED : SC_UNO_PAGE_HDRSHARED ) ), + sContent( OUString::createFromAscii( bFooter ? SC_UNO_PAGE_RIGHTFTRCON : SC_UNO_PAGE_RIGHTHDRCON ) ), + sContentLeft( OUString::createFromAscii( bFooter ? SC_UNO_PAGE_LEFTFTRCONT : SC_UNO_PAGE_LEFTHDRCONT ) ), + bDisplay( sal_True ), + bInsertContent( sal_True ), + bLeft( bLft ), + bContainsLeft(sal_False), + bContainsRight(sal_False), + bContainsCenter(sal_False) +{ + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const OUString& rAttrName(xAttrList->getNameByIndex( i )); + OUString aLName; + sal_uInt16 nPrefix(GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLName )); + const OUString& rValue(xAttrList->getValueByIndex( i )); + + // TODO: use a map here + if( XML_NAMESPACE_STYLE == nPrefix ) + { + if( IsXMLToken(aLName, XML_DISPLAY ) ) + bDisplay = IsXMLToken(rValue, XML_TRUE); + } + } + if( bLeft ) + { + sal_Bool bOn(::cppu::any2bool(xPropSet->getPropertyValue( sOn ))); + + if( bOn && bDisplay ) + { + if( ::cppu::any2bool(xPropSet->getPropertyValue( sShareContent )) ) + // Don't share headers any longer + xPropSet->setPropertyValue( sShareContent, uno::makeAny(sal_False) ); + } + else + { + if( !::cppu::any2bool(xPropSet->getPropertyValue( sShareContent )) ) + // share headers + xPropSet->setPropertyValue( sShareContent, uno::makeAny(sal_True) ); + } + } + else + { + sal_Bool bOn(::cppu::any2bool(xPropSet->getPropertyValue( sOn ))); + if ( bOn != bDisplay ) + xPropSet->setPropertyValue( sOn, uno::makeAny(bDisplay) ); + } + if (bLeft) + sCont = sContentLeft; + else + sCont = sContent; + xPropSet->getPropertyValue( sCont ) >>= xHeaderFooterContent; +} + +XMLTableHeaderFooterContext::~XMLTableHeaderFooterContext() +{ +} + +SvXMLImportContext *XMLTableHeaderFooterContext::CreateChildContext( + sal_uInt16 nPrefix, + const OUString& rLocalName, + const uno::Reference< xml::sax::XAttributeList > & xAttrList ) +{ + SvXMLImportContext *pContext(0); + + if ((nPrefix == XML_NAMESPACE_TEXT) && + IsXMLToken(rLocalName, XML_P)) + { + if (!xTextCursor.is()) + { + if( xHeaderFooterContent.is() ) + { + uno::Reference < text::XText > xText(xHeaderFooterContent->getCenterText()); + xText->setString(sEmpty); + xTextCursor.set(xText->createTextCursor()); + xOldTextCursor.set(GetImport().GetTextImport()->GetCursor()); + GetImport().GetTextImport()->SetCursor( xTextCursor ); + bContainsCenter = sal_True; + } + } + pContext = + GetImport().GetTextImport()->CreateTextChildContext(GetImport(), + nPrefix, + rLocalName, + xAttrList); + } + else + { + if (nPrefix == XML_NAMESPACE_STYLE) + { + if (xHeaderFooterContent.is()) + { + uno::Reference < text::XText > xText; + if (IsXMLToken(rLocalName, XML_REGION_LEFT )) + { + xText.set(xHeaderFooterContent->getLeftText()); + bContainsLeft = sal_True; + } + else if (IsXMLToken(rLocalName, XML_REGION_CENTER )) + { + xText.set(xHeaderFooterContent->getCenterText()); + bContainsCenter = sal_True; + } + else if (IsXMLToken(rLocalName, XML_REGION_RIGHT )) + { + xText.set(xHeaderFooterContent->getRightText()); + bContainsRight = sal_True; + } + if (xText.is()) + { + xText->setString(sEmpty); + //SvXMLImport aSvXMLImport( GetImport() ); + uno::Reference < text::XTextCursor > xTempTextCursor(xText->createTextCursor()); + pContext = new XMLHeaderFooterRegionContext( GetImport(), nPrefix, rLocalName, xAttrList, xTempTextCursor); + } + } + } + } + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); + + return pContext; +} + +void XMLTableHeaderFooterContext::EndElement() +{ + if( GetImport().GetTextImport()->GetCursor().is() ) + { + //GetImport().GetTextImport()->GetCursor()->gotoEnd(sal_False); + if( GetImport().GetTextImport()->GetCursor()->goLeft( 1, sal_True ) ) + { + GetImport().GetTextImport()->GetText()->insertString( + GetImport().GetTextImport()->GetCursorAsRange(), sEmpty, + sal_True ); + } + GetImport().GetTextImport()->ResetCursor(); + } + if (xOldTextCursor.is()) + GetImport().GetTextImport()->SetCursor(xOldTextCursor); + if (xHeaderFooterContent.is()) + { + if (!bContainsLeft) + xHeaderFooterContent->getLeftText()->setString(sEmpty); + if (!bContainsCenter) + xHeaderFooterContent->getCenterText()->setString(sEmpty); + if (!bContainsRight) + xHeaderFooterContent->getRightText()->setString(sEmpty); + + xPropSet->setPropertyValue( sCont, uno::makeAny(xHeaderFooterContent) ); + } +} + +TYPEINIT1( XMLHeaderFooterRegionContext, SvXMLImportContext ); + +XMLHeaderFooterRegionContext::XMLHeaderFooterRegionContext( SvXMLImport& rImport, sal_uInt16 nPrfx, + const OUString& rLName, + const uno::Reference< + xml::sax::XAttributeList > & /* xAttrList */, + uno::Reference< text::XTextCursor >& xCursor ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + xTextCursor ( xCursor ) +{ + xOldTextCursor.set(GetImport().GetTextImport()->GetCursor()); + GetImport().GetTextImport()->SetCursor( xTextCursor ); +} + +XMLHeaderFooterRegionContext::~XMLHeaderFooterRegionContext() +{ +} + +SvXMLImportContext *XMLHeaderFooterRegionContext::CreateChildContext( + sal_uInt16 nPrefix, + const OUString& rLocalName, + const uno::Reference< xml::sax::XAttributeList > & xAttrList ) +{ + SvXMLImportContext *pContext(0); + + if ((nPrefix == XML_NAMESPACE_TEXT) && + IsXMLToken(rLocalName, XML_P)) + { + pContext = + GetImport().GetTextImport()->CreateTextChildContext(GetImport(), + nPrefix, + rLocalName, + xAttrList); + } + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); + + return pContext; +} + +void XMLHeaderFooterRegionContext::EndElement() +{ + if( GetImport().GetTextImport()->GetCursor().is() ) + { + //GetImport().GetTextImport()->GetCursor()->gotoEnd(sal_False); + if( GetImport().GetTextImport()->GetCursor()->goLeft( 1, sal_True ) ) + { + OUString sEmpty; + GetImport().GetTextImport()->GetText()->insertString( + GetImport().GetTextImport()->GetCursorAsRange(), sEmpty, + sal_True ); + } + GetImport().GetTextImport()->ResetCursor(); + } + if (xOldTextCursor.is()) + GetImport().GetTextImport()->SetCursor(xOldTextCursor); +} diff --git a/sc/source/filter/xml/XMLTableHeaderFooterContext.hxx b/sc/source/filter/xml/XMLTableHeaderFooterContext.hxx new file mode 100644 index 000000000000..a3ce9c4c970d --- /dev/null +++ b/sc/source/filter/xml/XMLTableHeaderFooterContext.hxx @@ -0,0 +1,114 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef SC_XMLTABLEHEADERFOOTERCONTEXT_HXX_ +#define SC_XMLTABLEHEADERFOOTERCONTEXT_HXX_ + + +#include <xmloff/xmlictxt.hxx> +#include <xmloff/xmlimp.hxx> +#include <com/sun/star/sheet/XHeaderFooterContent.hpp> + +namespace com { namespace sun { namespace star { + namespace text { class XTextCursor; } + namespace beans { class XPropertySet; } +} } } + +class XMLTableHeaderFooterContext: public SvXMLImportContext +{ + ::com::sun::star::uno::Reference < + ::com::sun::star::text::XTextCursor > xTextCursor; + ::com::sun::star::uno::Reference < + ::com::sun::star::text::XTextCursor > xOldTextCursor; + ::com::sun::star::uno::Reference < + ::com::sun::star::beans::XPropertySet > xPropSet; + ::com::sun::star::uno::Reference < + ::com::sun::star::sheet::XHeaderFooterContent > xHeaderFooterContent; + + const ::rtl::OUString sOn; + const ::rtl::OUString sShareContent; + const ::rtl::OUString sContent; + const ::rtl::OUString sContentLeft; + const ::rtl::OUString sEmpty; + rtl::OUString sCont; + + sal_Bool bDisplay; + sal_Bool bInsertContent; + sal_Bool bLeft; + sal_Bool bContainsLeft; + sal_Bool bContainsRight; + sal_Bool bContainsCenter; + +public: + TYPEINFO(); + + XMLTableHeaderFooterContext( SvXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList > & xAttrList, + const ::com::sun::star::uno::Reference < + ::com::sun::star::beans::XPropertySet > & rPageStylePropSet, + sal_Bool bFooter, sal_Bool bLft ); + + virtual ~XMLTableHeaderFooterContext(); + + virtual SvXMLImportContext *CreateChildContext( + sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList ); + + virtual void EndElement(); +}; + +class XMLHeaderFooterRegionContext: public SvXMLImportContext +{ +private: + ::com::sun::star::uno::Reference < + ::com::sun::star::text::XTextCursor >& xTextCursor; + ::com::sun::star::uno::Reference < + ::com::sun::star::text::XTextCursor > xOldTextCursor; + +public: + TYPEINFO(); + + XMLHeaderFooterRegionContext( SvXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList > & xAttrList, + com::sun::star::uno::Reference< com::sun::star::text::XTextCursor >& xCursor ); + + virtual ~XMLHeaderFooterRegionContext(); + + virtual SvXMLImportContext *CreateChildContext( + sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList ); + + virtual void EndElement(); +}; + + +#endif diff --git a/sc/source/filter/xml/XMLTableMasterPageExport.cxx b/sc/source/filter/xml/XMLTableMasterPageExport.cxx new file mode 100644 index 000000000000..91f27ab646a7 --- /dev/null +++ b/sc/source/filter/xml/XMLTableMasterPageExport.cxx @@ -0,0 +1,178 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" +#include <tools/debug.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/xmltoken.hxx> +#include <com/sun/star/text/XText.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include "XMLTableMasterPageExport.hxx" +#include <comphelper/extract.hxx> + +#include "unonames.hxx" +#include "xmlexprt.hxx" + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::text; +using namespace ::com::sun::star::beans; +using namespace xmloff::token; + +XMLTableMasterPageExport::XMLTableMasterPageExport( ScXMLExport& rExp ) : + XMLTextMasterPageExport ( rExp ) +{ +} + +XMLTableMasterPageExport::~XMLTableMasterPageExport() +{ +} + +void XMLTableMasterPageExport::exportHeaderFooterContent( + const Reference< XText >& rText, + sal_Bool bAutoStyles, sal_Bool bProgress ) +{ + DBG_ASSERT( rText.is(), "There is the text" ); + + if( bAutoStyles ) + GetExport().GetTextParagraphExport() + ->collectTextAutoStyles( rText, bProgress, sal_False ); + else + { + GetExport().GetTextParagraphExport()->exportTextDeclarations( rText ); + GetExport().GetTextParagraphExport()->exportText( rText, bProgress, sal_False ); + } +} + +void XMLTableMasterPageExport::exportHeaderFooter(const com::sun::star::uno::Reference < com::sun::star::sheet::XHeaderFooterContent >& xHeaderFooter, + const XMLTokenEnum aName, + const sal_Bool bDisplay) +{ + if( xHeaderFooter.is() ) + { + Reference < XText > xCenter(xHeaderFooter->getCenterText()); + Reference < XText > xLeft(xHeaderFooter->getLeftText()); + Reference < XText > xRight(xHeaderFooter->getRightText()); + if (xCenter.is() && xLeft.is() && xRight.is()) + { + rtl::OUString sCenter (xCenter->getString()); + rtl::OUString sLeft (xLeft->getString()); + rtl::OUString sRight (xRight->getString()); + + if( !bDisplay ) + GetExport().AddAttribute( XML_NAMESPACE_STYLE, + XML_DISPLAY, XML_FALSE ); + SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_STYLE, + aName, sal_True, sal_True ); + if (sCenter.getLength() && !sLeft.getLength() && !sRight.getLength()) + exportHeaderFooterContent( xCenter, sal_False, sal_False ); + else + { + if (sLeft.getLength()) + { + SvXMLElementExport aSubElem( GetExport(), XML_NAMESPACE_STYLE, + XML_REGION_LEFT, sal_True, sal_True ); + exportHeaderFooterContent( xLeft, sal_False, sal_False ); + } + if (sCenter.getLength()) + { + SvXMLElementExport aSubElem( GetExport(), XML_NAMESPACE_STYLE, + XML_REGION_CENTER, sal_True, sal_True ); + exportHeaderFooterContent( xCenter, sal_False, sal_False ); + } + if (sRight.getLength()) + { + SvXMLElementExport aSubElem( GetExport(), XML_NAMESPACE_STYLE, + XML_REGION_RIGHT, sal_True, sal_True ); + exportHeaderFooterContent( xRight, sal_False, sal_False ); + } + } + } + } +} + +void XMLTableMasterPageExport::exportMasterPageContent( + const Reference < XPropertySet > & rPropSet, + sal_Bool bAutoStyles ) +{ + Reference < sheet::XHeaderFooterContent > xHeader(rPropSet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_PAGE_RIGHTHDRCON ) ) ), uno::UNO_QUERY); + + Reference < sheet::XHeaderFooterContent > xHeaderLeft(rPropSet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_PAGE_LEFTHDRCONT ) ) ), uno::UNO_QUERY); + + Reference < sheet::XHeaderFooterContent > xFooter(rPropSet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_PAGE_RIGHTFTRCON ) ) ), uno::UNO_QUERY); + + Reference < sheet::XHeaderFooterContent > xFooterLeft(rPropSet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_PAGE_LEFTFTRCONT ) ) ), uno::UNO_QUERY); + + if( bAutoStyles ) + { + if( xHeader.is() ) + { + exportHeaderFooterContent( xHeader->getCenterText(), sal_True, sal_False ); + exportHeaderFooterContent( xHeader->getLeftText(), sal_True, sal_False ); + exportHeaderFooterContent( xHeader->getRightText(), sal_True, sal_False ); + } + if( xHeaderLeft.is()) + { + exportHeaderFooterContent( xHeaderLeft->getCenterText(), sal_True, sal_False ); + exportHeaderFooterContent( xHeaderLeft->getLeftText(), sal_True, sal_False ); + exportHeaderFooterContent( xHeaderLeft->getRightText(), sal_True, sal_False ); + } + if( xFooter.is() ) + { + exportHeaderFooterContent( xFooter->getCenterText(), sal_True, sal_False ); + exportHeaderFooterContent( xFooter->getLeftText(), sal_True, sal_False ); + exportHeaderFooterContent( xFooter->getRightText(), sal_True, sal_False ); + } + if( xFooterLeft.is()) + { + exportHeaderFooterContent( xFooterLeft->getCenterText(), sal_True, sal_False ); + exportHeaderFooterContent( xFooterLeft->getLeftText(), sal_True, sal_False ); + exportHeaderFooterContent( xFooterLeft->getRightText(), sal_True, sal_False ); + } + } + else + { + sal_Bool bHeader(::cppu::any2bool(rPropSet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_PAGE_HDRON ) ) ))); + + exportHeaderFooter(xHeader, XML_HEADER, bHeader ); + + sal_Bool bLeftHeader(!::cppu::any2bool(rPropSet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_PAGE_HDRSHARED ) ) )) && bHeader); + + exportHeaderFooter( xHeaderLeft, XML_HEADER_LEFT, bLeftHeader ); + + sal_Bool bFooter(::cppu::any2bool(rPropSet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_PAGE_FTRON ) ) ))); + + exportHeaderFooter( xFooter, XML_FOOTER, bFooter ); + + sal_Bool bLeftFooter = (!::cppu::any2bool(rPropSet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_PAGE_FTRSHARED ) ) )) && bFooter); + + exportHeaderFooter( xFooterLeft, XML_FOOTER_LEFT, bLeftFooter ); + } +} + diff --git a/sc/source/filter/xml/XMLTableMasterPageExport.hxx b/sc/source/filter/xml/XMLTableMasterPageExport.hxx new file mode 100644 index 000000000000..0a277bec0bb9 --- /dev/null +++ b/sc/source/filter/xml/XMLTableMasterPageExport.hxx @@ -0,0 +1,66 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLTABLEMASTERPAGEEXPORT_HXX +#define SC_XMLTABLEMASTERPAGEEXPORT_HXX + +#include <rtl/ustring.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/XMLTextMasterPageExport.hxx> +#include <com/sun/star/sheet/XHeaderFooterContent.hpp> + +#include "xmlexprt.hxx" + +namespace com { namespace sun { namespace star { + namespace text { class XText; } +} } } + +class XMLTableMasterPageExport : public XMLTextMasterPageExport +{ + void exportHeaderFooter(const com::sun::star::uno::Reference < com::sun::star::sheet::XHeaderFooterContent >& xHeaderFooter, + const xmloff::token::XMLTokenEnum aName, + const sal_Bool bDisplay); + +protected: + virtual void exportHeaderFooterContent( + const ::com::sun::star::uno::Reference< + ::com::sun::star::text::XText >& rText, + sal_Bool bAutoStyles, sal_Bool bProgress ); + + virtual void exportMasterPageContent( + const ::com::sun::star::uno::Reference < + ::com::sun::star::beans::XPropertySet > & rPropSet, + sal_Bool bAutoStyles ); + +public: + XMLTableMasterPageExport( ScXMLExport& rExp ); + ~XMLTableMasterPageExport(); +}; + + +#endif // _XMLOFF_XMLTABLEMASTERPAGEEXPORT_HXX + diff --git a/sc/source/filter/xml/XMLTableShapeImportHelper.cxx b/sc/source/filter/xml/XMLTableShapeImportHelper.cxx new file mode 100644 index 000000000000..cc425e0f4d65 --- /dev/null +++ b/sc/source/filter/xml/XMLTableShapeImportHelper.cxx @@ -0,0 +1,215 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" +#include "XMLTableShapeImportHelper.hxx" +#include "xmlimprt.hxx" +#include "XMLConverter.hxx" +#include "drwlayer.hxx" +#include "xmlannoi.hxx" +#include "rangeutl.hxx" +#include "docuno.hxx" +#include "sheetdata.hxx" +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/xmluconv.hxx> +#include <xmloff/xmltoken.hxx> +#include <svx/unoshape.hxx> +#include <svx/svdobj.hxx> +#include <com/sun/star/drawing/XShape.hpp> +#include <com/sun/star/drawing/XShapes.hpp> + +#define SC_LAYERID "LayerID" + +using namespace ::com::sun::star; +using namespace xmloff::token; +using ::rtl::OUString; + +XMLTableShapeImportHelper::XMLTableShapeImportHelper( + ScXMLImport& rImp, SvXMLImportPropertyMapper *pImpMapper ) : + XMLShapeImportHelper(rImp, rImp.GetModel(), pImpMapper ), + pAnnotationContext(NULL), + bOnTable(sal_False) +{ +} + +XMLTableShapeImportHelper::~XMLTableShapeImportHelper() +{ +} + +void XMLTableShapeImportHelper::SetLayer(uno::Reference<drawing::XShape>& rShape, sal_Int16 nLayerID, const rtl::OUString& sType) const +{ + if (sType.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.ControlShape")))) + nLayerID = SC_LAYER_CONTROLS; + if (nLayerID != -1) + { + uno::Reference< beans::XPropertySet > xShapeProp( rShape, uno::UNO_QUERY ); + if( xShapeProp.is() ) + xShapeProp->setPropertyValue(OUString( RTL_CONSTASCII_USTRINGPARAM( SC_LAYERID ) ), uno::makeAny(nLayerID) ); + } +} + +void XMLTableShapeImportHelper::finishShape( + uno::Reference< drawing::XShape >& rShape, + const uno::Reference< xml::sax::XAttributeList >& xAttrList, + uno::Reference< drawing::XShapes >& rShapes ) +{ + bool bNote = false; + XMLShapeImportHelper::finishShape( rShape, xAttrList, rShapes ); + static_cast<ScXMLImport&>(mrImporter).LockSolarMutex(); + ScMyTables& rTables = static_cast<ScXMLImport&>(mrImporter).GetTables(); + if (rShapes == rTables.GetCurrentXShapes()) + { + if (!pAnnotationContext) + { + sal_Int32 nEndX(-1); + sal_Int32 nEndY(-1); + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + table::CellAddress aEndCell; + rtl::OUString* pRangeList(NULL); + sal_Int16 nLayerID(-1); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& rAttrName(xAttrList->getNameByIndex( i )); + const rtl::OUString& rValue(xAttrList->getValueByIndex( i )); + + rtl::OUString aLocalName; + sal_uInt16 nPrefix( + static_cast<ScXMLImport&>(mrImporter).GetNamespaceMap().GetKeyByAttrName( rAttrName, + &aLocalName )); + if(nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(aLocalName, XML_END_CELL_ADDRESS)) + { + sal_Int32 nOffset(0); + ScRangeStringConverter::GetAddressFromString(aEndCell, rValue, static_cast<ScXMLImport&>(mrImporter).GetDocument(), ::formula::FormulaGrammar::CONV_OOO, nOffset); + } + else if (IsXMLToken(aLocalName, XML_END_X)) + static_cast<ScXMLImport&>(mrImporter).GetMM100UnitConverter().convertMeasure(nEndX, rValue); + else if (IsXMLToken(aLocalName, XML_END_Y)) + static_cast<ScXMLImport&>(mrImporter).GetMM100UnitConverter().convertMeasure(nEndY, rValue); + else if (IsXMLToken(aLocalName, XML_TABLE_BACKGROUND)) + if (IsXMLToken(rValue, XML_TRUE)) + nLayerID = SC_LAYER_BACK; + } + else if(nPrefix == XML_NAMESPACE_DRAW) + { + if (IsXMLToken(aLocalName, XML_NOTIFY_ON_UPDATE_OF_RANGES)) + pRangeList = new rtl::OUString(rValue); + } + } + SetLayer(rShape, nLayerID, rShape->getShapeType()); + + if (!bOnTable) + { + rTables.AddShape(rShape, + pRangeList, aStartCell, aEndCell, nEndX, nEndY); + SvxShape* pShapeImp = SvxShape::getImplementation(rShape); + if (pShapeImp) + { + SdrObject *pSdrObj = pShapeImp->GetSdrObject(); + if (pSdrObj) + ScDrawLayer::SetAnchor(pSdrObj, SCA_CELL); + } + } + else + { + if ( pRangeList ) + { + // #i78086# If there are notification ranges, the ChartListener must be created + // also when anchored to the sheet + // -> call AddShape with invalid cell position (checked in ScMyShapeResizer::ResizeShapes) + + table::CellAddress aInvalidPos( -1, -1, -1 ); + rTables.AddShape(rShape, + pRangeList, aInvalidPos, aInvalidPos, 0, 0); + } + + SvxShape* pShapeImp = SvxShape::getImplementation(rShape); + if (pShapeImp) + { + SdrObject *pSdrObj = pShapeImp->GetSdrObject(); + if (pSdrObj) + ScDrawLayer::SetAnchor(pSdrObj, SCA_PAGE); + } + } + } + else // shape is annotation + { + // get the style names for stream copying + rtl::OUString aStyleName; + rtl::OUString aTextStyle; + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& rAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(static_cast<ScXMLImport&>(mrImporter).GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName )); + if(nPrefix == XML_NAMESPACE_DRAW) + { + if (IsXMLToken(aLocalName, XML_STYLE_NAME)) + aStyleName = xAttrList->getValueByIndex( i ); + else if (IsXMLToken(aLocalName, XML_TEXT_STYLE_NAME)) + aTextStyle = xAttrList->getValueByIndex( i ); + } + } + + pAnnotationContext->SetShape(rShape, rShapes, aStyleName, aTextStyle); + bNote = true; + } + } + else //#99532# this are grouped shapes which should also get the layerid + { + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + sal_Int16 nLayerID(-1); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& rAttrName(xAttrList->getNameByIndex( i )); + const rtl::OUString& rValue(xAttrList->getValueByIndex( i )); + + rtl::OUString aLocalName; + sal_uInt16 nPrefix(static_cast<ScXMLImport&>(mrImporter).GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName )); + if(nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(aLocalName, XML_TABLE_BACKGROUND)) + if (IsXMLToken(rValue, XML_TRUE)) + nLayerID = SC_LAYER_BACK; + } + } + SetLayer(rShape, nLayerID, rShape->getShapeType()); + } + + if (!bNote) + { + // any shape other than a note prevents copying the sheet + ScSheetSaveData* pSheetData = ScModelObj::getImplementation(mrImporter.GetModel())->GetSheetSaveData(); + pSheetData->BlockSheet( rTables.GetCurrentSheet() ); + } + + static_cast<ScXMLImport&>(mrImporter).UnlockSolarMutex(); +} diff --git a/sc/source/filter/xml/XMLTableShapeImportHelper.hxx b/sc/source/filter/xml/XMLTableShapeImportHelper.hxx new file mode 100644 index 000000000000..94a64312c8ed --- /dev/null +++ b/sc/source/filter/xml/XMLTableShapeImportHelper.hxx @@ -0,0 +1,62 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLTABLESHAPEIMPORTHELPER_HXX +#define SC_XMLTABLESHAPEIMPORTHELPER_HXX + +#include <xmloff/shapeimport.hxx> +#include <com/sun/star/table/CellAddress.hpp> + +class ScXMLImport; +class ScXMLAnnotationContext; + +class XMLTableShapeImportHelper : public XMLShapeImportHelper +{ + ::com::sun::star::table::CellAddress aStartCell; + ScXMLAnnotationContext* pAnnotationContext; + sal_Bool bOnTable; + +public: + + XMLTableShapeImportHelper( ScXMLImport& rImp, SvXMLImportPropertyMapper *pImpMapper=0 ); + ~XMLTableShapeImportHelper(); + + void SetLayer(com::sun::star::uno::Reference<com::sun::star::drawing::XShape>& rShape, sal_Int16 nLayerID, const rtl::OUString& sType) const; + virtual void finishShape(com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& rShape, + const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttrList, + com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >& rShapes); + + + void SetCell (const ::com::sun::star::table::CellAddress& rAddress) { aStartCell = rAddress; } + void SetOnTable (const sal_Bool bTempOnTable) { bOnTable = bTempOnTable; } + void SetAnnotation(ScXMLAnnotationContext* pAnnotation) { pAnnotationContext = pAnnotation; } + + ScXMLAnnotationContext* GetAnnotationContext() const { return pAnnotationContext; } +}; + + +#endif diff --git a/sc/source/filter/xml/XMLTableShapeResizer.cxx b/sc/source/filter/xml/XMLTableShapeResizer.cxx new file mode 100644 index 000000000000..6e70d4d53c0f --- /dev/null +++ b/sc/source/filter/xml/XMLTableShapeResizer.cxx @@ -0,0 +1,385 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" +#include "XMLTableShapeResizer.hxx" +#include "unonames.hxx" +#include "document.hxx" +#include "xmlimprt.hxx" +#include "chartlis.hxx" +#include "XMLConverter.hxx" +#include "rangeutl.hxx" +#include "reftokenhelper.hxx" +#include <tools/debug.hxx> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include <com/sun/star/table/XColumnRowRange.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> + +#include <memory> +#include <vector> + +using namespace ::com::sun::star; +using ::std::auto_ptr; +using ::std::vector; +using ::rtl::OUString; + +ScMyShapeResizer::ScMyShapeResizer(ScXMLImport& rTempImport) + : rImport(rTempImport), + aShapes(), + pCollection(NULL) +{ +} + +ScMyShapeResizer::~ScMyShapeResizer() +{ +} + +sal_Bool ScMyShapeResizer::IsOLE(uno::Reference< drawing::XShape >& rShape) const +{ + return rShape->getShapeType().equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.OLE2Shape"))); +} + +void ScMyShapeResizer::CreateChartListener(ScDocument* pDoc, + const rtl::OUString& rName, + const rtl::OUString* pRangeList) +{ + if (!pDoc || !pRangeList) + // These are minimum required. + return; + + if (!pRangeList->getLength()) + { + pDoc->AddOLEObjectToCollection(rName); + return; + } + + OUString aRangeStr; + ScRangeStringConverter::GetStringFromXMLRangeString(aRangeStr, *pRangeList, pDoc); + if (!aRangeStr.getLength()) + { + pDoc->AddOLEObjectToCollection(rName); + return; + } + + if (!pCollection) + pCollection = pDoc->GetChartListenerCollection(); + + if (!pCollection) + return; + + auto_ptr< vector<ScSharedTokenRef> > pRefTokens(new vector<ScSharedTokenRef>); + ScRefTokenHelper::compileRangeRepresentation(*pRefTokens, aRangeStr, pDoc); + if (!pRefTokens->empty()) + { + ScChartListener* pCL(new ScChartListener(rName, pDoc, pRefTokens.release())); + + //for loading binary files e.g. + //if we have the flat filter we need to set the dirty flag thus the visible charts get repainted + //otherwise the charts keep their first visual representation which was created at a moment where the calc itself was not loaded completly and is incorect therefor + if( (rImport.getImportFlags() & IMPORT_ALL) == IMPORT_ALL ) + pCL->SetDirty( sal_True ); + else + { + // #i104899# If a formula cell is already dirty, further changes aren't propagated. + // This can happen easily now that row heights aren't updated for all sheets. + pDoc->InterpretDirtyCells( *pCL->GetRangeList() ); + } + + pCollection->Insert( pCL ); + pCL->StartListeningTo(); + } +} + +void ScMyShapeResizer::AddShape(uno::Reference <drawing::XShape>& rShape, + rtl::OUString* pRangeList, + table::CellAddress& rStartAddress, table::CellAddress& rEndAddress, + sal_Int32 nEndX, sal_Int32 nEndY) +{ + ScMyToResizeShape aShape; + aShape.xShape.set(rShape); + aShape.pRangeList = pRangeList; + aShape.aEndCell = rEndAddress; + aShape.aStartCell = rStartAddress; + aShape.nEndY = nEndY; + aShape.nEndX = nEndX; + aShapes.push_back(aShape); +} + +void ScMyShapeResizer::GetNewShapeSizePos(ScDocument* pDoc, const Rectangle& rStartRect, + const table::CellAddress& rEndCell, + awt::Point& rPoint, awt::Size& rSize, + sal_Int32& rEndX, sal_Int32& rEndY) const +{ + awt::Point aRefPoint; + sal_Bool bNegativePage(pDoc->IsNegativePage(rEndCell.Sheet)); + if (bNegativePage) + aRefPoint.X = rStartRect.Right(); + else + aRefPoint.X = rStartRect.Left(); + aRefPoint.Y = rStartRect.Top(); + Rectangle aRect(pDoc->GetMMRect( + static_cast<SCCOL>(rEndCell.Column), static_cast<SCROW>(rEndCell.Row), + static_cast<SCCOL>(rEndCell.Column), static_cast<SCROW>(rEndCell.Row), rEndCell.Sheet )); + if (bNegativePage) + rEndX = -rEndX + aRect.Right(); + else + rEndX += aRect.Left(); + rEndY += aRect.Top(); + rPoint.X += aRefPoint.X; + if (bNegativePage) + { + if (rPoint.X < rStartRect.Left()) + rPoint.X = rStartRect.Left() + 2; // increment by 2 100th_mm because the cellwidth is internal in twips + } + else + { + if (rPoint.X > rStartRect.Right()) + rPoint.X = rStartRect.Right() - 2; // decrement by 2 100th_mm because the cellwidth is internal in twips + } + rPoint.Y += aRefPoint.Y; + if (rPoint.Y > rStartRect.Bottom()) + rPoint.Y = rStartRect.Bottom() - 2; // decrement by 2 100th_mm because the cellheight is internal in twips + if (bNegativePage) + { + rSize.Width = -(rEndX - rPoint.X); + } + else + rSize.Width = rEndX - rPoint.X; + rSize.Height = rEndY - rPoint.Y; +} + +void ScMyShapeResizer::ResizeShapes() +{ + if (!aShapes.empty() && rImport.GetModel().is()) + { + rtl::OUString sRowHeight(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CELLHGT)); + rtl::OUString sPersistName (RTL_CONSTASCII_USTRINGPARAM("PersistName")); + rtl::OUString sCaptionPoint( RTL_CONSTASCII_USTRINGPARAM( "CaptionPoint" )); + rtl::OUString sConnectorShape( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.ConnectorShape") ); + rtl::OUString sCaptionShape( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.CaptionShape") ); + rtl::OUString sStartShape(RTL_CONSTASCII_USTRINGPARAM("StartShape")); + rtl::OUString sEndShape(RTL_CONSTASCII_USTRINGPARAM("EndShape")); + rtl::OUString sStartPosition(RTL_CONSTASCII_USTRINGPARAM("StartPosition")); + rtl::OUString sEndPosition(RTL_CONSTASCII_USTRINGPARAM("EndPosition")); + uno::Reference<table::XCellRange> xTableRow; + uno::Reference<sheet::XSpreadsheet> xSheet; + uno::Reference<table::XTableRows> xTableRows; + sal_Int32 nOldRow(-1); + sal_Int32 nOldSheet(-1); + ScMyToResizeShapes::iterator aItr(aShapes.begin()); + ScMyToResizeShapes::iterator aEndItr(aShapes.end()); + uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( rImport.GetModel(), uno::UNO_QUERY ); + if ( xSpreadDoc.is() ) + { + uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY ); + ScDocument* pDoc(rImport.GetDocument()); + if ( pDoc && xIndex.is() ) + { + rImport.LockSolarMutex(); + while (aItr != aEndItr) + { + // #i78086# invalid cell position is used to call CreateChartListener only + if ( aItr->aEndCell.Sheet >= 0 ) + { + if ((nOldSheet != aItr->aEndCell.Sheet) || !xSheet.is()) + { + nOldSheet = aItr->aEndCell.Sheet; + xSheet.set(xIndex->getByIndex(nOldSheet), uno::UNO_QUERY); + if (xSheet.is()) + { + uno::Reference<table::XColumnRowRange> xColumnRowRange (xSheet, uno::UNO_QUERY); + if (xColumnRowRange.is()) + xTableRows = xColumnRowRange->getRows(); + } + } + if (xTableRows.is()) + { + if (nOldRow != aItr->aEndCell.Row || !xTableRow.is()) + { + nOldRow = aItr->aEndCell.Row; + xTableRows->getByIndex(nOldRow) >>= xTableRow; + } + if (xTableRow.is()) + { + uno::Reference <beans::XPropertySet> xRowProperties(xTableRow, uno::UNO_QUERY); + if (xRowProperties.is()) + { + sal_Int32 nHeight; + if (xRowProperties->getPropertyValue(sRowHeight) >>= nHeight) + { + Rectangle aRec = pDoc->GetMMRect(static_cast<SCCOL>(aItr->aStartCell.Column), static_cast<SCROW>(aItr->aStartCell.Row), + static_cast<SCCOL>(aItr->aStartCell.Column), static_cast<SCROW>(aItr->aStartCell.Row), aItr->aStartCell.Sheet); + awt::Point aPoint(aItr->xShape->getPosition()); + awt::Size aSize(aItr->xShape->getSize()); + if (pDoc->IsNegativePage(static_cast<SCTAB>(nOldSheet))) + aPoint.X += aSize.Width; + if (aItr->nEndY >= 0 && aItr->nEndX >= 0) + { + if (aItr->xShape->getShapeType().equals(sConnectorShape)) + { + //#103122#; handle connected Connectorshapes + uno::Reference<beans::XPropertySet> xShapeProps (aItr->xShape, uno::UNO_QUERY); + if(xShapeProps.is()) + { + uno::Reference<drawing::XShape> xStartShape(xShapeProps->getPropertyValue( sStartShape ), uno::UNO_QUERY); + uno::Reference<drawing::XShape> xEndShape(xShapeProps->getPropertyValue( sEndShape ), uno::UNO_QUERY); + if (!xStartShape.is() && !xEndShape.is()) + { + awt::Size aOldSize(aSize); + GetNewShapeSizePos(pDoc, aRec, aItr->aEndCell, aPoint, aSize, aItr->nEndX, aItr->nEndY); + aItr->xShape->setPosition(aPoint); + if( (aSize.Width != aOldSize.Width) || + (aSize.Height != aOldSize.Height) ) + aItr->xShape->setSize(aSize); + } + else if (xStartShape.is() && xEndShape.is()) + { + // do nothing, because they are connected + } + else + { + // only one point is connected, the other should be moved + + rtl::OUString sProperty; + if (xStartShape.is()) + { + awt::Point aEndPoint; + xShapeProps->getPropertyValue(sEndPosition) >>= aEndPoint; + aPoint.X = aRec.Left() + aEndPoint.X; + aPoint.Y = aRec.Top() + aEndPoint.Y; + sProperty = sEndPosition; + } + else + { + awt::Point aStartPoint; + xShapeProps->getPropertyValue(sStartPosition) >>= aStartPoint; + aPoint.X = aRec.Left() + aStartPoint.X; + aPoint.Y = aRec.Top() + aStartPoint.Y; + sProperty = sStartPosition; + } + xShapeProps->setPropertyValue(sProperty, uno::makeAny(aPoint)); + } + } + } + else + { + awt::Size aOldSize(aSize); + GetNewShapeSizePos(pDoc, aRec, aItr->aEndCell, aPoint, aSize, aItr->nEndX, aItr->nEndY); + if (pDoc->IsNegativePage(static_cast<SCTAB>(nOldSheet))) + aPoint.X -= aSize.Width; + aItr->xShape->setPosition(aPoint); + if( (aSize.Width != aOldSize.Width) || + (aSize.Height != aOldSize.Height) ) + aItr->xShape->setSize(aSize); + } + } + else + { + if (aItr->xShape->getShapeType().equals(sCaptionShape)) + { + Rectangle aRectangle(aPoint.X, aPoint.Y, aPoint.X + aSize.Width, aPoint.Y + aSize.Height); + + awt::Point aCaptionPoint; + uno::Reference< beans::XPropertySet > xShapeProps(aItr->xShape, uno::UNO_QUERY); + if (xShapeProps.is()) + { + try + { + xShapeProps->getPropertyValue( sCaptionPoint ) >>= aCaptionPoint; + } + catch ( uno::Exception& ) + { + DBG_ERROR("This Captionshape has no CaptionPoint property."); + } + } + Point aCorePoint(aPoint.X, aPoint.Y); + Point aCoreCaptionPoint(aCaptionPoint.X, aCaptionPoint.Y); + aCoreCaptionPoint += aCorePoint; + aRectangle.Union(Rectangle(aCoreCaptionPoint, aCoreCaptionPoint)); + + Point aBeforeRightBottomPoint(aRectangle.BottomRight()); + + aRectangle += aRec.TopLeft(); + if (aRectangle.Left() > aRec.Right()) + aRectangle -= (Point(aRectangle.Left() - aRec.Right() + 2, 0)); + if (aRectangle.Top() > aRec.Bottom()) + aRectangle -= (Point(0, aRectangle.Top() - aRec.Bottom() + 2)); + + Point aDifferencePoint(aRectangle.BottomRight() - aBeforeRightBottomPoint); + aPoint.X += aDifferencePoint.X(); + aPoint.Y += aDifferencePoint.Y(); + + aItr->xShape->setPosition(aPoint); + } + else + { + // #96159# it is possible, that shapes have a negative position + // this is now handled here + DBG_ERROR("no or negative end address of this shape"); + awt::Point aRefPoint; + aRefPoint.X = aRec.Left(); + aRefPoint.Y = aRec.Top(); + aPoint.X += aRefPoint.X; + if (aPoint.X > aRec.Right()) + aPoint.X = aRec.Right() - 2; // decrement by 2 100th_mm because the cellheight is internal in twips + aPoint.Y += aRefPoint.Y; + if (aPoint.Y > aRec.Bottom()) + aPoint.Y = aRec.Bottom() - 2; // decrement by 2 100th_mm because the cellheight is internal in twips + aItr->xShape->setPosition(aPoint); + } + } + } + } + } + } + else + { + DBG_ERROR("something wents wrong"); + } + } + // #i78086# call CreateChartListener also for invalid position (anchored to sheet) + if (IsOLE(aItr->xShape)) + { + uno::Reference < beans::XPropertySet > xShapeProps ( aItr->xShape, uno::UNO_QUERY ); + uno::Reference < beans::XPropertySetInfo > xShapeInfo(xShapeProps->getPropertySetInfo()); + rtl::OUString sName; + if (xShapeProps.is() && xShapeInfo.is() && xShapeInfo->hasPropertyByName(sPersistName) && + (xShapeProps->getPropertyValue(sPersistName) >>= sName)) + CreateChartListener(pDoc, sName, aItr->pRangeList); + } + if (aItr->pRangeList) + delete aItr->pRangeList; + aItr = aShapes.erase(aItr); + } + rImport.UnlockSolarMutex(); +// if (pCollection) +// pDoc->SetChartListenerCollection(pCollection); + } + } + } +} diff --git a/sc/source/filter/xml/XMLTableShapeResizer.hxx b/sc/source/filter/xml/XMLTableShapeResizer.hxx new file mode 100644 index 000000000000..9ece92995101 --- /dev/null +++ b/sc/source/filter/xml/XMLTableShapeResizer.hxx @@ -0,0 +1,81 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLTABLESHAPERESIZER_HXX +#define SC_XMLTABLESHAPERESIZER_HXX + +#include <com/sun/star/drawing/XShape.hpp> +#include <com/sun/star/table/CellAddress.hpp> +#include <com/sun/star/sheet/XSpreadsheet.hpp> +#include <list> + +class ScXMLImport; +class ScChartListenerCollection; +class ScDocument; +class Rectangle; + +struct ScMyToResizeShape +{ + com::sun::star::uno::Reference <com::sun::star::drawing::XShape> xShape; + rtl::OUString* pRangeList; + com::sun::star::table::CellAddress aEndCell; + com::sun::star::table::CellAddress aStartCell; + sal_Int32 nEndX; + sal_Int32 nEndY; + + ScMyToResizeShape() : pRangeList(NULL) {} +}; + +typedef std::list<ScMyToResizeShape> ScMyToResizeShapes; + +class ScMyShapeResizer +{ + ScXMLImport& rImport; + ScMyToResizeShapes aShapes; + ScChartListenerCollection* pCollection; + + sal_Bool IsOLE(com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& rShape) const; + void CreateChartListener(ScDocument* pDoc, + const rtl::OUString& rName, + const rtl::OUString* pRangeList); + void GetNewShapeSizePos(ScDocument* pDoc, const Rectangle& rStartRect, + const com::sun::star::table::CellAddress& rEndCell, + com::sun::star::awt::Point& rPoint, com::sun::star::awt::Size& rSize, + sal_Int32& rEndX, sal_Int32& rEndY) const; +public: + ScMyShapeResizer(ScXMLImport& rImport); + ~ScMyShapeResizer(); + + void AddShape(com::sun::star::uno::Reference <com::sun::star::drawing::XShape>& rShape, + rtl::OUString* pRangeList, + com::sun::star::table::CellAddress& rStartAddress, + com::sun::star::table::CellAddress& rEndAddress, + sal_Int32 nEndX, sal_Int32 nEndY); + void ResizeShapes(); +}; + +#endif diff --git a/sc/source/filter/xml/XMLTableShapesContext.cxx b/sc/source/filter/xml/XMLTableShapesContext.cxx new file mode 100644 index 000000000000..9d9bfc2a1a13 --- /dev/null +++ b/sc/source/filter/xml/XMLTableShapesContext.cxx @@ -0,0 +1,87 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- +#include "XMLTableShapesContext.hxx" +#include "XMLTableShapeImportHelper.hxx" +#include "xmlimprt.hxx" +#include "document.hxx" +#include <com/sun/star/drawing/XDrawPageSupplier.hpp> + +using namespace com::sun::star; + +//------------------------------------------------------------------ + +ScXMLTableShapesContext::ScXMLTableShapesContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) : + SvXMLImportContext( rImport, nPrfx, rLName ) +{ + // here are no attributes +} + +ScXMLTableShapesContext::~ScXMLTableShapesContext() +{ +} + +SvXMLImportContext *ScXMLTableShapesContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + if (!pContext) + { + ScXMLImport& rXMLImport(GetScImport()); + uno::Reference<drawing::XShapes> xShapes (rXMLImport.GetTables().GetCurrentXShapes()); + if (xShapes.is()) + { + XMLTableShapeImportHelper* pTableShapeImport((XMLTableShapeImportHelper*)rXMLImport.GetShapeImport().get()); + pTableShapeImport->SetOnTable(sal_True); + pContext = rXMLImport.GetShapeImport()->CreateGroupChildContext( + rXMLImport, nPrefix, rLName, xAttrList, xShapes); + } + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLTableShapesContext::EndElement() +{ +} + diff --git a/sc/source/filter/xml/XMLTableShapesContext.hxx b/sc/source/filter/xml/XMLTableShapesContext.hxx new file mode 100644 index 000000000000..ff38af0f9a2d --- /dev/null +++ b/sc/source/filter/xml/XMLTableShapesContext.hxx @@ -0,0 +1,55 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLTABLESHAPESCONTEXT_HXX +#define SC_XMLTABLESHAPESCONTEXT_HXX + +#include <xmloff/xmlictxt.hxx> + +class ScXMLImport; + +class ScXMLTableShapesContext : public SvXMLImportContext +{ + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } +public: + ScXMLTableShapesContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList); + + virtual ~ScXMLTableShapesContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +#endif diff --git a/sc/source/filter/xml/XMLTableSourceContext.cxx b/sc/source/filter/xml/XMLTableSourceContext.cxx new file mode 100644 index 000000000000..5abbe4c0ea26 --- /dev/null +++ b/sc/source/filter/xml/XMLTableSourceContext.cxx @@ -0,0 +1,146 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- +#include "XMLTableSourceContext.hxx" +#include "xmlimprt.hxx" +#include "document.hxx" +#include "xmlsubti.hxx" +#include "tablink.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmluconv.hxx> +#include <com/sun/star/sheet/XSheetLinkable.hpp> + +using namespace com::sun::star; +using namespace xmloff::token; + +//------------------------------------------------------------------ + +ScXMLTableSourceContext::ScXMLTableSourceContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList) : + SvXMLImportContext( rImport, nPrfx, rLName ), + sLink(), + sTableName(), + sFilterName(), + sFilterOptions(), + nRefresh(0), + nMode(sheet::SheetLinkMode_NORMAL) +{ + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + if(nPrefix == XML_NAMESPACE_XLINK) + { + if (IsXMLToken(aLocalName, XML_HREF)) + sLink = GetScImport().GetAbsoluteReference(sValue); + } + else if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(aLocalName, XML_TABLE_NAME)) + sTableName = sValue; + else if (IsXMLToken(aLocalName, XML_FILTER_NAME)) + sFilterName = sValue; + else if (IsXMLToken(aLocalName, XML_FILTER_OPTIONS)) + sFilterOptions = sValue; + else if (IsXMLToken(aLocalName, XML_MODE)) + { + if (IsXMLToken(sValue, XML_COPY_RESULTS_ONLY)) + nMode = sheet::SheetLinkMode_VALUE; + } + else if (IsXMLToken(aLocalName, XML_REFRESH_DELAY)) + { + double fTime; + if( SvXMLUnitConverter::convertTime( fTime, sValue ) ) + nRefresh = Max( (sal_Int32)(fTime * 86400.0), (sal_Int32)0 ); + } + } + } +} + +ScXMLTableSourceContext::~ScXMLTableSourceContext() +{ +} + +SvXMLImportContext *ScXMLTableSourceContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + return new SvXMLImportContext( GetImport(), nPrefix, rLName ); +} + +void ScXMLTableSourceContext::EndElement() +{ + if (sLink.getLength()) + { + uno::Reference <sheet::XSheetLinkable> xLinkable (GetScImport().GetTables().GetCurrentXSheet(), uno::UNO_QUERY); + ScDocument* pDoc(GetScImport().GetDocument()); + if (xLinkable.is() && pDoc) + { + GetScImport().LockSolarMutex(); + if (pDoc->RenameTab( static_cast<SCTAB>(GetScImport().GetTables().GetCurrentSheet()), + GetScImport().GetTables().GetCurrentSheetName(), sal_False, sal_True)) + { + String aFileString(sLink); + String aFilterString(sFilterName); + String aOptString(sFilterOptions); + String aSheetString(sTableName); + + aFileString = ScGlobal::GetAbsDocName( aFileString, pDoc->GetDocumentShell() ); + if ( !aFilterString.Len() ) + ScDocumentLoader::GetFilterName( aFileString, aFilterString, aOptString, sal_False, sal_False ); + + sal_uInt8 nLinkMode = SC_LINK_NONE; + if ( nMode == sheet::SheetLinkMode_NORMAL ) + nLinkMode = SC_LINK_NORMAL; + else if ( nMode == sheet::SheetLinkMode_VALUE ) + nLinkMode = SC_LINK_VALUE; + + pDoc->SetLink( static_cast<SCTAB>(GetScImport().GetTables().GetCurrentSheet()), + nLinkMode, aFileString, aFilterString, aOptString, + aSheetString, nRefresh ); + } + GetScImport().UnlockSolarMutex(); + } + } +} + diff --git a/sc/source/filter/xml/XMLTableSourceContext.hxx b/sc/source/filter/xml/XMLTableSourceContext.hxx new file mode 100644 index 000000000000..456c81baf636 --- /dev/null +++ b/sc/source/filter/xml/XMLTableSourceContext.hxx @@ -0,0 +1,63 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLTABLESOURCECONTEXT_HXX +#define SC_XMLTABLESOURCECONTEXT_HXX + +#include <xmloff/xmlictxt.hxx> +#include <com/sun/star/sheet/SheetLinkMode.hpp> + +class ScXMLImport; + +class ScXMLTableSourceContext : public SvXMLImportContext +{ + rtl::OUString sLink; + rtl::OUString sTableName; + rtl::OUString sFilterName; + rtl::OUString sFilterOptions; + sal_Int32 nRefresh; + com::sun::star::sheet::SheetLinkMode nMode; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } +public: + ScXMLTableSourceContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList); + + virtual ~ScXMLTableSourceContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +#endif diff --git a/sc/source/filter/xml/XMLTextPContext.cxx b/sc/source/filter/xml/XMLTextPContext.cxx new file mode 100644 index 000000000000..c95c881b4283 --- /dev/null +++ b/sc/source/filter/xml/XMLTextPContext.cxx @@ -0,0 +1,224 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- +#include "XMLTextPContext.hxx" +#include "xmlimprt.hxx" +#include "xmlcelli.hxx" +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/nmspmap.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/text/XTextCursor.hpp> + +using namespace com::sun::star; +using namespace xmloff::token; + +class ScXMLTextTContext : public SvXMLImportContext +{ + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } +public: + ScXMLTextTContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLTextPContext* pTextPContext); + + virtual ~ScXMLTextTContext(); +}; + + +ScXMLTextTContext::ScXMLTextTContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLTextPContext* pTextPContext) : + SvXMLImportContext( rImport, nPrfx, rLName ) +{ + if (pTextPContext) + { + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + rtl::OUString aLocalName; + sal_Int32 nCount(1); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + xAttrList->getNameByIndex( i ), &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + if ((nPrefix == XML_NAMESPACE_TEXT) && IsXMLToken(aLocalName, XML_C)) + nCount = sValue.toInt32(); + } + pTextPContext->AddSpaces(nCount); + } +} + +ScXMLTextTContext::~ScXMLTextTContext() +{ +} + +//------------------------------------------------------------------ + +ScXMLTextPContext::ScXMLTextPContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xTempAttrList, + ScXMLTableRowCellContext* pTempCellContext) : + SvXMLImportContext( rImport, nPrfx, rLName ), + xAttrList(xTempAttrList), + pTextPContext(NULL), + pCellContext(pTempCellContext), + sLName(rLName), + sSimpleContent(), + pContentBuffer(NULL), + nPrefix(nPrfx), + bIsOwn(sal_True) +{ + // here are no attributes +} + +ScXMLTextPContext::~ScXMLTextPContext() +{ + if (pTextPContext) + delete pTextPContext; + if (pContentBuffer) + delete pContentBuffer; +} + +void ScXMLTextPContext::AddSpaces(sal_Int32 nSpaceCount) +{ + // use pContentBuffer + if ( !pContentBuffer ) + pContentBuffer = new rtl::OUStringBuffer( sSimpleContent ); + + sal_Char* pChars = new sal_Char[nSpaceCount]; + memset(pChars, ' ', nSpaceCount); + pContentBuffer->appendAscii(pChars, nSpaceCount); +} + +SvXMLImportContext *ScXMLTextPContext::CreateChildContext( sal_uInt16 nTempPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xTempAttrList ) +{ + SvXMLImportContext *pContext(NULL); + if (!pTextPContext && + (nTempPrefix == XML_NAMESPACE_TEXT) && + IsXMLToken(rLName, XML_S)) + pContext = new ScXMLTextTContext( GetScImport(), nTempPrefix, rLName, xTempAttrList, this); + else + { + if (!pTextPContext) + { + rtl::OUString sSetString; + if ( pContentBuffer ) + sSetString = pContentBuffer->makeStringAndClear(); + else + sSetString = sSimpleContent; + + sal_Unicode cNonSpace(0); + + sal_Int32 nLength = sSetString.getLength(); + if ( nLength > 0 ) + { + sal_Unicode cLast = sSetString.getStr()[ nLength - 1 ]; + if ( cLast != (sal_Unicode)' ' ) + { + // #i53253# To keep XMLParaContext's whitespace handling in sync, + // if there's a non-space character at the end of the existing string, + // it has to be processed by XMLParaContext. + + cNonSpace = cLast; + sSetString = sSetString.copy( 0, nLength - 1 ); // remove from the string for SetCursorOnTextImport + } + } + + pCellContext->SetCursorOnTextImport( sSetString ); + + pTextPContext = GetScImport().GetTextImport()->CreateTextChildContext( + GetScImport(), nPrefix, sLName, xAttrList); + + if ( cNonSpace != 0 ) + { + // pass non-space character through XMLParaContext, so a following space isn't ignored + pTextPContext->Characters( rtl::OUString( cNonSpace ) ); + } + } + if (pTextPContext) + pContext = pTextPContext->CreateChildContext(nTempPrefix, rLName, xTempAttrList); + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetScImport(), nTempPrefix, rLName ); + + return pContext; +} + +void ScXMLTextPContext::Characters( const ::rtl::OUString& rChars ) +{ + if (!pTextPContext) + { + // For the first call to an empty context, copy (ref-counted) the OUString. + // The OUStringBuffer is used only if there is more complex content. + + if ( !pContentBuffer && sSimpleContent.getLength() == 0 ) + sSimpleContent = rChars; + else + { + if ( !pContentBuffer ) + pContentBuffer = new rtl::OUStringBuffer( sSimpleContent ); + pContentBuffer->append(rChars); + } + } + else + pTextPContext->Characters(rChars); +} + +void ScXMLTextPContext::EndElement() +{ + if (!pTextPContext) + { + if ( pContentBuffer ) + pCellContext->SetString(pContentBuffer->makeStringAndClear()); + else + pCellContext->SetString(sSimpleContent); + } + else + { + pTextPContext->EndElement(); + GetScImport().SetRemoveLastChar(sal_True); + } +} + diff --git a/sc/source/filter/xml/XMLTextPContext.hxx b/sc/source/filter/xml/XMLTextPContext.hxx new file mode 100644 index 000000000000..7df19470454f --- /dev/null +++ b/sc/source/filter/xml/XMLTextPContext.hxx @@ -0,0 +1,72 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLTEXTPCONTEXT_HXX +#define SC_XMLTEXTPCONTEXT_HXX + +#include <xmloff/xmlictxt.hxx> +#include <rtl/ustrbuf.hxx> + +class ScXMLImport; +class ScXMLTableRowCellContext; + +class ScXMLTextPContext : public SvXMLImportContext +{ + ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList> xAttrList; + SvXMLImportContext* pTextPContext; + ScXMLTableRowCellContext* pCellContext; + rtl::OUString sLName; + rtl::OUString sSimpleContent; // copy of the first Character call's argument + rtl::OUStringBuffer* pContentBuffer; // used if there's more than one string + sal_uInt16 nPrefix; + sal_Bool bIsOwn; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLTextPContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLTableRowCellContext* pCellContext); + + virtual ~ScXMLTextPContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void Characters( const ::rtl::OUString& rChars ); + + virtual void EndElement(); + + void AddSpaces(sal_Int32 nSpaceCount); +}; + +#endif diff --git a/sc/source/filter/xml/XMLTrackedChangesContext.cxx b/sc/source/filter/xml/XMLTrackedChangesContext.cxx new file mode 100644 index 000000000000..c084d83faeff --- /dev/null +++ b/sc/source/filter/xml/XMLTrackedChangesContext.cxx @@ -0,0 +1,2025 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +#include "XMLTrackedChangesContext.hxx" +#include "xmlimprt.hxx" +#include "xmlconti.hxx" +#include "XMLConverter.hxx" +#include "cell.hxx" +#include "textuno.hxx" +#include "editutil.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmluconv.hxx> +#include <svl/zforlist.hxx> +#include <com/sun/star/text/XTextCursor.hpp> +#include <com/sun/star/text/ControlCharacter.hpp> + +using rtl::OUString; +using namespace com::sun::star; +using namespace xmloff::token; + +//----------------------------------------------------------------------------- + +class ScXMLChangeInfoContext : public SvXMLImportContext +{ + ScMyActionInfo aInfo; + ::rtl::OUStringBuffer sAuthorBuffer; + ::rtl::OUStringBuffer sDateTimeBuffer; + ::rtl::OUStringBuffer sCommentBuffer; + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper; + sal_uInt32 nParagraphCount; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLChangeInfoContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper); + virtual ~ScXMLChangeInfoContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +//----------------------------------------------------------------------------- + +class ScXMLBigRangeContext : public SvXMLImportContext +{ + ScBigRange& rBigRange; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLBigRangeContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScBigRange& rBigRange); + virtual ~ScXMLBigRangeContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +//----------------------------------------------------------------------------- + +class ScXMLCellContentDeletionContext : public SvXMLImportContext +{ + rtl::OUString sFormulaAddress; + rtl::OUString sFormula; + rtl::OUString sFormulaNmsp; + rtl::OUString sInputString; + ScBigRange aBigRange; + double fValue; + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper; + ScBaseCell* pCell; + sal_uInt32 nID; + sal_Int32 nMatrixCols; + sal_Int32 nMatrixRows; + formula::FormulaGrammar::Grammar eGrammar; + sal_uInt16 nType; + sal_uInt8 nMatrixFlag; + sal_Bool bBigRange; + sal_Bool bContainsCell; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLCellContentDeletionContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper); + virtual ~ScXMLCellContentDeletionContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +//----------------------------------------------------------------------------- + +class ScXMLDependenceContext : public SvXMLImportContext +{ + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLDependenceContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper); + virtual ~ScXMLDependenceContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +//----------------------------------------------------------------------------- + +class ScXMLDependingsContext : public SvXMLImportContext +{ + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLDependingsContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper); + virtual ~ScXMLDependingsContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +//----------------------------------------------------------------------------- + +class ScXMLChangeDeletionContext : public SvXMLImportContext +{ + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLChangeDeletionContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper); + virtual ~ScXMLChangeDeletionContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +//----------------------------------------------------------------------------- + +class ScXMLDeletionsContext : public SvXMLImportContext +{ + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLDeletionsContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper); + virtual ~ScXMLDeletionsContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +//----------------------------------------------------------------------------- + +class ScXMLChangeCellContext; + +class ScXMLChangeTextPContext : public SvXMLImportContext +{ + ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList> xAttrList; + rtl::OUString sLName; + rtl::OUStringBuffer sText; + ScXMLChangeCellContext* pChangeCellContext; + SvXMLImportContext* pTextPContext; + sal_uInt16 nPrefix; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLChangeTextPContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLChangeCellContext* pChangeCellContext); + + virtual ~ScXMLChangeTextPContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void Characters( const ::rtl::OUString& rChars ); + + virtual void EndElement(); +}; + +//----------------------------------------------------------------------------- + +class ScXMLChangeCellContext : public SvXMLImportContext +{ + rtl::OUString sText; + rtl::OUString& rInputString; + ScBaseCell*& rOldCell; + ScEditEngineTextObj* pEditTextObj; + double& rDateTimeValue; + double fValue; + sal_uInt16& rType; +// sal_Bool bIsMatrix; +// sal_Bool bIsCoveredMatrix; + sal_Bool bEmpty; + sal_Bool bFirstParagraph; + sal_Bool bString; + sal_Bool bFormula; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLChangeCellContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScBaseCell*& rOldCell, rtl::OUString& sAddress, + rtl::OUString& rFormula, rtl::OUString& rFormulaNmsp, + formula::FormulaGrammar::Grammar& rGrammar, + rtl::OUString& rInputString, double& fValue, sal_uInt16& nType, + sal_uInt8& nMatrixFlag, sal_Int32& nMatrixCols, sal_Int32& nMatrixRows); + virtual ~ScXMLChangeCellContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + void CreateTextPContext(sal_Bool bIsNewParagraph); + sal_Bool IsEditCell() { return pEditTextObj != 0; } + void SetText(const rtl::OUString& sTempText) { sText = sTempText; } + + virtual void EndElement(); +}; + +//----------------------------------------------------------------------------- + +class ScXMLPreviousContext : public SvXMLImportContext +{ + rtl::OUString sFormulaAddress; + rtl::OUString sFormula; + rtl::OUString sFormulaNmsp; + rtl::OUString sInputString; + double fValue; + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper; + ScBaseCell* pOldCell; + sal_uInt32 nID; + sal_Int32 nMatrixCols; + sal_Int32 nMatrixRows; + formula::FormulaGrammar::Grammar eGrammar; + sal_uInt16 nType; + sal_uInt8 nMatrixFlag; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLPreviousContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper); + virtual ~ScXMLPreviousContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +//----------------------------------------------------------------------------- + +class ScXMLContentChangeContext : public SvXMLImportContext +{ + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper; + ScBigRange aBigRange; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLContentChangeContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper); + virtual ~ScXMLContentChangeContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + virtual void EndElement(); +}; + +//----------------------------------------------------------------------------- + +class ScXMLInsertionContext : public SvXMLImportContext +{ + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLInsertionContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper); + virtual ~ScXMLInsertionContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + virtual void EndElement(); +}; + +//----------------------------------------------------------------------------- + +class ScXMLInsertionCutOffContext : public SvXMLImportContext +{ + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLInsertionCutOffContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper); + virtual ~ScXMLInsertionCutOffContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + virtual void EndElement(); +}; + +//----------------------------------------------------------------------------- + +class ScXMLMovementCutOffContext : public SvXMLImportContext +{ + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLMovementCutOffContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper); + virtual ~ScXMLMovementCutOffContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + virtual void EndElement(); +}; + +//----------------------------------------------------------------------------- + +class ScXMLCutOffsContext : public SvXMLImportContext +{ + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLCutOffsContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper); + virtual ~ScXMLCutOffsContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + virtual void EndElement(); +}; + +//----------------------------------------------------------------------------- + +class ScXMLDeletionContext : public SvXMLImportContext +{ + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLDeletionContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper); + virtual ~ScXMLDeletionContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + virtual void EndElement(); +}; + +//----------------------------------------------------------------------------- + +class ScXMLMovementContext : public SvXMLImportContext +{ + ScBigRange aSourceRange; + ScBigRange aTargetRange; + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLMovementContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper); + virtual ~ScXMLMovementContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + virtual void EndElement(); +}; + +//----------------------------------------------------------------------------- + +class ScXMLRejectionContext : public SvXMLImportContext +{ + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLRejectionContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper); + virtual ~ScXMLRejectionContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + virtual void EndElement(); +}; + +//------------------------------------------------------------------ + +ScXMLTrackedChangesContext::ScXMLTrackedChangesContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pChangeTrackingImportHelper(pTempChangeTrackingImportHelper) +{ + rImport.LockSolarMutex(); + pChangeTrackingImportHelper->SetChangeTrack(sal_True); + + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(aLocalName, XML_PROTECTION_KEY)) + { + if (sValue.getLength()) + { + uno::Sequence<sal_Int8> aPass; + SvXMLUnitConverter::decodeBase64(aPass, sValue); + pChangeTrackingImportHelper->SetProtection(aPass); + } + } + } + } +} + +ScXMLTrackedChangesContext::~ScXMLTrackedChangesContext() +{ + GetScImport().UnlockSolarMutex(); +} + +SvXMLImportContext *ScXMLTrackedChangesContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(rLocalName, XML_CELL_CONTENT_CHANGE)) + { + pContext = new ScXMLContentChangeContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + } + else if (IsXMLToken(rLocalName, XML_INSERTION)) + { + pContext = new ScXMLInsertionContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + } + else if (IsXMLToken(rLocalName, XML_DELETION)) + { + pContext = new ScXMLDeletionContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + } + else if (IsXMLToken(rLocalName, XML_MOVEMENT)) + { + pContext = new ScXMLMovementContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + } + else if (IsXMLToken(rLocalName, XML_REJECTION)) + { + pContext = new ScXMLRejectionContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + } + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); + + return pContext; +} + +void ScXMLTrackedChangesContext::EndElement() +{ +} + +ScXMLChangeInfoContext::ScXMLChangeInfoContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + aInfo(), + pChangeTrackingImportHelper(pTempChangeTrackingImportHelper), + nParagraphCount(0) +{ + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + if (nPrefix == XML_NAMESPACE_OFFICE) + { + if (IsXMLToken(aLocalName, XML_CHG_AUTHOR)) + { + sAuthorBuffer = sValue; + } + else if (IsXMLToken(aLocalName, XML_CHG_DATE_TIME)) + { + sDateTimeBuffer = sValue; + } + } + } +} + +ScXMLChangeInfoContext::~ScXMLChangeInfoContext() +{ +} + +SvXMLImportContext *ScXMLChangeInfoContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + if( XML_NAMESPACE_DC == nPrefix ) + { + if( IsXMLToken( rLocalName, XML_CREATOR ) ) + pContext = new ScXMLContentContext(GetScImport(), nPrefix, + rLocalName, xAttrList, sAuthorBuffer); + else if( IsXMLToken( rLocalName, XML_DATE ) ) + pContext = new ScXMLContentContext(GetScImport(), nPrefix, + rLocalName, xAttrList, sDateTimeBuffer); + } + else if ((nPrefix == XML_NAMESPACE_TEXT) && (IsXMLToken(rLocalName, XML_P)) ) + { + if(nParagraphCount) + sCommentBuffer.append(static_cast<sal_Unicode>('\n')); + ++nParagraphCount; + pContext = new ScXMLContentContext( GetScImport(), nPrefix, rLocalName, xAttrList, sCommentBuffer); + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); + + return pContext; +} + +void ScXMLChangeInfoContext::EndElement() +{ + aInfo.sUser = sAuthorBuffer.makeStringAndClear(); + GetScImport().GetMM100UnitConverter().convertDateTime(aInfo.aDateTime, sDateTimeBuffer.makeStringAndClear()); + aInfo.sComment = sCommentBuffer.makeStringAndClear(); + pChangeTrackingImportHelper->SetActionInfo(aInfo); +} + +ScXMLBigRangeContext::ScXMLBigRangeContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList, + ScBigRange& rTempBigRange ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + rBigRange(rTempBigRange) +{ + sal_Bool bColumn(sal_False); + sal_Bool bRow(sal_False); + sal_Bool bTable(sal_False); + sal_Int32 nColumn(0); + sal_Int32 nRow(0); + sal_Int32 nTable(0); + sal_Int32 nStartColumn(0); + sal_Int32 nEndColumn(0); + sal_Int32 nStartRow(0); + sal_Int32 nEndRow(0); + sal_Int32 nStartTable(0); + sal_Int32 nEndTable(0); + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(aLocalName, XML_COLUMN)) + { + SvXMLUnitConverter::convertNumber(nColumn, sValue); + bColumn = sal_True; + } + else if (IsXMLToken(aLocalName, XML_ROW)) + { + SvXMLUnitConverter::convertNumber(nRow, sValue); + bRow = sal_True; + } + else if (IsXMLToken(aLocalName, XML_TABLE)) + { + SvXMLUnitConverter::convertNumber(nTable, sValue); + bTable = sal_True; + } + else if (IsXMLToken(aLocalName, XML_START_COLUMN)) + SvXMLUnitConverter::convertNumber(nStartColumn, sValue); + else if (IsXMLToken(aLocalName, XML_END_COLUMN)) + SvXMLUnitConverter::convertNumber(nEndColumn, sValue); + else if (IsXMLToken(aLocalName, XML_START_ROW)) + SvXMLUnitConverter::convertNumber(nStartRow, sValue); + else if (IsXMLToken(aLocalName, XML_END_ROW)) + SvXMLUnitConverter::convertNumber(nEndRow, sValue); + else if (IsXMLToken(aLocalName, XML_START_TABLE)) + SvXMLUnitConverter::convertNumber(nStartTable, sValue); + else if (IsXMLToken(aLocalName, XML_END_TABLE)) + SvXMLUnitConverter::convertNumber(nEndTable, sValue); + } + } + if (bColumn) + nStartColumn = nEndColumn = nColumn; + if (bRow) + nStartRow = nEndRow = nRow; + if (bTable) + nStartTable = nEndTable = nTable; + rBigRange.Set(nStartColumn, nStartRow, nStartTable, + nEndColumn, nEndRow, nEndTable); +} + +ScXMLBigRangeContext::~ScXMLBigRangeContext() +{ +} + +SvXMLImportContext *ScXMLBigRangeContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + return new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); +} + +void ScXMLBigRangeContext::EndElement() +{ +} + +ScXMLCellContentDeletionContext::ScXMLCellContentDeletionContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pChangeTrackingImportHelper(pTempChangeTrackingImportHelper), + pCell(NULL), + nID(0), + nMatrixCols(0), + nMatrixRows(0), + nType(NUMBERFORMAT_ALL), + nMatrixFlag(MM_NONE), + bBigRange(sal_False), + bContainsCell(sal_False) +{ + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(aLocalName, XML_ID)) + nID = pChangeTrackingImportHelper->GetIDFromString(sValue); + } + } +} + +ScXMLCellContentDeletionContext::~ScXMLCellContentDeletionContext() +{ +} + +SvXMLImportContext *ScXMLCellContentDeletionContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(rLocalName, XML_CHANGE_TRACK_TABLE_CELL)) + { + bContainsCell = sal_True; + pContext = new ScXMLChangeCellContext(GetScImport(), nPrefix, rLocalName, xAttrList, + pCell, sFormulaAddress, sFormula, sFormulaNmsp, eGrammar, sInputString, fValue, nType, nMatrixFlag, nMatrixCols, nMatrixRows ); + } + else if (IsXMLToken(rLocalName, XML_CELL_ADDRESS)) + { + DBG_ASSERT(!nID, "a action with a ID should not contain a BigRange"); + bBigRange = sal_True; + pContext = new ScXMLBigRangeContext(GetScImport(), nPrefix, rLocalName, xAttrList, aBigRange); + } + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); + + return pContext; +} + +void ScXMLCellContentDeletionContext::EndElement() +{ + ScMyCellInfo* pCellInfo(new ScMyCellInfo(pCell, sFormulaAddress, sFormula, eGrammar, sInputString, fValue, nType, + nMatrixFlag, nMatrixCols, nMatrixRows)); + if (nID) + pChangeTrackingImportHelper->AddDeleted(nID, pCellInfo); + else + pChangeTrackingImportHelper->AddGenerated(pCellInfo, aBigRange); +} + +ScXMLDependenceContext::ScXMLDependenceContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pChangeTrackingImportHelper(pTempChangeTrackingImportHelper) +{ + sal_uInt32 nID(0); + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(aLocalName, XML_ID)) + nID = pChangeTrackingImportHelper->GetIDFromString(sValue); + } + } + pChangeTrackingImportHelper->AddDependence(nID); +} + +ScXMLDependenceContext::~ScXMLDependenceContext() +{ +} + +SvXMLImportContext *ScXMLDependenceContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + return new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); +} + +void ScXMLDependenceContext::EndElement() +{ +} + +ScXMLDependingsContext::ScXMLDependingsContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const uno::Reference<xml::sax::XAttributeList>& /* xAttrList */, + ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pChangeTrackingImportHelper(pTempChangeTrackingImportHelper) +{ + // here are no attributes +} + +ScXMLDependingsContext::~ScXMLDependingsContext() +{ +} + +SvXMLImportContext *ScXMLDependingsContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + if (nPrefix == XML_NAMESPACE_TABLE) + { + // #i80033# read both old (dependence) and new (dependency) elements + if (IsXMLToken(rLocalName, XML_DEPENDENCE) || IsXMLToken(rLocalName, XML_DEPENDENCY)) + pContext = new ScXMLDependenceContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); + + return pContext; +} + +void ScXMLDependingsContext::EndElement() +{ +} + +ScXMLChangeDeletionContext::ScXMLChangeDeletionContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pChangeTrackingImportHelper(pTempChangeTrackingImportHelper) +{ + sal_uInt32 nID(0); + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(aLocalName, XML_ID)) + nID = pChangeTrackingImportHelper->GetIDFromString(sValue); + } + } + pChangeTrackingImportHelper->AddDeleted(nID); +} + +ScXMLChangeDeletionContext::~ScXMLChangeDeletionContext() +{ +} + +SvXMLImportContext *ScXMLChangeDeletionContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + return new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); +} + +void ScXMLChangeDeletionContext::EndElement() +{ +} + +ScXMLDeletionsContext::ScXMLDeletionsContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const uno::Reference<xml::sax::XAttributeList>& /* xAttrList */, + ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pChangeTrackingImportHelper(pTempChangeTrackingImportHelper) +{ + // here are no attributes +} + +ScXMLDeletionsContext::~ScXMLDeletionsContext() +{ +} + +SvXMLImportContext *ScXMLDeletionsContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(rLocalName, XML_CHANGE_DELETION)) + pContext = new ScXMLChangeDeletionContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + else if (IsXMLToken(rLocalName, XML_CELL_CONTENT_DELETION)) + pContext = new ScXMLCellContentDeletionContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); + + return pContext; +} + +void ScXMLDeletionsContext::EndElement() +{ +} + +ScXMLChangeTextPContext::ScXMLChangeTextPContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xTempAttrList, + ScXMLChangeCellContext* pTempChangeCellContext) : + SvXMLImportContext( rImport, nPrfx, rLName ), + xAttrList(xTempAttrList), + sLName(rLName), + sText(), + pChangeCellContext(pTempChangeCellContext), + pTextPContext(NULL), + nPrefix(nPrfx) +{ + // here are no attributes +} + +ScXMLChangeTextPContext::~ScXMLChangeTextPContext() +{ + if (pTextPContext) + delete pTextPContext; +} + +SvXMLImportContext *ScXMLChangeTextPContext::CreateChildContext( sal_uInt16 nTempPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xTempAttrList ) +{ + SvXMLImportContext *pContext(0); + + if ((nPrefix == XML_NAMESPACE_TEXT) && (IsXMLToken(rLName, XML_S)) && !pTextPContext) + { + sal_Int32 nRepeat(0); + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrfx(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + if ((nPrfx == XML_NAMESPACE_TEXT) && (IsXMLToken(aLocalName, XML_C))) + nRepeat = sValue.toInt32(); + } + if (nRepeat) + for (sal_Int32 j = 0; j < nRepeat; ++j) + sText.append(static_cast<sal_Unicode>(' ')); + else + sText.append(static_cast<sal_Unicode>(' ')); + } + else + { + if (!pChangeCellContext->IsEditCell()) + pChangeCellContext->CreateTextPContext(sal_False); + sal_Bool bWasContext (sal_True); + if (!pTextPContext) + { + bWasContext = sal_False; + pTextPContext = GetScImport().GetTextImport()->CreateTextChildContext( + GetScImport(), nPrefix, sLName, xAttrList); + } + if (pTextPContext) + { + if (!bWasContext) + pTextPContext->Characters(sText.makeStringAndClear()); + pContext = pTextPContext->CreateChildContext(nTempPrefix, rLName, xTempAttrList); + } + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLChangeTextPContext::Characters( const ::rtl::OUString& rChars ) +{ + if (!pTextPContext) + sText.append(rChars); + else + pTextPContext->Characters(rChars); +} + +void ScXMLChangeTextPContext::EndElement() +{ + if (!pTextPContext) + pChangeCellContext->SetText(sText.makeStringAndClear()); +} + +ScXMLChangeCellContext::ScXMLChangeCellContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList, + ScBaseCell*& rTempOldCell, rtl::OUString& rAddress, + rtl::OUString& rFormula, rtl::OUString& rFormulaNmsp, + formula::FormulaGrammar::Grammar& rGrammar, + rtl::OUString& rTempInputString, double& fDateTimeValue, sal_uInt16& nType, + sal_uInt8& nMatrixFlag, sal_Int32& nMatrixCols, sal_Int32& nMatrixRows ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + rInputString(rTempInputString), + rOldCell(rTempOldCell), + pEditTextObj(NULL), + rDateTimeValue(fDateTimeValue), + rType(nType), + bEmpty(sal_True), + bFirstParagraph(sal_True), + bString(sal_True), + bFormula(sal_False) +{ + sal_Bool bIsMatrix(sal_False); + sal_Bool bIsCoveredMatrix(sal_False); + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(aLocalName, XML_FORMULA)) + { + bEmpty = sal_False; + GetScImport().ExtractFormulaNamespaceGrammar( rFormula, rFormulaNmsp, rGrammar, sValue ); + bFormula = sal_True; + } + else if (IsXMLToken(aLocalName, XML_CELL_ADDRESS)) + { + rAddress = sValue; + } + else if (IsXMLToken(aLocalName, XML_MATRIX_COVERED)) + { + bIsCoveredMatrix = IsXMLToken(sValue, XML_TRUE); + } + else if (IsXMLToken(aLocalName, XML_NUMBER_MATRIX_COLUMNS_SPANNED)) + { + bIsMatrix = sal_True; + SvXMLUnitConverter::convertNumber(nMatrixCols, sValue); + } + else if (IsXMLToken(aLocalName, XML_NUMBER_MATRIX_ROWS_SPANNED)) + { + bIsMatrix = sal_True; + SvXMLUnitConverter::convertNumber(nMatrixRows, sValue); + } + } + else if (nPrefix == XML_NAMESPACE_OFFICE) + { + if (IsXMLToken(aLocalName, XML_VALUE_TYPE)) + { + if (IsXMLToken(sValue, XML_FLOAT)) + bString = sal_False; + else if (IsXMLToken(sValue, XML_DATE)) + { + rType = NUMBERFORMAT_DATE; + bString = sal_False; + } + else if (IsXMLToken(sValue, XML_TIME)) + { + rType = NUMBERFORMAT_TIME; + bString = sal_False; + } + } + else if (IsXMLToken(aLocalName, XML_VALUE)) + { + SvXMLUnitConverter::convertDouble(fValue, sValue); + bEmpty = sal_False; + } + else if (IsXMLToken(aLocalName, XML_DATE_VALUE)) + { + bEmpty = sal_False; + if (GetScImport().GetMM100UnitConverter().setNullDate(GetScImport().GetModel())) + GetScImport().GetMM100UnitConverter().convertDateTime(rDateTimeValue, sValue); + fValue = rDateTimeValue; + } + else if (IsXMLToken(aLocalName, XML_TIME_VALUE)) + { + bEmpty = sal_False; + GetScImport().GetMM100UnitConverter().convertTime(rDateTimeValue, sValue); + fValue = rDateTimeValue; + } + } + } + if (bIsCoveredMatrix) + nMatrixFlag = MM_REFERENCE; + else if (bIsMatrix && nMatrixRows && nMatrixCols) + nMatrixFlag = MM_FORMULA; +} + +ScXMLChangeCellContext::~ScXMLChangeCellContext() +{ +} + +SvXMLImportContext *ScXMLChangeCellContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + if ((nPrefix == XML_NAMESPACE_TEXT) && (IsXMLToken(rLocalName, XML_P))) + { + bEmpty = sal_False; + if (bFirstParagraph) + { + pContext = new ScXMLChangeTextPContext(GetScImport(), nPrefix, rLocalName, xAttrList, this); + bFirstParagraph = sal_False; + } + else + { + if (!pEditTextObj) + CreateTextPContext(sal_True); + pContext = GetScImport().GetTextImport()->CreateTextChildContext( + GetScImport(), nPrefix, rLocalName, xAttrList); + } + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); + + return pContext; +} + +void ScXMLChangeCellContext::CreateTextPContext(sal_Bool bIsNewParagraph) +{ + if (GetScImport().GetDocument()) + { + pEditTextObj = new ScEditEngineTextObj(); + pEditTextObj->acquire(); + pEditTextObj->GetEditEngine()->SetEditTextObjectPool(GetScImport().GetDocument()->GetEditPool()); + uno::Reference <text::XText> xText(pEditTextObj); + if (xText.is()) + { + uno::Reference<text::XTextCursor> xTextCursor(xText->createTextCursor()); + if (bIsNewParagraph) + { + xText->setString(sText); + xTextCursor->gotoEnd(sal_False); + uno::Reference < text::XTextRange > xTextRange (xTextCursor, uno::UNO_QUERY); + if (xTextRange.is()) + xText->insertControlCharacter(xTextRange, text::ControlCharacter::PARAGRAPH_BREAK, sal_False); + } + GetScImport().GetTextImport()->SetCursor(xTextCursor); + } + } +} + +void ScXMLChangeCellContext::EndElement() +{ + if (!bEmpty) + { + if (pEditTextObj) + { + if (GetImport().GetTextImport()->GetCursor().is()) + { + //GetImport().GetTextImport()->GetCursor()->gotoEnd(sal_False); + if( GetImport().GetTextImport()->GetCursor()->goLeft( 1, sal_True ) ) + { + OUString sEmpty; + GetImport().GetTextImport()->GetText()->insertString( + GetImport().GetTextImport()->GetCursorAsRange(), sEmpty, + sal_True ); + } + } + if (GetScImport().GetDocument()) + rOldCell = new ScEditCell(pEditTextObj->CreateTextObject(), GetScImport().GetDocument(), GetScImport().GetDocument()->GetEditPool()); + GetScImport().GetTextImport()->ResetCursor(); + // delete pEditTextObj; + pEditTextObj->release(); + } + else + { + if (!bFormula) + { + if (sText.getLength() && bString) + rOldCell = new ScStringCell(sText); + else + rOldCell = new ScValueCell(fValue); + if (rType == NUMBERFORMAT_DATE || rType == NUMBERFORMAT_TIME) + rInputString = sText; + } + else + { + // do nothing, this has to do later (on another place) + /*ScAddress aCellPos; + rOldCell = new ScFormulaCell(GetScImport().GetDocument(), aCellPos, sFormula); + if (bString) + static_cast<ScFormulaCell*>(rOldCell)->SetString(sValue); + else + static_cast<ScFormulaCell*>(rOldCell)->SetDouble(fValue); + static_cast<ScFormulaCell*>(rOldCell)->SetInChangeTrack(sal_True); + if (bIsCoveredMatrix) + static_cast<ScFormulaCell*>(rOldCell)->SetMatrixFlag(MM_REFERENCE); + else if (bIsMatrix && nMatrixRows && nMatrixCols) + { + static_cast<ScFormulaCell*>(rOldCell)->SetMatrixFlag(MM_FORMULA); + static_cast<ScFormulaCell*>(rOldCell)->SetMatColsRows(static_cast<SCCOL>(nMatrixCols), static_cast<SCROW>(nMatrixRows)); + }*/ + } + } + } + else + rOldCell = NULL; +} + +ScXMLPreviousContext::ScXMLPreviousContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pChangeTrackingImportHelper(pTempChangeTrackingImportHelper), + pOldCell(NULL), + nID(0), + nMatrixCols(0), + nMatrixRows(0), + eGrammar( formula::FormulaGrammar::GRAM_STORAGE_DEFAULT), + nType(NUMBERFORMAT_ALL), + nMatrixFlag(MM_NONE) +{ + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(aLocalName, XML_ID)) + nID = pChangeTrackingImportHelper->GetIDFromString(sValue); + } + } +} + +ScXMLPreviousContext::~ScXMLPreviousContext() +{ +} + +SvXMLImportContext *ScXMLPreviousContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + if ((nPrefix == XML_NAMESPACE_TABLE) && (IsXMLToken(rLocalName, XML_CHANGE_TRACK_TABLE_CELL))) + pContext = new ScXMLChangeCellContext(GetScImport(), nPrefix, rLocalName, xAttrList, + pOldCell, sFormulaAddress, sFormula, sFormulaNmsp, eGrammar, sInputString, fValue, nType, nMatrixFlag, nMatrixCols, nMatrixRows); + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); + + return pContext; +} + +void ScXMLPreviousContext::EndElement() +{ + pChangeTrackingImportHelper->SetPreviousChange(nID, new ScMyCellInfo(pOldCell, sFormulaAddress, sFormula, eGrammar, sInputString, + fValue, nType, nMatrixFlag, nMatrixCols, nMatrixRows)); +} + +ScXMLContentChangeContext::ScXMLContentChangeContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pChangeTrackingImportHelper(pTempChangeTrackingImportHelper) +{ + sal_uInt32 nActionNumber(0); + sal_uInt32 nRejectingNumber(0); + ScChangeActionState nActionState(SC_CAS_VIRGIN); + + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(aLocalName, XML_ID)) + { + nActionNumber = pChangeTrackingImportHelper->GetIDFromString(sValue); + } + else if (IsXMLToken(aLocalName, XML_ACCEPTANCE_STATE)) + { + if (IsXMLToken(sValue, XML_ACCEPTED)) + nActionState = SC_CAS_ACCEPTED; + else if (IsXMLToken(sValue, XML_REJECTED)) + nActionState = SC_CAS_REJECTED; + } + else if (IsXMLToken(aLocalName, XML_REJECTING_CHANGE_ID)) + { + nRejectingNumber = pChangeTrackingImportHelper->GetIDFromString(sValue); + } + } + } + + pChangeTrackingImportHelper->StartChangeAction(SC_CAT_CONTENT); + pChangeTrackingImportHelper->SetActionNumber(nActionNumber); + pChangeTrackingImportHelper->SetActionState(nActionState); + pChangeTrackingImportHelper->SetRejectingNumber(nRejectingNumber); +} + +ScXMLContentChangeContext::~ScXMLContentChangeContext() +{ +} + +SvXMLImportContext *ScXMLContentChangeContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + if ((nPrefix == XML_NAMESPACE_OFFICE) && (IsXMLToken(rLocalName, XML_CHANGE_INFO))) + { + pContext = new ScXMLChangeInfoContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + } + else if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(rLocalName, XML_CELL_ADDRESS)) + { + pContext = new ScXMLBigRangeContext(GetScImport(), nPrefix, rLocalName, xAttrList, aBigRange); + } + else if (IsXMLToken(rLocalName, XML_DEPENDENCIES)) + { + pContext = new ScXMLDependingsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + } + else if (IsXMLToken(rLocalName, XML_DELETIONS)) + pContext = new ScXMLDeletionsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + else if (IsXMLToken(rLocalName, XML_PREVIOUS)) + { + pContext = new ScXMLPreviousContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + } + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); + + return pContext; +} + +void ScXMLContentChangeContext::EndElement() +{ + pChangeTrackingImportHelper->SetBigRange(aBigRange); + pChangeTrackingImportHelper->EndChangeAction(); +} + +ScXMLInsertionContext::ScXMLInsertionContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pChangeTrackingImportHelper(pTempChangeTrackingImportHelper) +{ + sal_uInt32 nActionNumber(0); + sal_uInt32 nRejectingNumber(0); + sal_Int32 nPosition(0); + sal_Int32 nCount(1); + sal_Int32 nTable(0); + ScChangeActionState nActionState(SC_CAS_VIRGIN); + ScChangeActionType nActionType(SC_CAT_INSERT_COLS); + + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(aLocalName, XML_ID)) + { + nActionNumber = pChangeTrackingImportHelper->GetIDFromString(sValue); + } + else if (IsXMLToken(aLocalName, XML_ACCEPTANCE_STATE)) + { + if (IsXMLToken(sValue, XML_ACCEPTED)) + nActionState = SC_CAS_ACCEPTED; + else if (IsXMLToken(sValue, XML_REJECTED)) + nActionState = SC_CAS_REJECTED; + } + else if (IsXMLToken(aLocalName, XML_REJECTING_CHANGE_ID)) + { + nRejectingNumber = pChangeTrackingImportHelper->GetIDFromString(sValue); + } + else if (IsXMLToken(aLocalName, XML_TYPE)) + { + if (IsXMLToken(sValue, XML_ROW)) + nActionType = SC_CAT_INSERT_ROWS; + else if (IsXMLToken(sValue, XML_TABLE)) + nActionType = SC_CAT_INSERT_TABS; + } + else if (IsXMLToken(aLocalName, XML_POSITION)) + { + SvXMLUnitConverter::convertNumber(nPosition, sValue); + } + else if (IsXMLToken(aLocalName, XML_TABLE)) + { + SvXMLUnitConverter::convertNumber(nTable, sValue); + } + else if (IsXMLToken(aLocalName, XML_COUNT)) + { + SvXMLUnitConverter::convertNumber(nCount, sValue); + } + } + } + + pChangeTrackingImportHelper->StartChangeAction(nActionType); + pChangeTrackingImportHelper->SetActionNumber(nActionNumber); + pChangeTrackingImportHelper->SetActionState(nActionState); + pChangeTrackingImportHelper->SetRejectingNumber(nRejectingNumber); + pChangeTrackingImportHelper->SetPosition(nPosition, nCount, nTable); +} + +ScXMLInsertionContext::~ScXMLInsertionContext() +{ +} + +SvXMLImportContext *ScXMLInsertionContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + if ((nPrefix == XML_NAMESPACE_OFFICE) && (IsXMLToken(rLocalName, XML_CHANGE_INFO))) + { + pContext = new ScXMLChangeInfoContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + } + else if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(rLocalName, XML_DEPENDENCIES)) + pContext = new ScXMLDependingsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + else if (IsXMLToken(rLocalName, XML_DELETIONS)) + pContext = new ScXMLDeletionsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); + + return pContext; +} + +void ScXMLInsertionContext::EndElement() +{ + pChangeTrackingImportHelper->EndChangeAction(); +} + +ScXMLInsertionCutOffContext::ScXMLInsertionCutOffContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pChangeTrackingImportHelper(pTempChangeTrackingImportHelper) +{ + sal_uInt32 nID(0); + sal_Int32 nPosition(0); + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(aLocalName, XML_ID)) + { + nID = pChangeTrackingImportHelper->GetIDFromString(sValue); + } + else if (IsXMLToken(aLocalName, XML_POSITION)) + { + SvXMLUnitConverter::convertNumber(nPosition, sValue); + } + } + } + pChangeTrackingImportHelper->SetInsertionCutOff(nID, nPosition); +} + +ScXMLInsertionCutOffContext::~ScXMLInsertionCutOffContext() +{ +} + +SvXMLImportContext *ScXMLInsertionCutOffContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + return new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); +} + +void ScXMLInsertionCutOffContext::EndElement() +{ +} + +ScXMLMovementCutOffContext::ScXMLMovementCutOffContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pChangeTrackingImportHelper(pTempChangeTrackingImportHelper) +{ + sal_uInt32 nID(0); + sal_Int32 nPosition(0); + sal_Int32 nStartPosition(0); + sal_Int32 nEndPosition(0); + sal_Bool bPosition(sal_False); + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(aLocalName, XML_ID)) + { + nID = pChangeTrackingImportHelper->GetIDFromString(sValue); + } + else if (IsXMLToken(aLocalName, XML_POSITION)) + { + bPosition = sal_True; + SvXMLUnitConverter::convertNumber(nPosition, sValue); + } + else if (IsXMLToken(aLocalName, XML_START_POSITION)) + { + SvXMLUnitConverter::convertNumber(nStartPosition, sValue); + } + else if (IsXMLToken(aLocalName, XML_END_POSITION)) + { + SvXMLUnitConverter::convertNumber(nEndPosition, sValue); + } + } + } + if (bPosition) + nStartPosition = nEndPosition = nPosition; + pChangeTrackingImportHelper->AddMoveCutOff(nID, nStartPosition, nEndPosition); +} + +ScXMLMovementCutOffContext::~ScXMLMovementCutOffContext() +{ +} + +SvXMLImportContext *ScXMLMovementCutOffContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + return new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); +} + +void ScXMLMovementCutOffContext::EndElement() +{ +} + +ScXMLCutOffsContext::ScXMLCutOffsContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const uno::Reference<xml::sax::XAttributeList>& /* xAttrList */, + ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pChangeTrackingImportHelper(pTempChangeTrackingImportHelper) +{ + // here are no attributes +} + +ScXMLCutOffsContext::~ScXMLCutOffsContext() +{ +} + +SvXMLImportContext *ScXMLCutOffsContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(rLocalName, XML_INSERTION_CUT_OFF)) + pContext = new ScXMLInsertionCutOffContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + else if (IsXMLToken(rLocalName, XML_MOVEMENT_CUT_OFF)) + pContext = new ScXMLMovementCutOffContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); + + return pContext; +} + +void ScXMLCutOffsContext::EndElement() +{ +} + +ScXMLDeletionContext::ScXMLDeletionContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pChangeTrackingImportHelper(pTempChangeTrackingImportHelper) +{ + sal_uInt32 nActionNumber(0); + sal_uInt32 nRejectingNumber(0); + sal_Int32 nPosition(0); + sal_Int32 nMultiSpanned(0); + sal_Int32 nTable(0); + ScChangeActionState nActionState(SC_CAS_VIRGIN); + ScChangeActionType nActionType(SC_CAT_DELETE_COLS); + + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + for( sal_Int16 i=0; i < nAttrCount; i++ ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(aLocalName, XML_ID)) + { + nActionNumber = pChangeTrackingImportHelper->GetIDFromString(sValue); + } + else if (IsXMLToken(aLocalName, XML_ACCEPTANCE_STATE)) + { + if (IsXMLToken(sValue, XML_ACCEPTED)) + nActionState = SC_CAS_ACCEPTED; + else if (IsXMLToken(sValue, XML_REJECTED)) + nActionState = SC_CAS_REJECTED; + } + else if (IsXMLToken(aLocalName, XML_REJECTING_CHANGE_ID)) + { + nRejectingNumber = pChangeTrackingImportHelper->GetIDFromString(sValue); + } + else if (IsXMLToken(aLocalName, XML_TYPE)) + { + if (IsXMLToken(sValue, XML_ROW)) + { + nActionType = SC_CAT_DELETE_ROWS; + } + else if (IsXMLToken(aLocalName, XML_TABLE)) + { + nActionType = SC_CAT_DELETE_TABS; + } + } + else if (IsXMLToken(aLocalName, XML_POSITION)) + { + SvXMLUnitConverter::convertNumber(nPosition, sValue); + } + else if (IsXMLToken(aLocalName, XML_TABLE)) + { + SvXMLUnitConverter::convertNumber(nTable, sValue); + } + else if (IsXMLToken(aLocalName, XML_MULTI_DELETION_SPANNED)) + { + SvXMLUnitConverter::convertNumber(nMultiSpanned, sValue); + } + } + } + + pChangeTrackingImportHelper->StartChangeAction(nActionType); + pChangeTrackingImportHelper->SetActionNumber(nActionNumber); + pChangeTrackingImportHelper->SetActionState(nActionState); + pChangeTrackingImportHelper->SetRejectingNumber(nRejectingNumber); + pChangeTrackingImportHelper->SetPosition(nPosition, 1, nTable); + pChangeTrackingImportHelper->SetMultiSpanned(static_cast<sal_Int16>(nMultiSpanned)); +} + +ScXMLDeletionContext::~ScXMLDeletionContext() +{ +} + +SvXMLImportContext *ScXMLDeletionContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + if ((nPrefix == XML_NAMESPACE_OFFICE) && (IsXMLToken(rLocalName, XML_CHANGE_INFO))) + { + pContext = new ScXMLChangeInfoContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + } + else if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(rLocalName, XML_DEPENDENCIES)) + pContext = new ScXMLDependingsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + else if (IsXMLToken(rLocalName, XML_DELETIONS)) + pContext = new ScXMLDeletionsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + else if (IsXMLToken(rLocalName, XML_CUT_OFFS) || rLocalName.equalsAsciiL("cut_offs", 8)) + pContext = new ScXMLCutOffsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + else + { + DBG_ERROR("don't know this"); + } + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); + + return pContext; +} + +void ScXMLDeletionContext::EndElement() +{ + pChangeTrackingImportHelper->EndChangeAction(); +} + +ScXMLMovementContext::ScXMLMovementContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pChangeTrackingImportHelper(pTempChangeTrackingImportHelper) +{ + sal_uInt32 nActionNumber(0); + sal_uInt32 nRejectingNumber(0); + ScChangeActionState nActionState(SC_CAS_VIRGIN); + + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(aLocalName, XML_ID)) + { + nActionNumber = pChangeTrackingImportHelper->GetIDFromString(sValue); + } + else if (IsXMLToken(aLocalName, XML_ACCEPTANCE_STATE)) + { + if (IsXMLToken(sValue, XML_ACCEPTED)) + nActionState = SC_CAS_ACCEPTED; + else if (IsXMLToken(sValue, XML_REJECTED)) + nActionState = SC_CAS_REJECTED; + } + else if (IsXMLToken(aLocalName, XML_REJECTING_CHANGE_ID)) + { + nRejectingNumber = pChangeTrackingImportHelper->GetIDFromString(sValue); + } + } + } + + pChangeTrackingImportHelper->StartChangeAction(SC_CAT_MOVE); + pChangeTrackingImportHelper->SetActionNumber(nActionNumber); + pChangeTrackingImportHelper->SetActionState(nActionState); + pChangeTrackingImportHelper->SetRejectingNumber(nRejectingNumber); +} + +ScXMLMovementContext::~ScXMLMovementContext() +{ +} + +SvXMLImportContext *ScXMLMovementContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + if ((nPrefix == XML_NAMESPACE_OFFICE) && (IsXMLToken(rLocalName, XML_CHANGE_INFO))) + { + pContext = new ScXMLChangeInfoContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + } + else if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(rLocalName, XML_DEPENDENCIES)) + pContext = new ScXMLDependingsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + else if (IsXMLToken(rLocalName, XML_DELETIONS)) + pContext = new ScXMLDeletionsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + else if (IsXMLToken(rLocalName, XML_SOURCE_RANGE_ADDRESS)) + pContext = new ScXMLBigRangeContext(GetScImport(), nPrefix, rLocalName, xAttrList, aSourceRange); + else if (IsXMLToken(rLocalName, XML_TARGET_RANGE_ADDRESS)) + pContext = new ScXMLBigRangeContext(GetScImport(), nPrefix, rLocalName, xAttrList, aTargetRange); + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); + + return pContext; +} + +void ScXMLMovementContext::EndElement() +{ + pChangeTrackingImportHelper->SetMoveRanges(aSourceRange, aTargetRange); + pChangeTrackingImportHelper->EndChangeAction(); +} + +ScXMLRejectionContext::ScXMLRejectionContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pTempChangeTrackingImportHelper ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pChangeTrackingImportHelper(pTempChangeTrackingImportHelper) +{ + sal_uInt32 nActionNumber(0); + sal_uInt32 nRejectingNumber(0); + ScChangeActionState nActionState(SC_CAS_VIRGIN); + + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(aLocalName, XML_ID)) + { + nActionNumber = pChangeTrackingImportHelper->GetIDFromString(sValue); + } + else if (IsXMLToken(aLocalName, XML_ACCEPTANCE_STATE)) + { + if (IsXMLToken(sValue, XML_ACCEPTED)) + nActionState = SC_CAS_ACCEPTED; + else if (IsXMLToken(sValue, XML_REJECTED)) + nActionState = SC_CAS_REJECTED; + } + else if (IsXMLToken(aLocalName, XML_REJECTING_CHANGE_ID)) + { + nRejectingNumber = pChangeTrackingImportHelper->GetIDFromString(sValue); + } + } + } + + pChangeTrackingImportHelper->StartChangeAction(SC_CAT_MOVE); + pChangeTrackingImportHelper->SetActionNumber(nActionNumber); + pChangeTrackingImportHelper->SetActionState(nActionState); + pChangeTrackingImportHelper->SetRejectingNumber(nRejectingNumber); +} + +ScXMLRejectionContext::~ScXMLRejectionContext() +{ +} + +SvXMLImportContext *ScXMLRejectionContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + if ((nPrefix == XML_NAMESPACE_OFFICE) && (IsXMLToken(rLocalName, XML_CHANGE_INFO))) + { + pContext = new ScXMLChangeInfoContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + } + else if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(rLocalName, XML_DEPENDENCIES)) + pContext = new ScXMLDependingsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + else if (IsXMLToken(rLocalName, XML_DELETIONS)) + pContext = new ScXMLDeletionsContext(GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); + + return pContext; +} + +void ScXMLRejectionContext::EndElement() +{ + pChangeTrackingImportHelper->EndChangeAction(); +} + + + diff --git a/sc/source/filter/xml/XMLTrackedChangesContext.hxx b/sc/source/filter/xml/XMLTrackedChangesContext.hxx new file mode 100644 index 000000000000..299c835f49a9 --- /dev/null +++ b/sc/source/filter/xml/XMLTrackedChangesContext.hxx @@ -0,0 +1,62 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLTRACKEDCHANGESCONTEXT_HXX +#define SC_XMLTRACKEDCHANGESCONTEXT_HXX + +#include "XMLChangeTrackingImportHelper.hxx" +#include "chgtrack.hxx" +#include <xmloff/xmlictxt.hxx> +#include <rtl/ustrbuf.hxx> + +class ScXMLImport; +class ScXMLChangeTrackingImportHelper; +class ScEditEngineTextObj; + +class ScXMLTrackedChangesContext : public SvXMLImportContext +{ + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLTrackedChangesContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper); + virtual ~ScXMLTrackedChangesContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + virtual void EndElement(); +}; + +#endif + diff --git a/sc/source/filter/xml/makefile.mk b/sc/source/filter/xml/makefile.mk new file mode 100644 index 000000000000..7f9f2d529a90 --- /dev/null +++ b/sc/source/filter/xml/makefile.mk @@ -0,0 +1,109 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=sc +TARGET=xml + +ENABLE_EXCEPTIONS=TRUE + +AUTOSEG=true + +PROJECTPCH4DLL=TRUE +PROJECTPCH=filt_pch +PROJECTPCHSOURCE=..\pch\filt_pch + +# --- Settings ----------------------------------------------------- + +.INCLUDE : scpre.mk +.INCLUDE : settings.mk +.INCLUDE : sc.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/sheetdata.obj \ + $(SLO)$/xmlwrap.obj \ + $(SLO)$/xmlimprt.obj \ + $(SLO)$/xmlexprt.obj \ + $(SLO)$/xmlbodyi.obj \ + $(SLO)$/xmltabi.obj \ + $(SLO)$/xmlexternaltabi.obj \ + $(SLO)$/xmlrowi.obj \ + $(SLO)$/xmlcelli.obj \ + $(SLO)$/xmlconti.obj \ + $(SLO)$/xmlcoli.obj \ + $(SLO)$/xmlsubti.obj \ + $(SLO)$/xmlnexpi.obj \ + $(SLO)$/xmldrani.obj \ + $(SLO)$/xmlfilti.obj \ + $(SLO)$/xmlsorti.obj \ + $(SLO)$/xmlstyle.obj \ + $(SLO)$/xmlstyli.obj \ + $(SLO)$/xmldpimp.obj \ + $(SLO)$/xmlannoi.obj \ + $(SLO)$/xmlsceni.obj \ + $(SLO)$/xmlcvali.obj \ + $(SLO)$/XMLTableMasterPageExport.obj \ + $(SLO)$/xmllabri.obj \ + $(SLO)$/XMLTableHeaderFooterContext.obj \ + $(SLO)$/XMLDetectiveContext.obj \ + $(SLO)$/XMLCellRangeSourceContext.obj \ + $(SLO)$/XMLConsolidationContext.obj \ + $(SLO)$/XMLConverter.obj \ + $(SLO)$/XMLExportIterator.obj \ + $(SLO)$/XMLColumnRowGroupExport.obj \ + $(SLO)$/XMLStylesExportHelper.obj \ + $(SLO)$/XMLStylesImportHelper.obj \ + $(SLO)$/XMLExportDataPilot.obj \ + $(SLO)$/XMLExportDatabaseRanges.obj \ + $(SLO)$/XMLTableShapeImportHelper.obj \ + $(SLO)$/XMLTableShapesContext.obj \ + $(SLO)$/XMLExportDDELinks.obj \ + $(SLO)$/XMLDDELinksContext.obj \ + $(SLO)$/XMLCalculationSettingsContext.obj \ + $(SLO)$/XMLTableSourceContext.obj \ + $(SLO)$/XMLTextPContext.obj \ + $(SLO)$/XMLTableShapeResizer.obj \ + $(SLO)$/XMLChangeTrackingExportHelper.obj \ + $(SLO)$/xmlfonte.obj \ + $(SLO)$/XMLChangeTrackingImportHelper.obj \ + $(SLO)$/XMLTrackedChangesContext.obj \ + $(SLO)$/XMLExportSharedData.obj \ + $(SLO)$/XMLEmptyContext.obj \ + $(SLO)$/XMLCodeNameProvider.obj + + +NOOPTFILES= \ + $(SLO)$/xmlcvali.obj + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/sc/source/filter/xml/sheetdata.cxx b/sc/source/filter/xml/sheetdata.cxx new file mode 100644 index 000000000000..947c1370fa4b --- /dev/null +++ b/sc/source/filter/xml/sheetdata.cxx @@ -0,0 +1,283 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +// INCLUDE --------------------------------------------------------------- + +#include <xmloff/families.hxx> +#include <xmloff/xmlaustp.hxx> +#include <xmloff/nmspmap.hxx> +#include <tools/string.hxx> +#include <tools/debug.hxx> + +#include "sheetdata.hxx" + +// ----------------------------------------------------------------------- + +ScSheetSaveData::ScSheetSaveData() : + mnStartTab( -1 ), + mnStartOffset( -1 ), + maPreviousNote( rtl::OUString(), rtl::OUString(), ScAddress(ScAddress::INITIALIZE_INVALID) ), + mbInSupportedSave( false ) +{ +} + +ScSheetSaveData::~ScSheetSaveData() +{ +} + +void ScSheetSaveData::AddCellStyle( const rtl::OUString& rName, const ScAddress& rCellPos ) +{ + maCellStyles.push_back( ScCellStyleEntry( rName, rCellPos ) ); +} + +void ScSheetSaveData::AddColumnStyle( const rtl::OUString& rName, const ScAddress& rCellPos ) +{ + maColumnStyles.push_back( ScCellStyleEntry( rName, rCellPos ) ); +} + +void ScSheetSaveData::AddRowStyle( const rtl::OUString& rName, const ScAddress& rCellPos ) +{ + maRowStyles.push_back( ScCellStyleEntry( rName, rCellPos ) ); +} + +void ScSheetSaveData::AddTableStyle( const rtl::OUString& rName, const ScAddress& rCellPos ) +{ + maTableStyles.push_back( ScCellStyleEntry( rName, rCellPos ) ); +} + +void ScSheetSaveData::HandleNoteStyles( const rtl::OUString& rStyleName, const rtl::OUString& rTextName, const ScAddress& rCellPos ) +{ + // only consecutive duplicates (most common case) are filtered out here, + // the others are found when the styles are created + + if ( rStyleName == maPreviousNote.maStyleName && + rTextName == maPreviousNote.maTextStyle && + rCellPos.Tab() == maPreviousNote.maCellPos.Tab() ) + { + // already stored for the same sheet - ignore + return; + } + + ScNoteStyleEntry aNewEntry( rStyleName, rTextName, rCellPos ); + maPreviousNote = aNewEntry; + maNoteStyles.push_back( aNewEntry ); +} + +void ScSheetSaveData::AddNoteContentStyle( sal_uInt16 nFamily, const rtl::OUString& rName, const ScAddress& rCellPos, const ESelection& rSelection ) +{ + if ( nFamily == XML_STYLE_FAMILY_TEXT_PARAGRAPH ) + maNoteParaStyles.push_back( ScTextStyleEntry( rName, rCellPos, rSelection ) ); + else + maNoteTextStyles.push_back( ScTextStyleEntry( rName, rCellPos, rSelection ) ); +} + +void ScSheetSaveData::AddTextStyle( const rtl::OUString& rName, const ScAddress& rCellPos, const ESelection& rSelection ) +{ + maTextStyles.push_back( ScTextStyleEntry( rName, rCellPos, rSelection ) ); +} + +void ScSheetSaveData::BlockSheet( sal_Int32 nTab ) +{ + if ( nTab >= (sal_Int32)maBlocked.size() ) + maBlocked.resize( nTab + 1, false ); // fill vector with "false" entries + + maBlocked[nTab] = true; +} + +bool ScSheetSaveData::IsSheetBlocked( sal_Int32 nTab ) const +{ + if ( nTab < (sal_Int32)maBlocked.size() ) + return maBlocked[nTab]; + else + return false; +} + +void ScSheetSaveData::AddStreamPos( sal_Int32 nTab, sal_Int32 nStartOffset, sal_Int32 nEndOffset ) +{ + if ( nTab >= (sal_Int32)maStreamEntries.size() ) + maStreamEntries.resize( nTab + 1 ); + + maStreamEntries[nTab] = ScStreamEntry( nStartOffset, nEndOffset ); +} + +void ScSheetSaveData::StartStreamPos( sal_Int32 nTab, sal_Int32 nStartOffset ) +{ + DBG_ASSERT( mnStartTab < 0, "StartStreamPos without EndStreamPos" ); + + mnStartTab = nTab; + mnStartOffset = nStartOffset; +} + +void ScSheetSaveData::EndStreamPos( sal_Int32 nEndOffset ) +{ + if ( mnStartTab >= 0 ) + { + AddStreamPos( mnStartTab, mnStartOffset, nEndOffset ); + mnStartTab = -1; + mnStartOffset = -1; + } +} + +void ScSheetSaveData::GetStreamPos( sal_Int32 nTab, sal_Int32& rStartOffset, sal_Int32& rEndOffset ) const +{ + if ( nTab < (sal_Int32)maStreamEntries.size() ) + { + const ScStreamEntry& rEntry = maStreamEntries[nTab]; + rStartOffset = rEntry.mnStartOffset; + rEndOffset = rEntry.mnEndOffset; + } + else + rStartOffset = rEndOffset = -1; +} + +bool ScSheetSaveData::HasStreamPos( sal_Int32 nTab ) const +{ + sal_Int32 nStartOffset = -1; + sal_Int32 nEndOffset = -1; + GetStreamPos( nTab, nStartOffset, nEndOffset ); + return ( nStartOffset >= 0 && nEndOffset >= 0 ); +} + +void ScSheetSaveData::ResetSaveEntries() +{ + maSaveEntries.clear(); +} + +void ScSheetSaveData::AddSavePos( sal_Int32 nTab, sal_Int32 nStartOffset, sal_Int32 nEndOffset ) +{ + if ( nTab >= (sal_Int32)maSaveEntries.size() ) + maSaveEntries.resize( nTab + 1 ); + + maSaveEntries[nTab] = ScStreamEntry( nStartOffset, nEndOffset ); +} + +void ScSheetSaveData::UseSaveEntries() +{ + maStreamEntries = maSaveEntries; +} + +void ScSheetSaveData::StoreInitialNamespaces( const SvXMLNamespaceMap& rNamespaces ) +{ + // the initial namespaces are just removed from the list of loaded namespaces, + // so only a hash_set of the prefixes is needed. + + const NameSpaceHash& rNameHash = rNamespaces.GetAllEntries(); + NameSpaceHash::const_iterator aIter = rNameHash.begin(), aEnd = rNameHash.end(); + while (aIter != aEnd) + { + maInitialPrefixes.insert( aIter->first ); + ++aIter; + } +} + +void ScSheetSaveData::StoreLoadedNamespaces( const SvXMLNamespaceMap& rNamespaces ) +{ + // store the loaded namespaces, so the prefixes in copied stream fragments remain valid + + const NameSpaceHash& rNameHash = rNamespaces.GetAllEntries(); + NameSpaceHash::const_iterator aIter = rNameHash.begin(), aEnd = rNameHash.end(); + while (aIter != aEnd) + { + // ignore the initial namespaces + if ( maInitialPrefixes.find( aIter->first ) == maInitialPrefixes.end() ) + { + const NameSpaceEntry& rEntry = aIter->second.getBody(); + maLoadedNamespaces.push_back( ScLoadedNamespaceEntry( rEntry.sPrefix, rEntry.sName, rEntry.nKey ) ); + } + ++aIter; + } +} + +bool lcl_NameInHash( const NameSpaceHash& rNameHash, const rtl::OUString& rName ) +{ + NameSpaceHash::const_iterator aIter = rNameHash.begin(), aEnd = rNameHash.end(); + while (aIter != aEnd) + { + if ( aIter->second->sName == rName ) + return true; + + ++aIter; + } + return false; // not found +} + +bool ScSheetSaveData::AddLoadedNamespaces( SvXMLNamespaceMap& rNamespaces ) const +{ + // Add the loaded namespaces to the name space map. + + // first loop: only look for conflicts + // (if the loaded namespaces were added first, this might not be necessary) + const NameSpaceHash& rNameHash = rNamespaces.GetAllEntries(); + std::vector<ScLoadedNamespaceEntry>::const_iterator aIter = maLoadedNamespaces.begin(); + std::vector<ScLoadedNamespaceEntry>::const_iterator aEnd = maLoadedNamespaces.end(); + while (aIter != aEnd) + { + NameSpaceHash::const_iterator aHashIter = rNameHash.find( aIter->maPrefix ); + if ( aHashIter == rNameHash.end() ) + { + if ( lcl_NameInHash( rNameHash, aIter->maName ) ) + { + // a second prefix for the same name would confuse SvXMLNamespaceMap lookup, + // so this is also considered a conflict + return false; + } + } + else if ( aHashIter->second->sName != aIter->maName ) + { + // same prefix, but different name: loaded namespaces can't be used + return false; + } + ++aIter; + } + + // only if there were no conflicts, add the entries that aren't in the map already + // (the key is needed if the same namespace is added later within an element) + aIter = maLoadedNamespaces.begin(); + while (aIter != aEnd) + { + NameSpaceHash::const_iterator aHashIter = rNameHash.find( aIter->maPrefix ); + if ( aHashIter == rNameHash.end() ) + rNamespaces.Add( aIter->maPrefix, aIter->maName, aIter->mnKey ); + ++aIter; + } + + return true; // success +} + +bool ScSheetSaveData::IsInSupportedSave() const +{ + return mbInSupportedSave; +} + +void ScSheetSaveData::SetInSupportedSave( bool bSet ) +{ + mbInSupportedSave = bSet; +} + diff --git a/sc/source/filter/xml/xmlannoi.cxx b/sc/source/filter/xml/xmlannoi.cxx new file mode 100644 index 000000000000..a6c76b830517 --- /dev/null +++ b/sc/source/filter/xml/xmlannoi.cxx @@ -0,0 +1,220 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +// INCLUDE --------------------------------------------------------------- + +#include "xmlannoi.hxx" +#include "xmlimprt.hxx" +#include "xmlconti.hxx" +#include "XMLTableShapeImportHelper.hxx" + +#include <xmloff/xmltkmap.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/xmltoken.hxx> + +using namespace com::sun::star; +using namespace xmloff::token; + +//------------------------------------------------------------------ + +ScXMLAnnotationData::ScXMLAnnotationData() : + mbUseShapePos( false ), + mbShown( false ) +{ +} + +ScXMLAnnotationData::~ScXMLAnnotationData() +{ +} + +//------------------------------------------------------------------ + +ScXMLAnnotationContext::ScXMLAnnotationContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList, + ScXMLAnnotationData& rAnnotationData, + ScXMLTableRowCellContext* pTempCellContext) : + SvXMLImportContext( rImport, nPrfx, rLName ), + mrAnnotationData( rAnnotationData ), + nParagraphCount(0), + bHasTextP(sal_False), + pCellContext(pTempCellContext), + pShapeContext(NULL) +{ + uno::Reference<drawing::XShapes> xLocalShapes (GetScImport().GetTables().GetCurrentXShapes()); + if (xLocalShapes.is()) + { + XMLTableShapeImportHelper* pTableShapeImport = (XMLTableShapeImportHelper*)GetScImport().GetShapeImport().get(); + pTableShapeImport->SetAnnotation(this); + pShapeContext = GetScImport().GetShapeImport()->CreateGroupChildContext( + GetScImport(), nPrfx, rLName, xAttrList, xLocalShapes, sal_True); + } + + pCellContext = pTempCellContext; + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetTableAnnotationAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_TABLE_ANNOTATION_ATTR_AUTHOR: + { + maAuthorBuffer = sValue; + } + break; + case XML_TOK_TABLE_ANNOTATION_ATTR_CREATE_DATE: + { + maCreateDateBuffer = sValue; + } + break; + case XML_TOK_TABLE_ANNOTATION_ATTR_CREATE_DATE_STRING: + { + maCreateDateStringBuffer = sValue; + } + break; + case XML_TOK_TABLE_ANNOTATION_ATTR_DISPLAY: + { + mrAnnotationData.mbShown = IsXMLToken(sValue, XML_TRUE); + } + break; + case XML_TOK_TABLE_ANNOTATION_ATTR_X: + { + mrAnnotationData.mbUseShapePos = true; + } + break; + case XML_TOK_TABLE_ANNOTATION_ATTR_Y: + { + mrAnnotationData.mbUseShapePos = true; + } + break; + } + } +} + +ScXMLAnnotationContext::~ScXMLAnnotationContext() +{ +} + +void ScXMLAnnotationContext::StartElement(const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList) +{ + if (pShapeContext) + pShapeContext->StartElement(xAttrList); +} + +SvXMLImportContext *ScXMLAnnotationContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + if( XML_NAMESPACE_DC == nPrefix ) + { + if( IsXMLToken( rLName, XML_CREATOR ) ) + pContext = new ScXMLContentContext(GetScImport(), nPrefix, + rLName, xAttrList, maAuthorBuffer); + else if( IsXMLToken( rLName, XML_DATE ) ) + pContext = new ScXMLContentContext(GetScImport(), nPrefix, + rLName, xAttrList, maCreateDateBuffer); + } + else if( XML_NAMESPACE_META == nPrefix ) + { + if( IsXMLToken( rLName, XML_DATE_STRING ) ) + pContext = new ScXMLContentContext(GetScImport(), nPrefix, + rLName, xAttrList, maCreateDateStringBuffer); + } +/* else if ((nPrefix == XML_NAMESPACE_TEXT) && IsXMLToken(rLName, XML_P) ) + { + if (!bHasTextP) + { + bHasTextP = sal_True; + maTextBuffer.setLength(0); + } + if(nParagraphCount) + maTextBuffer.append(static_cast<sal_Unicode>('\n')); + ++nParagraphCount; + pContext = new ScXMLContentContext( GetScImport(), nPrefix, rLName, xAttrList, maTextBuffer); + }*/ + + if( !pContext && pShapeContext ) + pContext = pShapeContext->CreateChildContext(nPrefix, rLName, xAttrList); + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLAnnotationContext::Characters( const ::rtl::OUString& rChars ) +{ + if (!bHasTextP) + maTextBuffer.append(rChars); +} + +void ScXMLAnnotationContext::EndElement() +{ + if (pShapeContext) + { + pShapeContext->EndElement(); + delete pShapeContext; + } + + mrAnnotationData.maAuthor = maAuthorBuffer.makeStringAndClear(); + mrAnnotationData.maCreateDate = maCreateDateBuffer.makeStringAndClear(); + if (!mrAnnotationData.maCreateDate.getLength()) + mrAnnotationData.maCreateDate = maCreateDateStringBuffer.makeStringAndClear(); + mrAnnotationData.maSimpleText = maTextBuffer.makeStringAndClear(); + + XMLTableShapeImportHelper* pTableShapeImport = (XMLTableShapeImportHelper*)GetScImport().GetShapeImport().get(); + pTableShapeImport->SetAnnotation(NULL); +} + +void ScXMLAnnotationContext::SetShape( const uno::Reference< drawing::XShape >& rxShape, const uno::Reference< drawing::XShapes >& rxShapes, + const rtl::OUString& rStyleName, const rtl::OUString& rTextStyle ) +{ + mrAnnotationData.mxShape = rxShape; + mrAnnotationData.mxShapes = rxShapes; + mrAnnotationData.maStyleName = rStyleName; + mrAnnotationData.maTextStyle = rTextStyle; +} + +void ScXMLAnnotationContext::AddContentStyle( sal_uInt16 nFamily, const rtl::OUString& rName, const ESelection& rSelection ) +{ + mrAnnotationData.maContentStyles.push_back( ScXMLAnnotationStyleEntry( nFamily, rName, rSelection ) ); +} + diff --git a/sc/source/filter/xml/xmlannoi.hxx b/sc/source/filter/xml/xmlannoi.hxx new file mode 100644 index 000000000000..2c39118dca1f --- /dev/null +++ b/sc/source/filter/xml/xmlannoi.hxx @@ -0,0 +1,122 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef SC_XMLANNOI_HXX +#define SC_XMLANNOI_HXX + +#include <memory> +#include <xmloff/xmlictxt.hxx> +#include <xmloff/xmlimp.hxx> +#include <rtl/ustrbuf.hxx> +#include <editeng/editdata.hxx> +#include <com/sun/star/drawing/XShape.hpp> +#include <com/sun/star/drawing/XShapes.hpp> + +class ScXMLImport; +class ScXMLTableRowCellContext; + +struct ScXMLAnnotationStyleEntry +{ + sal_uInt16 mnFamily; + rtl::OUString maName; + ESelection maSelection; + + ScXMLAnnotationStyleEntry( sal_uInt16 nFam, const rtl::OUString& rNam, const ESelection& rSel ) : + mnFamily( nFam ), + maName( rNam ), + maSelection( rSel ) + { + } +}; + +struct ScXMLAnnotationData +{ + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > + mxShape; + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes > + mxShapes; + ::rtl::OUString maAuthor; + ::rtl::OUString maCreateDate; + ::rtl::OUString maSimpleText; + ::rtl::OUString maStyleName; + ::rtl::OUString maTextStyle; + bool mbUseShapePos; + bool mbShown; + std::vector<ScXMLAnnotationStyleEntry> maContentStyles; + + explicit ScXMLAnnotationData(); + ~ScXMLAnnotationData(); +}; + +class ScXMLAnnotationContext : public SvXMLImportContext +{ +public: + + ScXMLAnnotationContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLAnnotationData& rAnnotationData, + ScXMLTableRowCellContext* pCellContext); + + virtual ~ScXMLAnnotationContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void StartElement(const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList); + + virtual void Characters( const ::rtl::OUString& rChars ); + + virtual void EndElement(); + + void SetShape( + const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape, + const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes, + const ::rtl::OUString& rStyleName, const ::rtl::OUString& rTextStyle ); + + void AddContentStyle( sal_uInt16 nFamily, const rtl::OUString& rName, const ESelection& rSelection ); + +private: + ScXMLAnnotationData& mrAnnotationData; + rtl::OUStringBuffer maTextBuffer; + rtl::OUStringBuffer maAuthorBuffer; + rtl::OUStringBuffer maCreateDateBuffer; + rtl::OUStringBuffer maCreateDateStringBuffer; + sal_Int32 nParagraphCount; + sal_Bool bHasTextP; + ScXMLTableRowCellContext* pCellContext; + SvXMLImportContext* pShapeContext; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } +}; + + +#endif + diff --git a/sc/source/filter/xml/xmlbodyi.cxx b/sc/source/filter/xml/xmlbodyi.cxx new file mode 100644 index 000000000000..f80540bafa55 --- /dev/null +++ b/sc/source/filter/xml/xmlbodyi.cxx @@ -0,0 +1,338 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + +// INCLUDE --------------------------------------------------------------- +#include <cstdio> + +#include "document.hxx" +#include "docuno.hxx" +#include "sheetdata.hxx" + +#include "xmlbodyi.hxx" +#include "xmltabi.hxx" +#include "xmlnexpi.hxx" +#include "xmldrani.hxx" +#include "xmlimprt.hxx" +#include "xmldpimp.hxx" +#include "xmlcvali.hxx" +#include "xmlstyli.hxx" +#include "xmllabri.hxx" +#include "XMLConsolidationContext.hxx" +#include "XMLDDELinksContext.hxx" +#include "XMLCalculationSettingsContext.hxx" +#include "XMLTrackedChangesContext.hxx" +#include "XMLEmptyContext.hxx" +#include "scerrors.hxx" +#include "tabprotection.hxx" + +#include <xmloff/xmltkmap.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmluconv.hxx> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include <sal/types.h> +#include <tools/debug.hxx> + +#include <memory> + +using rtl::OUString; + +using namespace com::sun::star; +using namespace xmloff::token; + +//------------------------------------------------------------------ + +ScXMLBodyContext::ScXMLBodyContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + sPassword(), + bProtected(sal_False), + bHadCalculationSettings(sal_False), + pChangeTrackingImportHelper(NULL) +{ + ScDocument* pDoc = GetScImport().GetDocument(); + if (pDoc) + { + // ODF 1.1 and earlier => GRAM_PODF; ODF 1.2 and later => GRAM_ODFF; + // no version => earlier than 1.2 => GRAM_PODF. + formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_ODFF; + OUString aVer( rImport.GetODFVersion()); + sal_Int32 nLen = aVer.getLength(); +#if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "\n ScXMLBodyContext ODFVersion: nLen: %d, str: %s\n", + (int)nLen, OUStringToOString( aVer, RTL_TEXTENCODING_UTF8).getStr()); +#endif + if (!nLen) + eGrammar = formula::FormulaGrammar::GRAM_PODF; + else + { + // In case there was a micro version, e.g. "1.2.3", this would + // still yield major.minor, but pParsedEnd (5th parameter, not + // passed here) would point before string end upon return. + double fVer = ::rtl::math::stringToDouble( aVer, '.', 0, NULL, NULL); + if (fVer < 1.2) + eGrammar = formula::FormulaGrammar::GRAM_PODF; + } + pDoc->SetStorageGrammar( eGrammar); + } + + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(aLocalName, XML_STRUCTURE_PROTECTED)) + bProtected = IsXMLToken(sValue, XML_TRUE); + else if (IsXMLToken(aLocalName, XML_PROTECTION_KEY)) + sPassword = sValue; + } + } +} + +ScXMLBodyContext::~ScXMLBodyContext() +{ +} + +SvXMLImportContext *ScXMLBodyContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData(); + if ( pSheetData && pSheetData->HasStartPos() ) + { + // stream part to copy ends before the next child element + sal_Int32 nEndOffset = GetScImport().GetByteOffset(); + pSheetData->EndStreamPos( nEndOffset ); + } + + SvXMLImportContext *pContext = 0; + + const SvXMLTokenMap& rTokenMap = GetScImport().GetBodyElemTokenMap(); +// sal_Bool bOrdered = sal_False; +// sal_Bool bHeading = sal_False; + switch( rTokenMap.Get( nPrefix, rLocalName ) ) + { +// case XML_TOK_TEXT_H: +// bHeading = sal_True; +// case XML_TOK_TEXT_P: +// pContext = new SwXMLParaContext( GetSwImport(),nPrefix, rLocalName, +// xAttrList, bHeading ); +// break; +// case XML_TOK_TEXT_ORDERED_LIST: +// bOrdered = sal_True; +// case XML_TOK_TEXT_UNORDERED_LIST: +// pContext = new SwXMLListBlockContext( GetSwImport(),nPrefix, rLocalName, +// xAttrList, bOrdered ); +// break; + case XML_TOK_BODY_TRACKED_CHANGES : + { + pChangeTrackingImportHelper = GetScImport().GetChangeTrackingImportHelper(); + if (pChangeTrackingImportHelper) + pContext = new ScXMLTrackedChangesContext( GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper); + } + break; + case XML_TOK_BODY_CALCULATION_SETTINGS : + pContext = new ScXMLCalculationSettingsContext( GetScImport(), nPrefix, rLocalName, xAttrList ); + bHadCalculationSettings = sal_True; + break; + case XML_TOK_BODY_CONTENT_VALIDATIONS : + pContext = new ScXMLContentValidationsContext( GetScImport(), nPrefix, rLocalName, xAttrList ); + break; + case XML_TOK_BODY_LABEL_RANGES: + pContext = new ScXMLLabelRangesContext( GetScImport(), nPrefix, rLocalName, xAttrList ); + break; + case XML_TOK_BODY_TABLE: + { + if (GetScImport().GetTables().GetCurrentSheet() >= MAXTAB) + { + GetScImport().SetRangeOverflowType(SCWARN_IMPORT_SHEET_OVERFLOW); + pContext = new ScXMLEmptyContext(GetScImport(), nPrefix, rLocalName); + } + else + { + pContext = new ScXMLTableContext( GetScImport(),nPrefix, rLocalName, + xAttrList ); + } + } + break; + case XML_TOK_BODY_NAMED_EXPRESSIONS: + pContext = new ScXMLNamedExpressionsContext ( GetScImport(), nPrefix, rLocalName, + xAttrList ); + break; + case XML_TOK_BODY_DATABASE_RANGES: + pContext = new ScXMLDatabaseRangesContext ( GetScImport(), nPrefix, rLocalName, + xAttrList ); + break; + case XML_TOK_BODY_DATABASE_RANGE: + pContext = new ScXMLDatabaseRangeContext ( GetScImport(), nPrefix, rLocalName, + xAttrList ); + break; + case XML_TOK_BODY_DATA_PILOT_TABLES: + pContext = new ScXMLDataPilotTablesContext ( GetScImport(), nPrefix, rLocalName, + xAttrList ); + break; + case XML_TOK_BODY_CONSOLIDATION: + pContext = new ScXMLConsolidationContext ( GetScImport(), nPrefix, rLocalName, + xAttrList ); + break; + case XML_TOK_BODY_DDE_LINKS: + pContext = new ScXMLDDELinksContext ( GetScImport(), nPrefix, rLocalName, + xAttrList ); + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); + + return pContext; +} + +void ScXMLBodyContext::Characters( const OUString& ) +{ + ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData(); + if ( pSheetData && pSheetData->HasStartPos() ) + { + // stream part to copy ends before any content (whitespace) within the spreadsheet element + sal_Int32 nEndOffset = GetScImport().GetByteOffset(); + pSheetData->EndStreamPos( nEndOffset ); + } + // otherwise ignore +} + +void ScXMLBodyContext::EndElement() +{ + ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData(); + if ( pSheetData && pSheetData->HasStartPos() ) + { + // stream part to copy ends before the closing tag of spreadsheet element + sal_Int32 nEndOffset = GetScImport().GetByteOffset(); + pSheetData->EndStreamPos( nEndOffset ); + } + + if ( pSheetData ) + { + // store the loaded namespaces (for the office:spreadsheet element), + // so the prefixes in copied stream fragments remain valid + const SvXMLNamespaceMap& rNamespaces = GetImport().GetNamespaceMap(); + pSheetData->StoreLoadedNamespaces( rNamespaces ); + } + + if (!bHadCalculationSettings) + { + // #111055#; set calculation settings defaults if there is no calculation settings element + SvXMLImportContext *pContext = new ScXMLCalculationSettingsContext( GetScImport(), XML_NAMESPACE_TABLE, GetXMLToken(XML_CALCULATION_SETTINGS), NULL ); + pContext->EndElement(); + } + GetScImport().LockSolarMutex(); + ScMyImpDetectiveOpArray* pDetOpArray = GetScImport().GetDetectiveOpArray(); + ScDocument* pDoc = GetScImport().GetDocument(); + ScMyImpDetectiveOp aDetOp; + + if (pDoc && GetScImport().GetModel().is()) + { + if (pDetOpArray) + { + pDetOpArray->Sort(); + while( pDetOpArray->GetFirstOp( aDetOp ) ) + { + ScDetOpData aOpData( aDetOp.aPosition, aDetOp.eOpType ); + pDoc->AddDetectiveOperation( aOpData ); + } + } + + if (pChangeTrackingImportHelper) + pChangeTrackingImportHelper->CreateChangeTrack(GetScImport().GetDocument()); + +#if 0 + // #i57869# table styles are applied before the contents now + + std::vector<rtl::OUString> aTableStyleNames(GetScImport().GetTableStyle()); + uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetScImport().GetModel(), uno::UNO_QUERY ); + if ( xSpreadDoc.is() && !aTableStyleNames.empty()) + { + uno::Reference <container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY ); + if ( xIndex.is() ) + { + sal_Int32 nTableCount = xIndex->getCount(); + sal_Int32 nSize(aTableStyleNames.size()); + DBG_ASSERT(nTableCount == nSize, "every table should have a style name"); + for(sal_uInt32 i = 0; i < nTableCount; i++) + { + if (i < nSize) + { + uno::Reference <beans::XPropertySet> xProperties(xIndex->getByIndex(i), uno::UNO_QUERY); + if (xProperties.is()) + { + rtl::OUString sTableStyleName(aTableStyleNames[i]); + XMLTableStylesContext *pStyles = (XMLTableStylesContext *)GetScImport().GetAutoStyles(); + if ( pStyles && sTableStyleName.getLength() ) + { + XMLTableStyleContext* pStyle = (XMLTableStyleContext *)pStyles->FindStyleChildContext( + XML_STYLE_FAMILY_TABLE_TABLE, sTableStyleName, sal_True); + if (pStyle) + pStyle->FillPropertySet(xProperties); + } + } + } + } + } + } +#endif + + // #i37959# handle document protection after the sheet settings + if (bProtected) + { + ::std::auto_ptr<ScDocProtection> pProtection(new ScDocProtection); + pProtection->setProtected(true); + + uno::Sequence<sal_Int8> aPass; + if (sPassword.getLength()) + { + SvXMLUnitConverter::decodeBase64(aPass, sPassword); + pProtection->setPasswordHash(aPass, PASSHASH_OOO); + } + + pDoc->SetDocProtection(pProtection.get()); + } + } + GetScImport().UnlockSolarMutex(); +} + diff --git a/sc/source/filter/xml/xmlbodyi.hxx b/sc/source/filter/xml/xmlbodyi.hxx new file mode 100644 index 000000000000..3a5c401c254f --- /dev/null +++ b/sc/source/filter/xml/xmlbodyi.hxx @@ -0,0 +1,61 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLBODYI_HXX +#define SC_XMLBODYI_HXX + +#include <xmloff/xmlictxt.hxx> +#include <xmloff/xmlimp.hxx> + +class ScXMLImport; +class ScXMLChangeTrackingImportHelper; + +class ScXMLBodyContext : public SvXMLImportContext +{ + rtl::OUString sPassword; + sal_Bool bProtected; + sal_Bool bHadCalculationSettings; + + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper; + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLBodyContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList ); + virtual ~ScXMLBodyContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + virtual void EndElement(); + virtual void Characters( const ::rtl::OUString& rChars ); +}; + +#endif + diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx new file mode 100644 index 000000000000..6028d70bb56a --- /dev/null +++ b/sc/source/filter/xml/xmlcelli.cxx @@ -0,0 +1,1127 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +// INCLUDE --------------------------------------------------------------- + +#include "xmlcelli.hxx" +#include "xmlimprt.hxx" +#include "xmltabi.hxx" +#include "xmlstyli.hxx" +#include "xmlannoi.hxx" +#include "global.hxx" +#include "document.hxx" +#include "cellsuno.hxx" +#include "docuno.hxx" +#include "unonames.hxx" +#include "postit.hxx" +#include "sheetdata.hxx" + +#include "XMLTableShapeImportHelper.hxx" +#include "XMLTextPContext.hxx" +#include "XMLStylesImportHelper.hxx" + +#include "arealink.hxx" +#include <sfx2/linkmgr.hxx> +#include "convuno.hxx" +#include "XMLConverter.hxx" +#include "scerrors.hxx" +#include "editutil.hxx" +#include "cell.hxx" + +#include <xmloff/xmltkmap.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmluconv.hxx> +#include <xmloff/families.hxx> +#include <xmloff/numehelp.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <svl/zforlist.hxx> +#include <svx/svdocapt.hxx> +#include <editeng/outlobj.hxx> +#include <editeng/editobj.hxx> +#include <svx/unoapi.hxx> +#include <svl/languageoptions.hxx> + +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/text/XText.hpp> +#include <com/sun/star/sheet/XSpreadsheets.hpp> +#include <com/sun/star/sheet/XSpreadsheet.hpp> +#include <com/sun/star/sheet/XCellRangeAddressable.hpp> + +#include <com/sun/star/util/XMergeable.hpp> +#include <com/sun/star/sheet/XSheetCondition.hpp> +#include <com/sun/star/table/XCellRange.hpp> +#include <com/sun/star/table/CellAddress.hpp> +#include <com/sun/star/util/NumberFormat.hpp> +#include <com/sun/star/util/XNumberFormatsSupplier.hpp> +#include <com/sun/star/util/XNumberFormatTypes.hpp> +#include <com/sun/star/util/Date.hpp> +#include <com/sun/star/lang/Locale.hpp> +#include <com/sun/star/text/ControlCharacter.hpp> + +#include <rtl/ustrbuf.hxx> +#include <tools/date.hxx> +#include <i18npool/lang.h> +#include <comphelper/extract.hxx> + +#define SC_CURRENCYSYMBOL "CurrencySymbol" + +using namespace com::sun::star; +using namespace xmloff::token; + +//------------------------------------------------------------------ + +ScXMLTableRowCellContext::ScXMLTableRowCellContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + const sal_Bool bTempIsCovered, + const sal_Int32 nTempRepeatedRows ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pContentValidationName(NULL), + pDetectiveObjVec(NULL), + pCellRangeSource(NULL), + fValue(0.0), + nMergedRows(1), + nMergedCols(1), + nRepeatedRows(nTempRepeatedRows), + nCellsRepeated(1), + rXMLImport((ScXMLImport&)rImport), + eGrammar( formula::FormulaGrammar::GRAM_STORAGE_DEFAULT), + nCellType(util::NumberFormat::TEXT), + bIsMerged(sal_False), + bIsMatrix(sal_False), + bHasSubTable(sal_False), + bIsCovered(bTempIsCovered), + bIsEmpty(sal_True), + bHasTextImport(sal_False), + bIsFirstTextImport(sal_False), + bSolarMutexLocked(sal_False), + bFormulaTextResult(sal_False) +{ + rXMLImport.SetRemoveLastChar(sal_False); + rXMLImport.GetTables().AddColumn(bTempIsCovered); + const sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + rtl::OUString aLocalName; + rtl::OUString* pStyleName = NULL; + rtl::OUString* pCurrencySymbol = NULL; + const SvXMLTokenMap& rTokenMap = rImport.GetTableRowCellAttrTokenMap(); + for (sal_Int16 i = 0; i < nAttrCount; ++i) + { + sal_uInt16 nAttrPrefix = rImport.GetNamespaceMap().GetKeyByAttrName( + xAttrList->getNameByIndex(i), &aLocalName); + + const rtl::OUString& sValue = xAttrList->getValueByIndex(i); + sal_uInt16 nToken = rTokenMap.Get(nAttrPrefix, aLocalName); + switch (nToken) + { + case XML_TOK_TABLE_ROW_CELL_ATTR_STYLE_NAME: + pStyleName = new rtl::OUString(sValue); + break; + case XML_TOK_TABLE_ROW_CELL_ATTR_CONTENT_VALIDATION_NAME: + DBG_ASSERT(!pContentValidationName, "here should be only one Validation Name"); + pContentValidationName = new rtl::OUString(sValue); + break; + case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_ROWS: + bIsMerged = sal_True; + nMergedRows = sValue.toInt32(); + break; + case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_COLS: + bIsMerged = sal_True; + nMergedCols = sValue.toInt32(); + break; + case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_COLS: + bIsMatrix = sal_True; + nMatrixCols = sValue.toInt32(); + break; + case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_ROWS: + bIsMatrix = sal_True; + nMatrixRows = sValue.toInt32(); + break; + case XML_TOK_TABLE_ROW_CELL_ATTR_REPEATED: + nCellsRepeated = std::max( sValue.toInt32(), (sal_Int32) 1 ); + break; + case XML_TOK_TABLE_ROW_CELL_ATTR_VALUE_TYPE: + nCellType = GetScImport().GetCellType(sValue); + bIsEmpty = sal_False; + break; + case XML_TOK_TABLE_ROW_CELL_ATTR_VALUE: + { + if (sValue.getLength()) + { + rXMLImport.GetMM100UnitConverter().convertDouble(fValue, sValue); + bIsEmpty = sal_False; + } + } + break; + case XML_TOK_TABLE_ROW_CELL_ATTR_DATE_VALUE: + { + if (sValue.getLength() && rXMLImport.SetNullDateOnUnitConverter()) + { + rXMLImport.GetMM100UnitConverter().convertDateTime(fValue, sValue); + bIsEmpty = sal_False; + } + } + break; + case XML_TOK_TABLE_ROW_CELL_ATTR_TIME_VALUE: + { + if (sValue.getLength()) + { + rXMLImport.GetMM100UnitConverter().convertTime(fValue, sValue); + bIsEmpty = sal_False; + } + } + break; + case XML_TOK_TABLE_ROW_CELL_ATTR_STRING_VALUE: + { + if (sValue.getLength()) + { + DBG_ASSERT(!pOUTextValue, "here should be only one string value"); + pOUTextValue.reset(sValue); + bIsEmpty = sal_False; + } + } + break; + case XML_TOK_TABLE_ROW_CELL_ATTR_BOOLEAN_VALUE: + { + if (sValue.getLength()) + { + if ( IsXMLToken(sValue, XML_TRUE) ) + fValue = 1.0; + else if ( IsXMLToken(sValue, XML_FALSE) ) + fValue = 0.0; + else + rXMLImport.GetMM100UnitConverter().convertDouble(fValue, sValue); + bIsEmpty = sal_False; + } + } + break; + case XML_TOK_TABLE_ROW_CELL_ATTR_FORMULA: + { + if (sValue.getLength()) + { + DBG_ASSERT(!pOUFormula, "here should be only one formula"); + rtl::OUString aFormula, aFormulaNmsp; + rXMLImport.ExtractFormulaNamespaceGrammar( aFormula, aFormulaNmsp, eGrammar, sValue ); + pOUFormula.reset( FormulaWithNamespace( aFormula, aFormulaNmsp ) ); + } + } + break; + case XML_TOK_TABLE_ROW_CELL_ATTR_CURRENCY: + pCurrencySymbol = new rtl::OUString(sValue); + break; + default: + ; + } + } + if (pOUFormula) + { + if (nCellType == util::NumberFormat::TEXT) + bFormulaTextResult = sal_True; + nCellType = util::NumberFormat::UNDEFINED; + } + rXMLImport.GetStylesImportHelper()->SetAttributes(pStyleName, pCurrencySymbol, nCellType); +} + +ScXMLTableRowCellContext::~ScXMLTableRowCellContext() +{ + if (pContentValidationName) + delete pContentValidationName; + if (pDetectiveObjVec) + delete pDetectiveObjVec; + if (pCellRangeSource) + delete pCellRangeSource; +} + +void ScXMLTableRowCellContext::LockSolarMutex() +{ + if (!bSolarMutexLocked) + { + GetScImport().LockSolarMutex(); + bSolarMutexLocked = sal_True; + } +} + +void ScXMLTableRowCellContext::UnlockSolarMutex() +{ + if (bSolarMutexLocked) + { + GetScImport().UnlockSolarMutex(); + bSolarMutexLocked = sal_False; + } +} + +void ScXMLTableRowCellContext::SetCursorOnTextImport(const rtl::OUString& rOUTempText) +{ + com::sun::star::table::CellAddress aCellPos = rXMLImport.GetTables().GetRealCellPos(); + if (CellExists(aCellPos)) + { + uno::Reference<table::XCellRange> xCellRange(rXMLImport.GetTables().GetCurrentXCellRange()); + if (xCellRange.is()) + { + xBaseCell.set(xCellRange->getCellByPosition(aCellPos.Column, aCellPos.Row)); + if (xBaseCell.is()) + { + xLockable.set(xBaseCell, uno::UNO_QUERY); + if (xLockable.is()) + xLockable->addActionLock(); + uno::Reference<text::XText> xText(xBaseCell, uno::UNO_QUERY); + if (xText.is()) + { + uno::Reference<text::XTextCursor> xTextCursor(xText->createTextCursor()); + if (xTextCursor.is()) + { + xTextCursor->setString(rOUTempText); + xTextCursor->gotoEnd(sal_False); + rXMLImport.GetTextImport()->SetCursor(xTextCursor); + } + } + } + } + } + else + { + DBG_ERRORFILE("this method should only be called for a existing cell"); + } +} + +SvXMLImportContext *ScXMLTableRowCellContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + const SvXMLTokenMap& rTokenMap = rXMLImport.GetTableRowCellElemTokenMap(); + sal_Bool bTextP(sal_False); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_TABLE_ROW_CELL_P: + { + bIsEmpty = sal_False; + bTextP = sal_True; + com::sun::star::table::CellAddress aCellPos = rXMLImport.GetTables().GetRealCellPos(); + if (((nCellType == util::NumberFormat::TEXT) || bFormulaTextResult) && + !rXMLImport.GetTables().IsPartOfMatrix(aCellPos.Column, aCellPos.Row)) + { + if (!bHasTextImport) + { + bIsFirstTextImport = sal_True; + bHasTextImport = sal_True; + pContext = new ScXMLTextPContext(rXMLImport, nPrefix, rLName, xAttrList, this); + } + else + { + // com::sun::star::table::CellAddress aCellPos = rXMLImport.GetTables().GetRealCellPos(); + if (CellExists(aCellPos)) + { + if (bIsFirstTextImport && !rXMLImport.GetRemoveLastChar()) + { + if (pOUTextContent) + { + SetCursorOnTextImport(*pOUTextContent); + pOUTextContent.reset(); + } + else + SetCursorOnTextImport(rtl::OUString()); + rXMLImport.SetRemoveLastChar(sal_True); + uno::Reference < text::XTextCursor > xTextCursor(rXMLImport.GetTextImport()->GetCursor()); + if (xTextCursor.is()) + { + uno::Reference < text::XText > xText (xTextCursor->getText()); + uno::Reference < text::XTextRange > xTextRange (xTextCursor, uno::UNO_QUERY); + if (xText.is() && xTextRange.is()) + xText->insertControlCharacter(xTextRange, text::ControlCharacter::PARAGRAPH_BREAK, sal_False); + } + } + pContext = rXMLImport.GetTextImport()->CreateTextChildContext( + rXMLImport, nPrefix, rLName, xAttrList); + bIsFirstTextImport = sal_False; + } + } + } + } + break; + case XML_TOK_TABLE_ROW_CELL_TABLE: + { + const sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + rtl::OUString aLocalName; + for( sal_Int16 i=0; i < nAttrCount; i++ ) + { + sal_uInt16 nAttrPrefix = rXMLImport.GetNamespaceMap().GetKeyByAttrName( + xAttrList->getNameByIndex( i ), &aLocalName ); + if ( nAttrPrefix == XML_NAMESPACE_TABLE + && IsXMLToken(aLocalName, XML_IS_SUB_TABLE)) + { + bHasSubTable = IsXMLToken(xAttrList->getValueByIndex( i ), XML_TRUE); + } + } + DBG_ASSERT(bHasSubTable, "it should be a subtable"); + pContext = new ScXMLTableContext( rXMLImport , nPrefix, + rLName, xAttrList, + sal_True, nMergedCols); + nMergedCols = 1; + bIsMerged = sal_False; + } + break; + case XML_TOK_TABLE_ROW_CELL_ANNOTATION: + { + bIsEmpty = sal_False; + DBG_ASSERT( !mxAnnotationData.get(), "ScXMLTableRowCellContext::CreateChildContext - multiple annotations in one cell" ); + mxAnnotationData.reset( new ScXMLAnnotationData ); + pContext = new ScXMLAnnotationContext( rXMLImport, nPrefix, rLName, + xAttrList, *mxAnnotationData, this); + } + break; + case XML_TOK_TABLE_ROW_CELL_DETECTIVE: + { + bIsEmpty = sal_False; + if (!pDetectiveObjVec) + pDetectiveObjVec = new ScMyImpDetectiveObjVec(); + pContext = new ScXMLDetectiveContext( + rXMLImport, nPrefix, rLName, pDetectiveObjVec ); + } + break; + case XML_TOK_TABLE_ROW_CELL_CELL_RANGE_SOURCE: + { + bIsEmpty = sal_False; + if (!pCellRangeSource) + pCellRangeSource = new ScMyImpCellRangeSource(); + pContext = new ScXMLCellRangeSourceContext( + rXMLImport, nPrefix, rLName, xAttrList, pCellRangeSource ); + } + break; + } + + if (!pContext && !bTextP) + { + com::sun::star::table::CellAddress aCellPos = rXMLImport.GetTables().GetRealCellPos(); + uno::Reference<drawing::XShapes> xShapes (rXMLImport.GetTables().GetCurrentXShapes()); + if (xShapes.is()) + { + if (aCellPos.Column > MAXCOL) + aCellPos.Column = MAXCOL; + if (aCellPos.Row > MAXROW) + aCellPos.Row = MAXROW; + XMLTableShapeImportHelper* pTableShapeImport = (XMLTableShapeImportHelper*)rXMLImport.GetShapeImport().get(); + pTableShapeImport->SetOnTable(sal_False); + pTableShapeImport->SetCell(aCellPos); + pContext = rXMLImport.GetShapeImport()->CreateGroupChildContext( + rXMLImport, nPrefix, rLName, xAttrList, xShapes); + if (pContext) + { + bIsEmpty = sal_False; + rXMLImport.ProgressBarIncrement(sal_False); + } + } + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +sal_Bool ScXMLTableRowCellContext::IsMerged (const uno::Reference <table::XCellRange>& xCellRange, const sal_Int32 nCol, const sal_Int32 nRow, + table::CellRangeAddress& aCellAddress) const +{ + table::CellAddress aCell; // don't need to set the sheet, because every sheet can contain the same count of cells. + aCell.Column = nCol; + aCell.Row = nRow; + if (CellExists(aCell)) + { + uno::Reference<sheet::XSheetCellRange> xMergeSheetCellRange (xCellRange->getCellRangeByPosition(nCol,nRow,nCol,nRow), uno::UNO_QUERY); + uno::Reference<sheet::XSpreadsheet> xTable (xMergeSheetCellRange->getSpreadsheet()); + uno::Reference<sheet::XSheetCellCursor> xMergeSheetCursor (xTable->createCursorByRange(xMergeSheetCellRange)); + if (xMergeSheetCursor.is()) + { + xMergeSheetCursor->collapseToMergedArea(); + uno::Reference<sheet::XCellRangeAddressable> xMergeCellAddress (xMergeSheetCursor, uno::UNO_QUERY); + if (xMergeCellAddress.is()) + { + aCellAddress = xMergeCellAddress->getRangeAddress(); + if (aCellAddress.StartColumn == nCol && aCellAddress.EndColumn == nCol && + aCellAddress.StartRow == nRow && aCellAddress.EndRow == nRow) + return sal_False; + else + return sal_True; + } + } + } + return sal_False; +} + +void ScXMLTableRowCellContext::DoMerge(const com::sun::star::table::CellAddress& aCellPos, + const sal_Int32 nCols, const sal_Int32 nRows) +{ + if (CellExists(aCellPos)) + { + uno::Reference<table::XCellRange> xCellRange(rXMLImport.GetTables().GetCurrentXCellRange()); + if ( xCellRange.is() ) + { + // Stored merge range may actually be of a larger extend than what + // we support, in which case getCellRangeByPosition() throws + // IndexOutOfBoundsException. Do nothing then. + try + { + table::CellRangeAddress aCellAddress; + if (IsMerged(xCellRange, aCellPos.Column, aCellPos.Row, aCellAddress)) + { + //unmerge + uno::Reference <util::XMergeable> xMergeable (xCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow, + aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY); + if (xMergeable.is()) + xMergeable->merge(sal_False); + } + + //merge + uno::Reference <util::XMergeable> xMergeable (xCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow, + aCellAddress.EndColumn + nCols, aCellAddress.EndRow + nRows), uno::UNO_QUERY); + if (xMergeable.is()) + xMergeable->merge(sal_True); + } + catch ( lang::IndexOutOfBoundsException & ) + { + DBG_ERRORFILE("ScXMLTableRowCellContext::DoMerge: range to be merged larger than what we support"); + } + } + } +} + +void ScXMLTableRowCellContext::SetContentValidation(com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet>& xPropSet) +{ + if (pContentValidationName) + { + ScMyImportValidation aValidation; + aValidation.eGrammar1 = aValidation.eGrammar2 = GetScImport().GetDocument()->GetStorageGrammar(); + if (rXMLImport.GetValidation(*pContentValidationName, aValidation)) + { + uno::Reference<beans::XPropertySet> xPropertySet(xPropSet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_VALIXML))), uno::UNO_QUERY); + if (xPropertySet.is()) + { + if (aValidation.sErrorMessage.getLength()) + xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ERRMESS)), uno::makeAny(aValidation.sErrorMessage)); + if (aValidation.sErrorTitle.getLength()) + xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ERRTITLE)), uno::makeAny(aValidation.sErrorTitle)); + if (aValidation.sImputMessage.getLength()) + xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_INPMESS)), uno::makeAny(aValidation.sImputMessage)); + if (aValidation.sImputTitle.getLength()) + xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_INPTITLE)), uno::makeAny(aValidation.sImputTitle)); + xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SHOWERR)), uno::makeAny(aValidation.bShowErrorMessage)); + xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SHOWINP)), uno::makeAny(aValidation.bShowImputMessage)); + xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_TYPE)), uno::makeAny(aValidation.aValidationType)); + xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_IGNOREBL)), uno::makeAny(aValidation.bIgnoreBlanks)); + xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SHOWLIST)), uno::makeAny(aValidation.nShowList)); + xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ERRALSTY)), uno::makeAny(aValidation.aAlertStyle)); + uno::Reference<sheet::XSheetCondition> xCondition(xPropertySet, uno::UNO_QUERY); + if (xCondition.is()) + { + xCondition->setFormula1(aValidation.sFormula1); + xCondition->setFormula2(aValidation.sFormula2); + xCondition->setOperator(aValidation.aOperator); + // #b4974740# source position must be set as string, because it may + // refer to a sheet that hasn't been loaded yet. + xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SOURCESTR)), uno::makeAny(aValidation.sBaseCellAddress)); + // Transport grammar and formula namespace + xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_FORMULANMSP1)), uno::makeAny(aValidation.sFormulaNmsp1)); + xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_FORMULANMSP2)), uno::makeAny(aValidation.sFormulaNmsp2)); + xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_GRAMMAR1)), uno::makeAny(static_cast<sal_Int32>(aValidation.eGrammar1))); + xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_GRAMMAR2)), uno::makeAny(static_cast<sal_Int32>(aValidation.eGrammar2))); + } + } + xPropSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_VALIXML)), uno::makeAny(xPropertySet)); + + // For now, any sheet with validity is blocked from stream-copying. + // Later, the validation names could be stored along with the style names. + ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetImport().GetModel())->GetSheetSaveData(); + pSheetData->BlockSheet( GetScImport().GetTables().GetCurrentSheet() ); + } + } +} + +void ScXMLTableRowCellContext::SetCellProperties(const uno::Reference<table::XCellRange>& xCellRange, + const table::CellAddress& aCellAddress) +{ + if (CellExists(aCellAddress) && pContentValidationName && pContentValidationName->getLength()) + { + sal_Int32 nBottom = aCellAddress.Row + nRepeatedRows - 1; + sal_Int32 nRight = aCellAddress.Column + nCellsRepeated - 1; + if (nBottom > MAXROW) + nBottom = MAXROW; + if (nRight > MAXCOL) + nRight = MAXCOL; + uno::Reference <beans::XPropertySet> xProperties (xCellRange->getCellRangeByPosition(aCellAddress.Column, aCellAddress.Row, + nRight, nBottom), uno::UNO_QUERY); + if (xProperties.is()) + SetContentValidation(xProperties); + } +} + +void ScXMLTableRowCellContext::SetCellProperties(const uno::Reference<table::XCell>& xCell) +{ + if (pContentValidationName && pContentValidationName->getLength()) + { + uno::Reference <beans::XPropertySet> xProperties (xCell, uno::UNO_QUERY); + if (xProperties.is()) + SetContentValidation(xProperties); + } +} + +void ScXMLTableRowCellContext::SetAnnotation(const table::CellAddress& aCellAddress) +{ + ScDocument* pDoc = rXMLImport.GetDocument(); + if( !pDoc || !mxAnnotationData.get() ) + return; + + LockSolarMutex(); + + ScAddress aPos; + ScUnoConversion::FillScAddress( aPos, aCellAddress ); + ScPostIt* pNote = 0; + + uno::Reference< drawing::XShapes > xShapes = rXMLImport.GetTables().GetCurrentXShapes(); + uno::Reference< container::XIndexAccess > xShapesIA( xShapes, uno::UNO_QUERY ); + sal_Int32 nOldShapeCount = xShapesIA.is() ? xShapesIA->getCount() : 0; + + DBG_ASSERT( !mxAnnotationData->mxShape.is() || mxAnnotationData->mxShapes.is(), + "ScXMLTableRowCellContext::SetAnnotation - shape without drawing page" ); + if( mxAnnotationData->mxShape.is() && mxAnnotationData->mxShapes.is() ) + { + DBG_ASSERT( mxAnnotationData->mxShapes.get() == xShapes.get(), "ScXMLTableRowCellContext::SetAnnotation - diffenet drawing pages" ); + SdrObject* pObject = ::GetSdrObjectFromXShape( mxAnnotationData->mxShape ); + DBG_ASSERT( pObject, "ScXMLTableRowCellContext::SetAnnotation - cannot get SdrObject from shape" ); + + /* Try to reuse the drawing object already created (but only if the + note is visible, and the object is a caption object). */ + if( mxAnnotationData->mbShown && mxAnnotationData->mbUseShapePos ) + { + if( SdrCaptionObj* pCaption = dynamic_cast< SdrCaptionObj* >( pObject ) ) + { + OSL_ENSURE( !pCaption->GetLogicRect().IsEmpty(), "ScXMLTableRowCellContext::SetAnnotation - invalid caption rectangle" ); + // create the cell note with the caption object + pNote = ScNoteUtil::CreateNoteFromCaption( *pDoc, aPos, *pCaption, true ); + // forget pointer to object (do not create note again below) + pObject = 0; + } + } + + // drawing object has not been used to create a note -> use shape data + if( pObject ) + { + // rescue settings from drawing object before the shape is removed + ::std::auto_ptr< SfxItemSet > xItemSet( new SfxItemSet( pObject->GetMergedItemSet() ) ); + ::std::auto_ptr< OutlinerParaObject > xOutlinerObj; + if( OutlinerParaObject* pOutlinerObj = pObject->GetOutlinerParaObject() ) + xOutlinerObj.reset( new OutlinerParaObject( *pOutlinerObj ) ); + Rectangle aCaptionRect; + if( mxAnnotationData->mbUseShapePos ) + aCaptionRect = pObject->GetLogicRect(); + // remove the shape from the drawing page, this invalidates pObject + mxAnnotationData->mxShapes->remove( mxAnnotationData->mxShape ); + pObject = 0; + // update current number of existing objects + if( xShapesIA.is() ) + nOldShapeCount = xShapesIA->getCount(); + + // an outliner object is required (empty note captions not allowed) + if( xOutlinerObj.get() ) + { + // create cell note with all data from drawing object + pNote = ScNoteUtil::CreateNoteFromObjectData( *pDoc, aPos, + xItemSet.release(), xOutlinerObj.release(), + aCaptionRect, mxAnnotationData->mbShown, false ); + } + } + } + else if( mxAnnotationData->maSimpleText.getLength() > 0 ) + { + // create note from simple text + pNote = ScNoteUtil::CreateNoteFromString( *pDoc, aPos, + mxAnnotationData->maSimpleText, mxAnnotationData->mbShown, false ); + } + + // set author and date + if( pNote ) + { + double fDate; + rXMLImport.GetMM100UnitConverter().convertDateTime( fDate, mxAnnotationData->maCreateDate ); + SvNumberFormatter* pNumForm = pDoc->GetFormatTable(); + sal_uInt32 nfIndex = pNumForm->GetFormatIndex( NF_DATE_SYS_DDMMYYYY, LANGUAGE_SYSTEM ); + String aDate; + Color* pColor = 0; + Color** ppColor = &pColor; + pNumForm->GetOutputString( fDate, nfIndex, aDate, ppColor ); + pNote->SetDate( aDate ); + pNote->SetAuthor( mxAnnotationData->maAuthor ); + } + + // register a shape that has been newly created in the ScNoteUtil functions + if( xShapesIA.is() && (nOldShapeCount < xShapesIA->getCount()) ) + { + uno::Reference< drawing::XShape > xShape; + rXMLImport.GetShapeImport()->shapeWithZIndexAdded( xShape, xShapesIA->getCount() ); + } + + // store the style names for stream copying + ScSheetSaveData* pSheetData = ScModelObj::getImplementation(rXMLImport.GetModel())->GetSheetSaveData(); + pSheetData->HandleNoteStyles( mxAnnotationData->maStyleName, mxAnnotationData->maTextStyle, aPos ); + + std::vector<ScXMLAnnotationStyleEntry>::const_iterator aIter = mxAnnotationData->maContentStyles.begin(); + std::vector<ScXMLAnnotationStyleEntry>::const_iterator aEnd = mxAnnotationData->maContentStyles.end(); + while (aIter != aEnd) + { + pSheetData->AddNoteContentStyle( aIter->mnFamily, aIter->maName, aPos, aIter->maSelection ); + ++aIter; + } +} + +// core implementation +void ScXMLTableRowCellContext::SetDetectiveObj( const table::CellAddress& rPosition ) +{ + if( CellExists(rPosition) && pDetectiveObjVec && pDetectiveObjVec->size() ) + { + LockSolarMutex(); + ScDetectiveFunc aDetFunc( rXMLImport.GetDocument(), rPosition.Sheet ); + uno::Reference<container::XIndexAccess> xShapesIndex (rXMLImport.GetTables().GetCurrentXShapes(), uno::UNO_QUERY); // make draw page + ScMyImpDetectiveObjVec::iterator aItr(pDetectiveObjVec->begin()); + ScMyImpDetectiveObjVec::iterator aEndItr(pDetectiveObjVec->end()); + while(aItr != aEndItr) + { + ScAddress aScAddress; + ScUnoConversion::FillScAddress( aScAddress, rPosition ); + aDetFunc.InsertObject( aItr->eObjType, aScAddress, aItr->aSourceRange, aItr->bHasError ); + if (xShapesIndex.is()) + { + sal_Int32 nShapes = xShapesIndex->getCount(); + uno::Reference < drawing::XShape > xShape; + rXMLImport.GetShapeImport()->shapeWithZIndexAdded(xShape, nShapes); + } + ++aItr; + } + } +} + +// core implementation +void ScXMLTableRowCellContext::SetCellRangeSource( const table::CellAddress& rPosition ) +{ + if( CellExists(rPosition) && pCellRangeSource && pCellRangeSource->sSourceStr.getLength() && + pCellRangeSource->sFilterName.getLength() && pCellRangeSource->sURL.getLength() ) + { + ScDocument* pDoc = rXMLImport.GetDocument(); + if (pDoc) + { + LockSolarMutex(); + ScRange aDestRange( static_cast<SCCOL>(rPosition.Column), static_cast<SCROW>(rPosition.Row), rPosition.Sheet, + static_cast<SCCOL>(rPosition.Column + pCellRangeSource->nColumns - 1), + static_cast<SCROW>(rPosition.Row + pCellRangeSource->nRows - 1), rPosition.Sheet ); + String sFilterName( pCellRangeSource->sFilterName ); + String sSourceStr( pCellRangeSource->sSourceStr ); + ScAreaLink* pLink = new ScAreaLink( pDoc->GetDocumentShell(), pCellRangeSource->sURL, + sFilterName, pCellRangeSource->sFilterOptions, sSourceStr, aDestRange, pCellRangeSource->nRefresh ); + sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager(); + pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, pCellRangeSource->sURL, &sFilterName, &sSourceStr ); + } + } +} + +bool lcl_IsEmptyOrNote( ScDocument* pDoc, const table::CellAddress& rCurrentPos ) +{ + ScAddress aScAddress; + ScUnoConversion::FillScAddress( aScAddress, rCurrentPos ); + ScBaseCell* pCell = pDoc->GetCell( aScAddress ); + return ( !pCell || pCell->GetCellType() == CELLTYPE_NOTE ); +} + +void ScXMLTableRowCellContext::EndElement() +{ + if (!bHasSubTable) + { + if (bHasTextImport && rXMLImport.GetRemoveLastChar()) + { + if (rXMLImport.GetTextImport()->GetCursor().is()) + { + //GetImport().GetTextImport()->GetCursor()->gotoEnd(sal_False); + if( GetImport().GetTextImport()->GetCursor()->goLeft( 1, sal_True ) ) + { + GetImport().GetTextImport()->GetText()->insertString( + GetImport().GetTextImport()->GetCursorAsRange(), rtl::OUString(), + sal_True ); + } + rXMLImport.GetTextImport()->ResetCursor(); + } + } + table::CellAddress aCellPos = rXMLImport.GetTables().GetRealCellPos(); + if (aCellPos.Column > 0 && nRepeatedRows > 1) + aCellPos.Row -= (nRepeatedRows - 1); + uno::Reference<table::XCellRange> xCellRange(rXMLImport.GetTables().GetCurrentXCellRange()); + if (xCellRange.is()) + { + if (bIsMerged) + DoMerge(aCellPos, nMergedCols - 1, nMergedRows - 1); + if ( !pOUFormula ) + { + ::boost::optional< rtl::OUString > pOUText; + + if(nCellType == util::NumberFormat::TEXT) + { + if (xLockable.is()) + xLockable->removeActionLock(); + + // #i61702# The formatted text content of xBaseCell / xLockable is invalidated, + // so it can't be used after calling removeActionLock (getString always uses the document). + + if (CellExists(aCellPos) && ((nCellsRepeated > 1) || (nRepeatedRows > 1))) + { + if (!xBaseCell.is()) + { + try + { + xBaseCell.set(xCellRange->getCellByPosition(aCellPos.Column, aCellPos.Row)); + } + catch (lang::IndexOutOfBoundsException&) + { + DBG_ERRORFILE("It seems here are to many columns or rows"); + } + } + uno::Reference <text::XText> xTempText (xBaseCell, uno::UNO_QUERY); + if (xTempText.is()) + { + pOUText.reset(xTempText->getString()); + } + } + if ( (!pOUTextContent && !pOUText && !pOUTextValue) + && ( (pOUTextContent && !pOUTextContent->getLength()) || !pOUTextContent ) + && ( (pOUText && !pOUText->getLength()) || !pOUText ) + && ( (pOUTextValue && !pOUTextValue->getLength()) || !pOUTextValue )) + bIsEmpty = sal_True; + } + sal_Bool bWasEmpty = bIsEmpty; +// uno::Reference <table::XCell> xCell; + table::CellAddress aCurrentPos( aCellPos ); + if ((pContentValidationName && pContentValidationName->getLength()) || + mxAnnotationData.get() || pDetectiveObjVec || pCellRangeSource) + bIsEmpty = sal_False; + + ScMyTables& rTables = rXMLImport.GetTables(); + for (sal_Int32 i = 0; i < nCellsRepeated; ++i) + { + aCurrentPos.Column = aCellPos.Column + i; + if (i > 0) + rTables.AddColumn(sal_False); + if (!bIsEmpty) + { + for (sal_Int32 j = 0; j < nRepeatedRows; ++j) + { + aCurrentPos.Row = aCellPos.Row + j; + if ((aCurrentPos.Column == 0) && (j > 0)) + { + rTables.AddRow(); + rTables.AddColumn(sal_False); + } + if (CellExists(aCurrentPos)) + { + // test - bypass the API + // if (xBaseCell.is() && (aCurrentPos == aCellPos)) + // xCell.set(xBaseCell); + // else + // { + // try + // { + // xCell.set(xCellRange->getCellByPosition(aCurrentPos.Column, aCurrentPos.Row)); + // } + // catch (lang::IndexOutOfBoundsException&) + // { + // DBG_ERRORFILE("It seems here are to many columns or rows"); + // } + // } + + // test - bypass the API + // if ((!(bIsCovered) || (xCell->getType() == table::CellContentType_EMPTY))) + if ((!(bIsCovered) || lcl_IsEmptyOrNote( rXMLImport.GetDocument(), aCurrentPos ))) + { + switch (nCellType) + { + case util::NumberFormat::TEXT: + { + sal_Bool bDoIncrement = sal_True; + if (rTables.IsPartOfMatrix(aCurrentPos.Column, aCurrentPos.Row)) + { + LockSolarMutex(); + // test - bypass the API + // ScCellObj* pCellObj = (ScCellObj*)ScCellRangesBase::getImplementation(xCell); + // if (pCellObj) + // { + // if(pOUTextValue && pOUTextValue->getLength()) + // pCellObj->SetFormulaResultString(*pOUTextValue); + // else if (pOUTextContent && pOUTextContent->getLength()) + // pCellObj->SetFormulaResultString(*pOUTextContent); + // else if ( i > 0 && pOUText && pOUText->getLength() ) + // { + // pCellObj->SetFormulaResultString(*pOUText); + // } + // else + // bDoIncrement = sal_False; + // } + // else + // bDoIncrement = sal_False; + ScAddress aScAddress; + ScUnoConversion::FillScAddress( aScAddress, aCurrentPos ); + ScBaseCell* pCell = rXMLImport.GetDocument()->GetCell( aScAddress ); + bDoIncrement = ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA ); + if ( bDoIncrement ) + { + ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell); + if (pOUTextValue && pOUTextValue->getLength()) + pFCell->SetHybridString( *pOUTextValue ); + else if (pOUTextContent && pOUTextContent->getLength()) + pFCell->SetHybridString( *pOUTextContent ); + else if ( i > 0 && pOUText && pOUText->getLength() ) + pFCell->SetHybridString( *pOUText ); + else + bDoIncrement = sal_False; + } + } + else + { + // test - bypass the API + // uno::Reference <text::XText> xText (xCell, uno::UNO_QUERY); + // if (xText.is()) + // { + // if(pOUTextValue && pOUTextValue->getLength()) + // xText->setString(*pOUTextValue); + // else if (pOUTextContent && pOUTextContent->getLength()) + // xText->setString(*pOUTextContent); + // else if ( i > 0 && pOUText && pOUText->getLength() ) + // { + // xText->setString(*pOUText); + // } + // else + // bDoIncrement = sal_False; + // } + LockSolarMutex(); + ScBaseCell* pNewCell = NULL; + ScDocument* pDoc = rXMLImport.GetDocument(); + if (pOUTextValue && pOUTextValue->getLength()) + pNewCell = ScBaseCell::CreateTextCell( *pOUTextValue, pDoc ); + else if (pOUTextContent && pOUTextContent->getLength()) + pNewCell = ScBaseCell::CreateTextCell( *pOUTextContent, pDoc ); + else if ( i > 0 && pOUText && pOUText->getLength() ) + pNewCell = ScBaseCell::CreateTextCell( *pOUText, pDoc ); + + bDoIncrement = pNewCell != NULL; + if ( bDoIncrement ) + { + ScAddress aScAddress; + ScUnoConversion::FillScAddress( aScAddress, aCurrentPos ); + pDoc->PutCell( aScAddress, pNewCell ); + } + } + // #i56027# This is about setting simple text, not edit cells, + // so ProgressBarIncrement must be called with bEditCell = FALSE. + // Formatted text that is put into the cell by the child context + // is handled below (bIsEmpty is sal_True then). + if (bDoIncrement || bHasTextImport) + rXMLImport.ProgressBarIncrement(sal_False); + } + break; + case util::NumberFormat::NUMBER: + case util::NumberFormat::PERCENT: + case util::NumberFormat::CURRENCY: + case util::NumberFormat::TIME: + case util::NumberFormat::DATETIME: + case util::NumberFormat::LOGICAL: + { + if (rTables.IsPartOfMatrix(aCurrentPos.Column, aCurrentPos.Row)) + { + LockSolarMutex(); + // test - bypass the API + // ScCellObj* pCellObj = (ScCellObj*)ScCellRangesBase::getImplementation(xCell); + // if (pCellObj) + // pCellObj->SetFormulaResultDouble(fValue); + ScAddress aScAddress; + ScUnoConversion::FillScAddress( aScAddress, aCurrentPos ); + ScBaseCell* pCell = rXMLImport.GetDocument()->GetCell( aScAddress ); + if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA ) + static_cast<ScFormulaCell*>(pCell)->SetHybridDouble( fValue ); + } + else + { + // test - bypass the API + // xCell->setValue(fValue); + LockSolarMutex(); + + // #i62435# Initialize the value cell's script type + // if the default style's number format is latin-only. + // If the cell uses a different format, the script type + // will be reset when the style is applied. + + ScBaseCell* pNewCell = new ScValueCell(fValue); + if ( rXMLImport.IsLatinDefaultStyle() ) + pNewCell->SetScriptType( SCRIPTTYPE_LATIN ); + rXMLImport.GetDocument()->PutCell( + sal::static_int_cast<SCCOL>( aCurrentPos.Column ), + sal::static_int_cast<SCROW>( aCurrentPos.Row ), + sal::static_int_cast<SCTAB>( aCurrentPos.Sheet ), + pNewCell ); + } + rXMLImport.ProgressBarIncrement(sal_False); + } + break; + default: + { + DBG_ERROR("no cell type given"); + } + break; + } + } + + SetAnnotation(aCurrentPos); + SetDetectiveObj( aCurrentPos ); + SetCellRangeSource( aCurrentPos ); + } + else + { + if (!bWasEmpty || mxAnnotationData.get()) + { + if (aCurrentPos.Row > MAXROW) + rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_ROW_OVERFLOW); + else + rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_COLUMN_OVERFLOW); + } + } + } + } + else + { + // #i56027# If the child context put formatted text into the cell, + // bIsEmpty is sal_True and ProgressBarIncrement has to be called + // with bEditCell = TRUE. + if (bHasTextImport) + rXMLImport.ProgressBarIncrement(sal_True); + if ((i == 0) && (aCellPos.Column == 0)) + for (sal_Int32 j = 1; j < nRepeatedRows; ++j) + { + rTables.AddRow(); + rTables.AddColumn(sal_False); + } + } + } + if (nCellsRepeated > 1 || nRepeatedRows > 1) + { + SetCellProperties(xCellRange, aCellPos); // set now only the validation for the complete range with the given cell as start cell + //SetType(xCellRange, aCellPos); + SCCOL nStartCol(aCellPos.Column < MAXCOL ? static_cast<SCCOL>(aCellPos.Column) : MAXCOL); + SCROW nStartRow(aCellPos.Row < MAXROW ? static_cast<SCROW>(aCellPos.Row) : MAXROW); + SCCOL nEndCol(aCellPos.Column + nCellsRepeated - 1 < MAXCOL ? static_cast<SCCOL>(aCellPos.Column + nCellsRepeated - 1) : MAXCOL); + SCROW nEndRow(aCellPos.Row + nRepeatedRows - 1 < MAXROW ? static_cast<SCROW>(aCellPos.Row + nRepeatedRows - 1) : MAXROW); + ScRange aScRange( nStartCol, nStartRow, aCellPos.Sheet, + nEndCol, nEndRow, aCellPos.Sheet ); + rXMLImport.GetStylesImportHelper()->AddRange(aScRange); + } + else if (CellExists(aCellPos)) + { + rXMLImport.GetStylesImportHelper()->AddCell(aCellPos); + + // test - bypass the API + // SetCellProperties(xCell); // set now only the validation + SetCellProperties(xCellRange, aCellPos); + + //SetType(xTempCell); + } + } + else // if ( !pOUFormula ) + { + if (CellExists(aCellPos)) + { + uno::Reference <table::XCell> xCell; + try + { + xCell.set(xCellRange->getCellByPosition(aCellPos.Column , aCellPos.Row)); + } + catch (lang::IndexOutOfBoundsException&) + { + DBG_ERRORFILE("It seems here are to many columns or rows"); + } + if (xCell.is()) + { + SetCellProperties(xCell); // set now only the validation + DBG_ASSERT(((nCellsRepeated == 1) && (nRepeatedRows == 1)), "repeated cells with formula not possible now"); + rXMLImport.GetStylesImportHelper()->AddCell(aCellPos); + if (!bIsMatrix) + { + LockSolarMutex(); + ScCellObj* pCellObj = + static_cast<ScCellObj*>(ScCellRangesBase::getImplementation( + xCell)); + if (pCellObj) + { + pCellObj->SetFormulaWithGrammar( pOUFormula->first, pOUFormula->second, eGrammar); + if (bFormulaTextResult && pOUTextValue && pOUTextValue->getLength()) + pCellObj->SetFormulaResultString( *pOUTextValue); + else if (fValue != 0.0) + pCellObj->SetFormulaResultDouble( fValue); + } + } + else + { + if (nMatrixCols > 0 && nMatrixRows > 0) + { + rXMLImport.GetTables().AddMatrixRange( + aCellPos.Column, aCellPos.Row, + aCellPos.Column + nMatrixCols - 1, + aCellPos.Row + nMatrixRows - 1, + pOUFormula->first, pOUFormula->second, eGrammar); + } + } + SetAnnotation( aCellPos ); + SetDetectiveObj( aCellPos ); + SetCellRangeSource( aCellPos ); + rXMLImport.ProgressBarIncrement(sal_False); + } + } + else + { + if (aCellPos.Row > MAXROW) + rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_ROW_OVERFLOW); + else + rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_COLUMN_OVERFLOW); + } + + } // if ( !pOUFormula ) + } + UnlockSolarMutex(); + } + bIsMerged = sal_False; + bHasSubTable = sal_False; + nMergedCols = 1; + nMergedRows = 1; + nCellsRepeated = 1; +} diff --git a/sc/source/filter/xml/xmlcelli.hxx b/sc/source/filter/xml/xmlcelli.hxx new file mode 100644 index 000000000000..a6091f87e485 --- /dev/null +++ b/sc/source/filter/xml/xmlcelli.hxx @@ -0,0 +1,130 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef SC_XMLCELLI_HXX +#define SC_XMLCELLI_HXX + +#include <memory> +#include "XMLDetectiveContext.hxx" +#include "XMLCellRangeSourceContext.hxx" +#include <xmloff/xmlictxt.hxx> +#include <xmloff/xmlimp.hxx> +#include <com/sun/star/table/XCell.hpp> +#include <tools/time.hxx> +#include <com/sun/star/util/DateTime.hpp> +#include <com/sun/star/table/XCellRange.hpp> +#include <com/sun/star/table/CellRangeAddress.hpp> +#include <com/sun/star/table/CellAddress.hpp> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include <com/sun/star/document/XActionLockable.hpp> + +#include "formula/grammar.hxx" +#include <boost/optional.hpp> + +class ScXMLImport; +struct ScXMLAnnotationData; + +class ScXMLTableRowCellContext : public SvXMLImportContext +{ + typedef ::std::pair< ::rtl::OUString, ::rtl::OUString > FormulaWithNamespace; + com::sun::star::uno::Reference<com::sun::star::table::XCell> xBaseCell; + com::sun::star::uno::Reference<com::sun::star::document::XActionLockable> xLockable; + ::boost::optional< rtl::OUString > pOUTextValue; + ::boost::optional< rtl::OUString > pOUTextContent; + ::boost::optional< FormulaWithNamespace > pOUFormula; + rtl::OUString* pContentValidationName; + ::std::auto_ptr< ScXMLAnnotationData > mxAnnotationData; + ScMyImpDetectiveObjVec* pDetectiveObjVec; + ScMyImpCellRangeSource* pCellRangeSource; + double fValue; + sal_Int32 nMergedRows, nMergedCols; + sal_Int32 nMatrixRows, nMatrixCols; + sal_Int32 nRepeatedRows; + sal_Int32 nCellsRepeated; + ScXMLImport& rXMLImport; + formula::FormulaGrammar::Grammar eGrammar; + sal_Int16 nCellType; + sal_Bool bIsMerged; + sal_Bool bIsMatrix; + sal_Bool bHasSubTable; + sal_Bool bIsCovered; + sal_Bool bIsEmpty; + sal_Bool bHasTextImport; + sal_Bool bIsFirstTextImport; + sal_Bool bSolarMutexLocked; + sal_Bool bFormulaTextResult; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + + sal_Int16 GetCellType(const rtl::OUString& sOUValue) const; + + sal_Bool IsMerged (const com::sun::star::uno::Reference <com::sun::star::table::XCellRange>& xCellRange, + const sal_Int32 nCol, const sal_Int32 nRow, + com::sun::star::table::CellRangeAddress& aCellAddress) const; + void DoMerge(const com::sun::star::table::CellAddress& aCellPos, + const sal_Int32 nCols, const sal_Int32 nRows); + + void SetContentValidation(com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet>& xPropSet); + void SetCellProperties(const com::sun::star::uno::Reference<com::sun::star::table::XCellRange>& xCellRange, + const com::sun::star::table::CellAddress& aCellAddress); + void SetCellProperties(const com::sun::star::uno::Reference<com::sun::star::table::XCell>& xCell); + + void LockSolarMutex(); + void UnlockSolarMutex(); + + sal_Bool CellExists(const com::sun::star::table::CellAddress& aCellPos) const + { + return (aCellPos.Column <= MAXCOL && aCellPos.Row <= MAXROW); + } + +public: + + ScXMLTableRowCellContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + const sal_Bool bIsCovered, const sal_Int32 nRepeatedRows ); + + virtual ~ScXMLTableRowCellContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + inline void SetString(const rtl::OUString& rOUTempText) { pOUTextContent.reset(rOUTempText); } + void SetCursorOnTextImport(const rtl::OUString& rOUTempText); + + void SetAnnotation(const ::com::sun::star::table::CellAddress& rPosition ); + void SetDetectiveObj( const ::com::sun::star::table::CellAddress& rPosition ); + void SetCellRangeSource( const ::com::sun::star::table::CellAddress& rPosition ); + + virtual void EndElement(); +}; + +#endif + diff --git a/sc/source/filter/xml/xmlcoli.cxx b/sc/source/filter/xml/xmlcoli.cxx new file mode 100644 index 000000000000..bdeaf39a3eb9 --- /dev/null +++ b/sc/source/filter/xml/xmlcoli.cxx @@ -0,0 +1,333 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- + +#include "xmlcoli.hxx" +#include "xmlimprt.hxx" +#include "global.hxx" +#include "xmlstyli.hxx" +#include "document.hxx" +#include "docuno.hxx" +#include "olinetab.hxx" +#include "sheetdata.hxx" +#include "unonames.hxx" + +#include <xmloff/xmltkmap.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/families.hxx> +#include <xmloff/xmltoken.hxx> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include <com/sun/star/sheet/XSpreadsheet.hpp> +#include <com/sun/star/table/XColumnRowRange.hpp> +#include <com/sun/star/sheet/XPrintAreas.hpp> + +using namespace com::sun::star; +using namespace xmloff::token; + +//------------------------------------------------------------------ + +ScXMLTableColContext::ScXMLTableColContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + sVisibility(GetXMLToken(XML_VISIBLE)) +{ + nColCount = 1; + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetTableColAttrTokenMap(); + + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_TABLE_COL_ATTR_REPEATED: + { + nColCount = sValue.toInt32(); + } + break; + case XML_TOK_TABLE_COL_ATTR_STYLE_NAME: + { + sStyleName = sValue; + } + break; + case XML_TOK_TABLE_COL_ATTR_VISIBILITY: + { + sVisibility = sValue; + } + break; + case XML_TOK_TABLE_COL_ATTR_DEFAULT_CELL_STYLE_NAME: + { + sCellStyleName = sValue; + } + break; + } + } +} + +ScXMLTableColContext::~ScXMLTableColContext() +{ +} + +SvXMLImportContext *ScXMLTableColContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + SvXMLImportContext *pContext = 0; +/* + const SvXMLTokenMap& rTokenMap = GetScImport().GetTableRowElemTokenMap(); + sal_Bool bHeader = sal_False; + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_TABLE_ROW_CELL: +// if( IsInsertCellPossible() ) + pContext = new ScXMLTableRowCellContext( GetScImport(), nPrefix, + rLName, xAttrList//, + //this + ); + break; + case XML_TOK_TABLE_ROW_COVERED_CELL: +// if( IsInsertCellPossible() ) + pContext = new ScXMLTableRowCellContext( GetScImport(), nPrefix, + rLName, xAttrList//, + //this + ); + break; + }*/ + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLTableColContext::EndElement() +{ + ScXMLImport& rXMLImport = GetScImport(); + sal_Int32 nSheet = rXMLImport.GetTables().GetCurrentSheet(); + sal_Int32 nCurrentColumn = rXMLImport.GetTables().GetCurrentColumn(); + uno::Reference<sheet::XSpreadsheet> xSheet(rXMLImport.GetTables().GetCurrentXSheet()); + if(xSheet.is()) + { + sal_Int32 nLastColumn(nCurrentColumn + nColCount - 1); + if (nLastColumn > MAXCOL) + nLastColumn = MAXCOL; + if (nCurrentColumn > MAXCOL) + nCurrentColumn = MAXCOL; + uno::Reference<table::XColumnRowRange> xColumnRowRange (xSheet->getCellRangeByPosition(nCurrentColumn, 0, nLastColumn, 0), uno::UNO_QUERY); + if (xColumnRowRange.is()) + { + uno::Reference <beans::XPropertySet> xColumnProperties(xColumnRowRange->getColumns(), uno::UNO_QUERY); + if (xColumnProperties.is()) + { + if (sStyleName.getLength()) + { + XMLTableStylesContext *pStyles = (XMLTableStylesContext *)rXMLImport.GetAutoStyles(); + if ( pStyles ) + { + XMLTableStyleContext* pStyle = (XMLTableStyleContext *)pStyles->FindStyleChildContext( + XML_STYLE_FAMILY_TABLE_COLUMN, sStyleName, sal_True); + if (pStyle) + { + pStyle->FillPropertySet(xColumnProperties); + + if ( nSheet != pStyle->GetLastSheet() ) + { + ScSheetSaveData* pSheetData = ScModelObj::getImplementation(rXMLImport.GetModel())->GetSheetSaveData(); + pSheetData->AddColumnStyle( sStyleName, ScAddress( (SCCOL)nCurrentColumn, 0, (SCTAB)nSheet ) ); + pStyle->SetLastSheet(nSheet); + } + } + } + } + rtl::OUString sVisible(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CELLVIS)); + sal_Bool bValue(sal_True); + if (!IsXMLToken(sVisibility, XML_VISIBLE)) + bValue = sal_False; + xColumnProperties->setPropertyValue(sVisible, uno::makeAny(bValue)); + } + } + } + + // #i57915# ScXMLImport::SetStyleToRange can't handle empty style names. + // The default for a column if there is no attribute is the style "Default" (programmatic API name). + if ( !sCellStyleName.getLength() ) + sCellStyleName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Default" )); + + GetScImport().GetTables().AddColCount(nColCount); + GetScImport().GetTables().AddColStyle(nColCount, sCellStyleName); +} + +ScXMLTableColsContext::ScXMLTableColsContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + const sal_Bool bTempHeader, const sal_Bool bTempGroup) : + SvXMLImportContext( rImport, nPrfx, rLName ), + nHeaderStartCol(0), + nHeaderEndCol(0), + nGroupStartCol(0), + nGroupEndCol(0), + bHeader(bTempHeader), + bGroup(bTempGroup), + bGroupDisplay(sal_True) +{ + // don't have any attributes + if (bHeader) + nHeaderStartCol = rImport.GetTables().GetCurrentColumn(); + else if (bGroup) + { + nGroupStartCol = rImport.GetTables().GetCurrentColumn(); + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + if (nPrefix == XML_NAMESPACE_TABLE && IsXMLToken(aLocalName, XML_DISPLAY)) + { + if (IsXMLToken(sValue, XML_FALSE)) + bGroupDisplay = sal_False; + } + } + } +} + +ScXMLTableColsContext::~ScXMLTableColsContext() +{ +} + +SvXMLImportContext *ScXMLTableColsContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + const SvXMLTokenMap& rTokenMap = GetScImport().GetTableColsElemTokenMap(); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_TABLE_COLS_COL_GROUP: + pContext = new ScXMLTableColsContext( GetScImport(), nPrefix, + rLName, xAttrList, + sal_False, sal_True ); + break; + case XML_TOK_TABLE_COLS_HEADER_COLS: + pContext = new ScXMLTableColsContext( GetScImport(), nPrefix, + rLName, xAttrList, + sal_True, sal_False ); + break; + case XML_TOK_TABLE_COLS_COLS: + pContext = new ScXMLTableColsContext( GetScImport(), nPrefix, + rLName, xAttrList, + sal_False, sal_False ); + break; + case XML_TOK_TABLE_COLS_COL: + pContext = new ScXMLTableColContext( GetScImport(), nPrefix, + rLName, xAttrList//, + //this + ); + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLTableColsContext::EndElement() +{ + ScXMLImport& rXMLImport = GetScImport(); + if (bHeader) + { + nHeaderEndCol = rXMLImport.GetTables().GetCurrentColumn(); + nHeaderEndCol--; + if (nHeaderStartCol <= nHeaderEndCol) + { + uno::Reference <sheet::XPrintAreas> xPrintAreas (rXMLImport.GetTables().GetCurrentXSheet(), uno::UNO_QUERY); + if (xPrintAreas.is()) + { + if (!xPrintAreas->getPrintTitleColumns()) + { + xPrintAreas->setPrintTitleColumns(sal_True); + table::CellRangeAddress aColumnHeaderRange; + aColumnHeaderRange.StartColumn = nHeaderStartCol; + aColumnHeaderRange.EndColumn = nHeaderEndCol; + xPrintAreas->setTitleColumns(aColumnHeaderRange); + } + else + { + table::CellRangeAddress aColumnHeaderRange(xPrintAreas->getTitleColumns()); + aColumnHeaderRange.EndColumn = nHeaderEndCol; + xPrintAreas->setTitleColumns(aColumnHeaderRange); + } + } + } + } + else if (bGroup) + { + sal_Int32 nSheet = rXMLImport.GetTables().GetCurrentSheet(); + nGroupEndCol = rXMLImport.GetTables().GetCurrentColumn(); + nGroupEndCol--; + if (nGroupStartCol <= nGroupEndCol) + { + ScDocument* pDoc = GetScImport().GetDocument(); + if (pDoc) + { + rXMLImport.LockSolarMutex(); + ScOutlineTable* pOutlineTable = pDoc->GetOutlineTable(static_cast<SCTAB>(nSheet), sal_True); + ScOutlineArray* pColArray = pOutlineTable ? pOutlineTable->GetColArray() : NULL; + if (pColArray) + { + sal_Bool bResized; + pColArray->Insert(static_cast<SCCOL>(nGroupStartCol), static_cast<SCCOL>(nGroupEndCol), bResized, !bGroupDisplay, sal_True); + } + rXMLImport.UnlockSolarMutex(); + } + } + } +} diff --git a/sc/source/filter/xml/xmlcoli.hxx b/sc/source/filter/xml/xmlcoli.hxx new file mode 100644 index 000000000000..7778192a337a --- /dev/null +++ b/sc/source/filter/xml/xmlcoli.hxx @@ -0,0 +1,93 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef SC_XMLCOLI_HXX +#define SC_XMLCOLI_HXX + +#include <xmloff/xmlictxt.hxx> +#include <xmloff/xmlimp.hxx> + +class ScXMLImport; + +class ScXMLTableColContext : public SvXMLImportContext +{ + sal_Int32 nColCount; + rtl::OUString sStyleName; + rtl::OUString sVisibility; + rtl::OUString sCellStyleName; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLTableColContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual ~ScXMLTableColContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLTableColsContext : public SvXMLImportContext +{ + sal_Int32 nHeaderStartCol; + sal_Int32 nHeaderEndCol; + sal_Int32 nGroupStartCol; + sal_Int32 nGroupEndCol; + sal_Bool bHeader; + sal_Bool bGroup; + sal_Bool bGroupDisplay; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLTableColsContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + const sal_Bool bHeader, const sal_Bool bGroup); + + virtual ~ScXMLTableColsContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +#endif diff --git a/sc/source/filter/xml/xmlconti.cxx b/sc/source/filter/xml/xmlconti.cxx new file mode 100644 index 000000000000..4c32f1859a8a --- /dev/null +++ b/sc/source/filter/xml/xmlconti.cxx @@ -0,0 +1,107 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- + +#include "xmlconti.hxx" +#include "xmlimprt.hxx" +#include "global.hxx" +#include "document.hxx" + +#include <xmloff/xmltkmap.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/xmltoken.hxx> + +using namespace xmloff::token; + +//------------------------------------------------------------------ + +ScXMLContentContext::ScXMLContentContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */, + rtl::OUStringBuffer& sTempValue) : + SvXMLImportContext( rImport, nPrfx, rLName ), + sOUText(), + sValue(sTempValue) +{ +} + +ScXMLContentContext::~ScXMLContentContext() +{ +} + +SvXMLImportContext *ScXMLContentContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + if ((nPrefix == XML_NAMESPACE_TEXT) && IsXMLToken(rLName, XML_S)) + { + sal_Int32 nRepeat(0); + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + const rtl::OUString& sAttrValue(xAttrList->getValueByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrfx = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + if ((nPrfx == XML_NAMESPACE_TEXT) && IsXMLToken(aLocalName, XML_C)) + nRepeat = sAttrValue.toInt32(); + } + if (nRepeat) + for (sal_Int32 j = 0; j < nRepeat; ++j) + sOUText.append(static_cast<sal_Unicode>(' ')); + else + sOUText.append(static_cast<sal_Unicode>(' ')); + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLContentContext::Characters( const ::rtl::OUString& rChars ) +{ + sOUText.append(rChars); +} + +void ScXMLContentContext::EndElement() +{ + sValue.append(sOUText); +} diff --git a/sc/source/filter/xml/xmlconti.hxx b/sc/source/filter/xml/xmlconti.hxx new file mode 100644 index 000000000000..c7d8521d71af --- /dev/null +++ b/sc/source/filter/xml/xmlconti.hxx @@ -0,0 +1,63 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef SC_XMLCONTI_HXX +#define SC_XMLCONTI_HXX + +#include <xmloff/xmlimp.hxx> +#include <rtl/ustrbuf.hxx> + +class ScXMLImport; + +class ScXMLContentContext : public SvXMLImportContext +{ + rtl::OUStringBuffer sOUText; + rtl::OUStringBuffer& sValue; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLContentContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + rtl::OUStringBuffer& sValue); + + virtual ~ScXMLContentContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void Characters( const ::rtl::OUString& rChars ); + + virtual void EndElement(); +}; + +#endif diff --git a/sc/source/filter/xml/xmlcvali.cxx b/sc/source/filter/xml/xmlcvali.cxx new file mode 100644 index 000000000000..0fd9887ea57e --- /dev/null +++ b/sc/source/filter/xml/xmlcvali.cxx @@ -0,0 +1,696 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- + +#include "xmlcvali.hxx" +#include "xmlimprt.hxx" +#include "xmlconti.hxx" +#include "document.hxx" +#include "XMLConverter.hxx" + +#include <xmloff/xmltkmap.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/XMLEventsImportContext.hxx> +#include <com/sun/star/sheet/TableValidationVisibility.hpp> +#include <tools/debug.hxx> + +using namespace com::sun::star; +using namespace xmloff::token; +using namespace ::formula; +using ::rtl::OUString; + +class ScXMLContentValidationContext : public SvXMLImportContext +{ + rtl::OUString sName; + rtl::OUString sHelpTitle; + rtl::OUString sHelpMessage; + rtl::OUString sErrorTitle; + rtl::OUString sErrorMessage; + rtl::OUString sErrorMessageType; + rtl::OUString sBaseCellAddress; + rtl::OUString sCondition; + sal_Int16 nShowList; + sal_Bool bAllowEmptyCell; + sal_Bool bDisplayHelp; + sal_Bool bDisplayError; + + SvXMLImportContextRef xEventContext; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + + com::sun::star::sheet::ValidationAlertStyle GetAlertStyle() const; + void SetFormula( OUString& rFormula, OUString& rFormulaNmsp, FormulaGrammar::Grammar& reGrammar, + const OUString& rCondition, const OUString& rGlobNmsp, FormulaGrammar::Grammar eGlobGrammar, bool bHasNmsp ) const; + void GetCondition( ScMyImportValidation& rValidation ) const; + +public: + + ScXMLContentValidationContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList); + + virtual ~ScXMLContentValidationContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); + + void SetHelpMessage(const rtl::OUString& sTitle, const rtl::OUString& sMessage, const sal_Bool bDisplay); + void SetErrorMessage(const rtl::OUString& sTitle, const rtl::OUString& sMessage, const rtl::OUString& sMessageType, const sal_Bool bDisplay); + void SetErrorMacro(const sal_Bool bExecute); +}; + +class ScXMLHelpMessageContext : public SvXMLImportContext +{ + rtl::OUString sTitle; + rtl::OUStringBuffer sMessage; + sal_Int32 nParagraphCount; + sal_Bool bDisplay; + + ScXMLContentValidationContext* pValidationContext; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLHelpMessageContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLContentValidationContext* pValidationContext); + + virtual ~ScXMLHelpMessageContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLErrorMessageContext : public SvXMLImportContext +{ + rtl::OUString sTitle; + rtl::OUStringBuffer sMessage; + rtl::OUString sMessageType; + sal_Int32 nParagraphCount; + sal_Bool bDisplay; + + ScXMLContentValidationContext* pValidationContext; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLErrorMessageContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLContentValidationContext* pValidationContext); + + virtual ~ScXMLErrorMessageContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLErrorMacroContext : public SvXMLImportContext +{ + rtl::OUString sName; + sal_Bool bExecute; + + ScXMLContentValidationContext* pValidationContext; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLErrorMacroContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLContentValidationContext* pValidationContext); + + virtual ~ScXMLErrorMacroContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + virtual void EndElement(); +}; + +//------------------------------------------------------------------ + +ScXMLContentValidationsContext::ScXMLContentValidationsContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) : + SvXMLImportContext( rImport, nPrfx, rLName ) +{ + // here are no attributes +} + +ScXMLContentValidationsContext::~ScXMLContentValidationsContext() +{ +} + +SvXMLImportContext *ScXMLContentValidationsContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + const SvXMLTokenMap& rTokenMap = GetScImport().GetContentValidationsElemTokenMap(); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_CONTENT_VALIDATION: + pContext = new ScXMLContentValidationContext( GetScImport(), nPrefix, rLName, xAttrList); + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLContentValidationsContext::EndElement() +{ +} + +ScXMLContentValidationContext::ScXMLContentValidationContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList) : + SvXMLImportContext( rImport, nPrfx, rLName ), + nShowList(sheet::TableValidationVisibility::UNSORTED), + bAllowEmptyCell(sal_True), + bDisplayHelp(sal_False), + bDisplayError(sal_False) +{ + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetContentValidationAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_CONTENT_VALIDATION_NAME: + sName = sValue; + break; + case XML_TOK_CONTENT_VALIDATION_CONDITION: + sCondition = sValue; + break; + case XML_TOK_CONTENT_VALIDATION_BASE_CELL_ADDRESS: + sBaseCellAddress = sValue; + break; + case XML_TOK_CONTENT_VALIDATION_ALLOW_EMPTY_CELL: + if (IsXMLToken(sValue, XML_FALSE)) + bAllowEmptyCell = sal_False; + break; + case XML_TOK_CONTENT_VALIDATION_DISPLAY_LIST: + { + if (IsXMLToken(sValue, XML_NO)) + { + nShowList = sheet::TableValidationVisibility::INVISIBLE; + } + else if (IsXMLToken(sValue, XML_UNSORTED)) + { + nShowList = sheet::TableValidationVisibility::UNSORTED; + } + else if (IsXMLToken(sValue, XML_SORTED_ASCENDING)) + { + nShowList = sheet::TableValidationVisibility::SORTEDASCENDING; + } + } + break; + } + } +} + +ScXMLContentValidationContext::~ScXMLContentValidationContext() +{ +} + +SvXMLImportContext *ScXMLContentValidationContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + const SvXMLTokenMap& rTokenMap = GetScImport().GetContentValidationElemTokenMap(); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_CONTENT_VALIDATION_ELEM_HELP_MESSAGE: + pContext = new ScXMLHelpMessageContext( GetScImport(), nPrefix, rLName, xAttrList, this); + break; + case XML_TOK_CONTENT_VALIDATION_ELEM_ERROR_MESSAGE: + pContext = new ScXMLErrorMessageContext( GetScImport(), nPrefix, rLName, xAttrList, this); + break; + case XML_TOK_CONTENT_VALIDATION_ELEM_ERROR_MACRO: + pContext = new ScXMLErrorMacroContext( GetScImport(), nPrefix, rLName, xAttrList, this); + break; + case XML_TOK_CONTENT_VALIDATION_ELEM_EVENT_LISTENERS: + pContext = new XMLEventsImportContext( GetImport(), nPrefix, rLName ); + xEventContext = pContext; + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +sheet::ValidationAlertStyle ScXMLContentValidationContext::GetAlertStyle() const +{ + if (IsXMLToken(sErrorMessageType, XML_MACRO)) + return sheet::ValidationAlertStyle_MACRO; + if (IsXMLToken(sErrorMessageType, XML_STOP)) + return sheet::ValidationAlertStyle_STOP; + if (IsXMLToken(sErrorMessageType, XML_WARNING)) + return sheet::ValidationAlertStyle_WARNING; + if (IsXMLToken(sErrorMessageType, XML_INFORMATION)) + return sheet::ValidationAlertStyle_INFO; + // default for unknown + return sheet::ValidationAlertStyle_STOP; +} + +void ScXMLContentValidationContext::SetFormula( OUString& rFormula, OUString& rFormulaNmsp, FormulaGrammar::Grammar& reGrammar, + const OUString& rCondition, const OUString& rGlobNmsp, FormulaGrammar::Grammar eGlobGrammar, bool bHasNmsp ) const +{ + reGrammar = FormulaGrammar::GRAM_UNSPECIFIED; + if( bHasNmsp ) + { + // the entire attribute contains a namespace: internal namespace not allowed + rFormula = rCondition; + rFormulaNmsp = rGlobNmsp; + reGrammar = eGlobGrammar; + } + else + { + // the attribute does not contain a namespace: try to find a namespace of an external grammar + GetScImport().ExtractFormulaNamespaceGrammar( rFormula, rFormulaNmsp, reGrammar, rCondition, true ); + if( reGrammar != FormulaGrammar::GRAM_EXTERNAL ) + reGrammar = eGlobGrammar; + } +} + +void ScXMLContentValidationContext::GetCondition( ScMyImportValidation& rValidation ) const +{ + rValidation.aValidationType = sheet::ValidationType_ANY; // #b6343997# default if no condition is given + rValidation.aOperator = sheet::ConditionOperator_NONE; + + if( sCondition.getLength() > 0 ) + { + // extract leading namespace from condition string + OUString aCondition, aConditionNmsp; + FormulaGrammar::Grammar eGrammar = FormulaGrammar::GRAM_UNSPECIFIED; + GetScImport().ExtractFormulaNamespaceGrammar( aCondition, aConditionNmsp, eGrammar, sCondition ); + bool bHasNmsp = aCondition.getLength() < sCondition.getLength(); + + // parse a condition from the attribute string + ScXMLConditionParseResult aParseResult; + ScXMLConditionHelper::parseCondition( aParseResult, aCondition, 0 ); + + /* Check the result. A valid value in aParseResult.meToken implies + that the other members of aParseResult are filled with valid data + for that token. */ + bool bSecondaryPart = false; + switch( aParseResult.meToken ) + { + case XML_COND_TEXTLENGTH: // condition is 'cell-content-text-length()<operator><expression>' + case XML_COND_TEXTLENGTH_ISBETWEEN: // condition is 'cell-content-text-length-is-between(<expression1>,<expression2>)' + case XML_COND_TEXTLENGTH_ISNOTBETWEEN: // condition is 'cell-content-text-length-is-not-between(<expression1>,<expression2>)' + case XML_COND_ISINLIST: // condition is 'cell-content-is-in-list(<expression>)' + rValidation.aValidationType = aParseResult.meValidation; + rValidation.aOperator = aParseResult.meOperator; + break; + + case XML_COND_ISWHOLENUMBER: // condition is 'cell-content-is-whole-number() and <condition>' + case XML_COND_ISDECIMALNUMBER: // condition is 'cell-content-is-decimal-number() and <condition>' + case XML_COND_ISDATE: // condition is 'cell-content-is-date() and <condition>' + case XML_COND_ISTIME: // condition is 'cell-content-is-time() and <condition>' + rValidation.aValidationType = aParseResult.meValidation; + bSecondaryPart = true; + break; + + default:; // unacceptable or unknown condition + } + + /* Parse the following 'and <condition>' part of some conditions. This + updates the members of aParseResult that will contain the operands + and comparison operator then. */ + if( bSecondaryPart ) + { + ScXMLConditionHelper::parseCondition( aParseResult, aCondition, aParseResult.mnEndIndex ); + if( aParseResult.meToken == XML_COND_AND ) + { + ScXMLConditionHelper::parseCondition( aParseResult, aCondition, aParseResult.mnEndIndex ); + switch( aParseResult.meToken ) + { + case XML_COND_CELLCONTENT: // condition is 'and cell-content()<operator><expression>' + case XML_COND_ISBETWEEN: // condition is 'and cell-content-is-between(<expression1>,<expression2>)' + case XML_COND_ISNOTBETWEEN: // condition is 'and cell-content-is-not-between(<expression1>,<expression2>)' + rValidation.aOperator = aParseResult.meOperator; + break; + default:; // unacceptable or unknown condition + } + } + } + + // a validation type (date, integer) without a condition isn't possible + if( rValidation.aOperator == sheet::ConditionOperator_NONE ) + rValidation.aValidationType = sheet::ValidationType_ANY; + + // parse the formulas + if( rValidation.aValidationType != sheet::ValidationType_ANY ) + { + SetFormula( rValidation.sFormula1, rValidation.sFormulaNmsp1, rValidation.eGrammar1, + aParseResult.maOperand1, aConditionNmsp, eGrammar, bHasNmsp ); + SetFormula( rValidation.sFormula2, rValidation.sFormulaNmsp2, rValidation.eGrammar2, + aParseResult.maOperand2, aConditionNmsp, eGrammar, bHasNmsp ); + } + } +} + +void ScXMLContentValidationContext::EndElement() +{ + // #i36650# event-listeners element moved up one level + if (xEventContext.Is()) + { + rtl::OUString sOnError(RTL_CONSTASCII_USTRINGPARAM("OnError")); + XMLEventsImportContext* pEvents = + (XMLEventsImportContext*)&xEventContext; + uno::Sequence<beans::PropertyValue> aValues; + pEvents->GetEventSequence( sOnError, aValues ); + + sal_Int32 nLength = aValues.getLength(); + for( sal_Int32 i = 0; i < nLength; i++ ) + { + // #i47525# must allow "MacroName" or "Script" + if ( aValues[i].Name.equalsAsciiL( "MacroName", sizeof("MacroName")-1 ) || + aValues[i].Name.equalsAsciiL( "Script", sizeof("Script")-1 ) ) + { + aValues[i].Value >>= sErrorTitle; + break; + } + } + } + + ScMyImportValidation aValidation; + aValidation.eGrammar1 = aValidation.eGrammar2 = GetScImport().GetDocument()->GetStorageGrammar(); + aValidation.sName = sName; + aValidation.sBaseCellAddress = sBaseCellAddress; + aValidation.sImputTitle = sHelpTitle; + aValidation.sImputMessage = sHelpMessage; + aValidation.sErrorTitle = sErrorTitle; + aValidation.sErrorMessage = sErrorMessage; + GetCondition( aValidation ); + aValidation.aAlertStyle = GetAlertStyle(); + aValidation.bShowErrorMessage = bDisplayError; + aValidation.bShowImputMessage = bDisplayHelp; + aValidation.bIgnoreBlanks = bAllowEmptyCell; + aValidation.nShowList = nShowList; + GetScImport().AddValidation(aValidation); +} + +void ScXMLContentValidationContext::SetHelpMessage(const rtl::OUString& sTitle, const rtl::OUString& sMessage, const sal_Bool bDisplay) +{ + sHelpTitle = sTitle; + sHelpMessage = sMessage; + bDisplayHelp = bDisplay; +} + +void ScXMLContentValidationContext::SetErrorMessage(const rtl::OUString& sTitle, const rtl::OUString& sMessage, + const rtl::OUString& sMessageType, const sal_Bool bDisplay) +{ + sErrorTitle = sTitle; + sErrorMessage = sMessage; + sErrorMessageType = sMessageType; + bDisplayError = bDisplay; +} + +void ScXMLContentValidationContext::SetErrorMacro(const sal_Bool bExecute) +{ + sErrorMessageType = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("macro")); + bDisplayError = bExecute; +} + +ScXMLHelpMessageContext::ScXMLHelpMessageContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLContentValidationContext* pTempValidationContext) : + SvXMLImportContext( rImport, nPrfx, rLName ), + sTitle(), + sMessage(), + nParagraphCount(0), + bDisplay(sal_False) +{ + pValidationContext = pTempValidationContext; + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetContentValidationHelpMessageAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_HELP_MESSAGE_ATTR_TITLE: + sTitle = sValue; + break; + case XML_TOK_HELP_MESSAGE_ATTR_DISPLAY: + bDisplay = IsXMLToken(sValue, XML_TRUE); + break; + } + } +} + +ScXMLHelpMessageContext::~ScXMLHelpMessageContext() +{ +} + +SvXMLImportContext *ScXMLHelpMessageContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + const SvXMLTokenMap& rTokenMap = GetScImport().GetContentValidationMessageElemTokenMap(); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_P: + { + if(nParagraphCount) + sMessage.append(static_cast<sal_Unicode>('\n')); + ++nParagraphCount; + pContext = new ScXMLContentContext( GetScImport(), nPrefix, rLName, xAttrList, sMessage); + } + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLHelpMessageContext::EndElement() +{ + pValidationContext->SetHelpMessage(sTitle, sMessage.makeStringAndClear(), bDisplay); +} + +ScXMLErrorMessageContext::ScXMLErrorMessageContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLContentValidationContext* pTempValidationContext) : + SvXMLImportContext( rImport, nPrfx, rLName ), + sTitle(), + sMessage(), + sMessageType(), + nParagraphCount(0), + bDisplay(sal_False) +{ + pValidationContext = pTempValidationContext; + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetContentValidationErrorMessageAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_ERROR_MESSAGE_ATTR_TITLE: + sTitle = sValue; + break; + case XML_TOK_ERROR_MESSAGE_ATTR_MESSAGE_TYPE: + sMessageType = sValue; + break; + case XML_TOK_ERROR_MESSAGE_ATTR_DISPLAY: + bDisplay = IsXMLToken(sValue, XML_TRUE); + break; + } + } +} + +ScXMLErrorMessageContext::~ScXMLErrorMessageContext() +{ +} + +SvXMLImportContext *ScXMLErrorMessageContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + const SvXMLTokenMap& rTokenMap = GetScImport().GetContentValidationMessageElemTokenMap(); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_P: + { + if(nParagraphCount) + sMessage.append(static_cast<sal_Unicode>('\n')); + ++nParagraphCount; + pContext = new ScXMLContentContext( GetScImport(), nPrefix, rLName, xAttrList, sMessage); + } + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLErrorMessageContext::EndElement() +{ + pValidationContext->SetErrorMessage(sTitle, sMessage.makeStringAndClear(), sMessageType, bDisplay); +} + +ScXMLErrorMacroContext::ScXMLErrorMacroContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLContentValidationContext* pTempValidationContext) : + SvXMLImportContext( rImport, nPrfx, rLName ), + sName(), + bExecute(sal_False) +{ + pValidationContext = pTempValidationContext; + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetContentValidationErrorMacroAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_ERROR_MACRO_ATTR_NAME: + sName = sValue; + break; + case XML_TOK_ERROR_MACRO_ATTR_EXECUTE: + bExecute = IsXMLToken(sValue, XML_TRUE); + break; + } + } +} + +ScXMLErrorMacroContext::~ScXMLErrorMacroContext() +{ +} + +SvXMLImportContext *ScXMLErrorMacroContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + SvXMLImportContext *pContext = NULL; + + if ((nPrefix == XML_NAMESPACE_SCRIPT) && IsXMLToken(rLName, XML_EVENTS)) + { + pContext = new XMLEventsImportContext(GetImport(), nPrefix, rLName); + } + if (!pContext) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLErrorMacroContext::EndElement() +{ + pValidationContext->SetErrorMacro( bExecute ); +} diff --git a/sc/source/filter/xml/xmlcvali.hxx b/sc/source/filter/xml/xmlcvali.hxx new file mode 100644 index 000000000000..b8d75cf5c7c3 --- /dev/null +++ b/sc/source/filter/xml/xmlcvali.hxx @@ -0,0 +1,61 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef SC_XMLCVALI_HXX +#define SC_XMLCVALI_HXX + +#include <xmloff/xmlictxt.hxx> +#include <xmloff/xmlimp.hxx> +#include <com/sun/star/sheet/ValidationAlertStyle.hpp> +#include <com/sun/star/sheet/ValidationType.hpp> +#include <com/sun/star/sheet/ConditionOperator.hpp> +#include <rtl/ustrbuf.hxx> + +class ScXMLImport; + +class ScXMLContentValidationsContext : public SvXMLImportContext +{ + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLContentValidationsContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList); + + virtual ~ScXMLContentValidationsContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +#endif diff --git a/sc/source/filter/xml/xmldpimp.cxx b/sc/source/filter/xml/xmldpimp.cxx new file mode 100644 index 000000000000..09d8a25fa86d --- /dev/null +++ b/sc/source/filter/xml/xmldpimp.cxx @@ -0,0 +1,1835 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- + +#include "xmldpimp.hxx" +#include "xmlimprt.hxx" +#include "xmlfilti.hxx" +#include "xmlsorti.hxx" +#include "document.hxx" +#include "docuno.hxx" +#include "dpshttab.hxx" +#include "dpsdbtab.hxx" +#include "attrib.hxx" +#include "XMLConverter.hxx" +#include "dpgroup.hxx" +#include "dpdimsave.hxx" +#include "rangeutl.hxx" +#include "dpoutputgeometry.hxx" + +#include <xmloff/xmltkmap.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/xmluconv.hxx> +#include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp> +#include <com/sun/star/sheet/DataPilotFieldReferenceItemType.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> + +//#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp> + +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; + +//------------------------------------------------------------------ + +ScXMLDataPilotTablesContext::ScXMLDataPilotTablesContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) : + SvXMLImportContext( rImport, nPrfx, rLName ) +{ + // has no Attributes + rImport.LockSolarMutex(); +} + +ScXMLDataPilotTablesContext::~ScXMLDataPilotTablesContext() +{ + GetScImport().UnlockSolarMutex(); +} + +SvXMLImportContext *ScXMLDataPilotTablesContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + const SvXMLTokenMap& rTokenMap = GetScImport().GetDataPilotTablesElemTokenMap(); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_DATA_PILOT_TABLE : + { + pContext = new ScXMLDataPilotTableContext( GetScImport(), nPrefix, + rLName, xAttrList); + } + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDataPilotTablesContext::EndElement() +{ +} + +ScXMLDataPilotTableContext::GrandTotalItem::GrandTotalItem() : + mbVisible(true) {} + +ScXMLDataPilotTableContext::ScXMLDataPilotTableContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDoc(GetScImport().GetDocument()), + pDPObject(NULL), + pDPSave(NULL), + pDPDimSaveData(NULL), + sDataPilotTableName(), + sApplicationData(), + sGrandTotal(GetXMLToken(XML_BOTH)), + mnRowFieldCount(0), + mnColFieldCount(0), + mnPageFieldCount(0), + mnDataFieldCount(0), + bIsNative(sal_True), + bIgnoreEmptyRows(sal_False), + bIdentifyCategories(sal_False), + bTargetRangeAddress(sal_False), + bSourceCellRange(sal_False), + bShowFilter(sal_True), + bDrillDown(sal_True) +{ + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotTableAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_DATA_PILOT_TABLE_ATTR_NAME : + { + sDataPilotTableName = sValue; + } + break; + case XML_TOK_DATA_PILOT_TABLE_ATTR_APPLICATION_DATA : + { + sApplicationData = sValue; + } + break; + 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; + maColGrandTotal.mbVisible = false; + } + else if (IsXMLToken(sValue, XML_COLUMN)) + { + maRowGrandTotal.mbVisible = false; + maColGrandTotal.mbVisible = true; + } + else + { + maRowGrandTotal.mbVisible = false; + maColGrandTotal.mbVisible = false; + } + } + break; + case XML_TOK_DATA_PILOT_TABLE_ATTR_IGNORE_EMPTY_ROWS : + { + bIgnoreEmptyRows = IsXMLToken(sValue, XML_TRUE); + } + break; + case XML_TOK_DATA_PILOT_TABLE_ATTR_IDENTIFY_CATEGORIES : + { + bIdentifyCategories = IsXMLToken(sValue, XML_TRUE); + } + break; + case XML_TOK_DATA_PILOT_TABLE_ATTR_TARGET_RANGE_ADDRESS : + { + sal_Int32 nOffset(0); + bTargetRangeAddress = ScRangeStringConverter::GetRangeFromString( aTargetRangeAddress, sValue, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset ); + } + break; + case XML_TOK_DATA_PILOT_TABLE_ATTR_BUTTONS : + { + sButtons = sValue; + } + break; + case XML_TOK_DATA_PILOT_TABLE_ATTR_SHOW_FILTER_BUTTON : + { + bShowFilter = IsXMLToken(sValue, XML_TRUE); + } + break; + case XML_TOK_DATA_PILOT_TABLE_ATTR_DRILL_DOWN : + { + bDrillDown = IsXMLToken(sValue, XML_TRUE); + } + break; + } + } + + pDPObject = new ScDPObject(pDoc); + pDPSave = new ScDPSaveData(); +} + +ScXMLDataPilotTableContext::~ScXMLDataPilotTableContext() +{ + delete pDPDimSaveData; +} + +SvXMLImportContext *ScXMLDataPilotTableContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + const SvXMLTokenMap& rTokenMap = GetScImport().GetDataPilotTableElemTokenMap(); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SQL : + { + pContext = new ScXMLDPSourceSQLContext(GetScImport(), nPrefix, rLName, xAttrList, this); + nSourceType = SQL; + } + break; + case XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_TABLE : + { + pContext = new ScXMLDPSourceTableContext(GetScImport(), nPrefix, rLName, xAttrList, this); + nSourceType = TABLE; + } + break; + case XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_QUERY : + { + pContext = new ScXMLDPSourceQueryContext(GetScImport(), nPrefix, rLName, xAttrList, this); + nSourceType = QUERY; + } + break; + case XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SERVICE : + { + pContext = new ScXMLSourceServiceContext(GetScImport(), nPrefix, rLName, xAttrList, this); + 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); + nSourceType = CELLRANGE; + } + break; + case XML_TOK_DATA_PILOT_TABLE_ELEM_DATA_PILOT_FIELD : + pContext = new ScXMLDataPilotFieldContext(GetScImport(), nPrefix, rLName, xAttrList, this); + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDataPilotTableContext::SetButtons() +{ + ScDPOutputGeometry aGeometry(aTargetRangeAddress, bShowFilter, ScDPOutputGeometry::ODF); + aGeometry.setColumnFieldCount(mnColFieldCount); + aGeometry.setRowFieldCount(mnRowFieldCount); + aGeometry.setPageFieldCount(mnPageFieldCount); + aGeometry.setDataFieldCount(mnDataFieldCount); + + OUString sAddress; + sal_Int32 nOffset = 0; + while( nOffset >= 0 ) + { + ScRangeStringConverter::GetTokenByOffset( sAddress, sButtons, nOffset ); + if( nOffset >= 0 ) + { + ScAddress aScAddress; + sal_Int32 nAddrOffset(0); + if (pDoc && ScRangeStringConverter::GetAddressFromString( aScAddress, sAddress, pDoc, ::formula::FormulaGrammar::CONV_OOO, nAddrOffset )) + { + ScDPOutputGeometry::FieldType eType = aGeometry.getFieldButtonType(aScAddress); + + sal_Int16 nMFlag = SC_MF_BUTTON; + if (eType == ScDPOutputGeometry::Column || eType == ScDPOutputGeometry::Row) + nMFlag |= SC_MF_BUTTON_POPUP; + + // Use the cell's string value to see if this field contains a + // hidden member. Isn't there a better way? GetString() is + // quite expensive... + String aCellStr; + pDoc->GetString(aScAddress.Col(), aScAddress.Row(), aScAddress.Tab(), aCellStr); + if (maHiddenMemberFields.count(aCellStr)) + nMFlag |= SC_MF_HIDDEN_MEMBER; + + pDoc->ApplyFlagsTab(aScAddress.Col(), aScAddress.Row(), aScAddress.Col(), aScAddress.Row(), aScAddress.Tab(), nMFlag); + } + } + } + + if ( pDPObject ) + pDPObject->RefreshAfterLoad(); +} + +void ScXMLDataPilotTableContext::AddDimension(ScDPSaveDimension* pDim, bool bHasHiddenMember) +{ + if (pDPSave) + { + // #91045# if a dimension with that name has already been inserted, + // mark the new one as duplicate + if ( !pDim->IsDataLayout() && + pDPSave->GetExistingDimensionByName(pDim->GetName()) ) + pDim->SetDupFlag( sal_True ); + + if (!pDim->IsDataLayout()) + { + switch (pDim->GetOrientation()) + { + case sheet::DataPilotFieldOrientation_ROW: + ++mnRowFieldCount; + break; + case sheet::DataPilotFieldOrientation_COLUMN: + ++mnColFieldCount; + break; + case sheet::DataPilotFieldOrientation_PAGE: + ++mnPageFieldCount; + break; + case sheet::DataPilotFieldOrientation_DATA: + ++mnDataFieldCount; + break; + case sheet::DataPilotFieldOrientation_HIDDEN: + default: + ; + } + + if (bHasHiddenMember) + { + // the layout name takes priority over the original name, + // since this data is used against cell values. + const OUString* pLayoutName = pDim->GetLayoutName(); + if (pLayoutName) + maHiddenMemberFields.insert(*pLayoutName); + else + maHiddenMemberFields.insert(pDim->GetName()); + } + } + pDPSave->AddDimension(pDim); + } +} + +void ScXMLDataPilotTableContext::AddGroupDim(const ScDPSaveNumGroupDimension& aNumGroupDim) +{ + if (!pDPDimSaveData) + pDPDimSaveData = new ScDPDimensionSaveData(); + pDPDimSaveData->AddNumGroupDimension(aNumGroupDim); +} + +void ScXMLDataPilotTableContext::AddGroupDim(const ScDPSaveGroupDimension& aGroupDim) +{ + if (!pDPDimSaveData) + pDPDimSaveData = new ScDPDimensionSaveData(); + pDPDimSaveData->AddGroupDimension(aGroupDim); +} + +void ScXMLDataPilotTableContext::EndElement() +{ + if (bTargetRangeAddress) + { + pDPObject->SetName(sDataPilotTableName); + pDPObject->SetTag(sApplicationData); + pDPObject->SetOutRange(aTargetRangeAddress); + switch (nSourceType) + { + case SQL : + { + ScImportSourceDesc aImportDesc; + aImportDesc.aDBName = sDatabaseName; + aImportDesc.aObject = sSourceObject; + aImportDesc.nType = sheet::DataImportMode_SQL; + aImportDesc.bNative = bIsNative; + pDPObject->SetImportDesc(aImportDesc); + } + break; + case TABLE : + { + ScImportSourceDesc aImportDesc; + aImportDesc.aDBName = sDatabaseName; + aImportDesc.aObject = sSourceObject; + aImportDesc.nType = sheet::DataImportMode_TABLE; + pDPObject->SetImportDesc(aImportDesc); + } + break; + case QUERY : + { + ScImportSourceDesc aImportDesc; + aImportDesc.aDBName = sDatabaseName; + aImportDesc.aObject = sSourceObject; + aImportDesc.nType = sheet::DataImportMode_QUERY; + pDPObject->SetImportDesc(aImportDesc); + } + break; + case SERVICE : + { + ScDPServiceDesc aServiceDesk(sServiceName, sServiceSourceName, sServiceSourceObject, + sServiceUsername, sServicePassword); + pDPObject->SetServiceData(aServiceDesk); + } + break; + case CELLRANGE : + { + if (bSourceCellRange) + { + ScSheetSourceDesc aSheetDesc; + aSheetDesc.aSourceRange = aSourceCellRangeAddress; + aSheetDesc.aQueryParam = aSourceQueryParam; + pDPObject->SetSheetDesc(aSheetDesc); + } + } + break; + } + + 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); + pDPSave->SetDrillDown(bDrillDown); + if (pDPDimSaveData) + pDPSave->SetDimensionData(pDPDimSaveData); + pDPObject->SetSaveData(*pDPSave); + if (pDoc) + { + ScDPCollection* pDPCollection = pDoc->GetDPCollection(); + + // #i94570# Names have to be unique, or the tables can't be accessed by API. + if ( pDPCollection->GetByName(pDPObject->GetName()) ) + pDPObject->SetName( String() ); // ignore the invalid name, create a new name in AfterXMLLoading + + pDPObject->SetAlive(sal_True); + pDPCollection->InsertNewTable(pDPObject); + } + SetButtons(); + } +} + +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, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotTableContext* pTempDataPilotTable) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDataPilotTable(pTempDataPilotTable) +{ + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDatabaseRangeSourceSQLAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_SOURCE_SQL_ATTR_DATABASE_NAME : + { + pDataPilotTable->SetDatabaseName(sValue); + } + break; + case XML_TOK_SOURCE_SQL_ATTR_SQL_STATEMENT : + { + pDataPilotTable->SetSourceObject(sValue); + } + break; + case XML_TOK_SOURCE_SQL_ATTR_PARSE_SQL_STATEMENT : + { + pDataPilotTable->SetNative(!IsXMLToken(sValue, XML_TRUE)); + } + break; + } + } +} + +ScXMLDPSourceSQLContext::~ScXMLDPSourceSQLContext() +{ +} + +SvXMLImportContext *ScXMLDPSourceSQLContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + SvXMLImportContext *pContext = 0; + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDPSourceSQLContext::EndElement() +{ +} + +ScXMLDPSourceTableContext::ScXMLDPSourceTableContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotTableContext* pTempDataPilotTable) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDataPilotTable(pTempDataPilotTable) +{ + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDatabaseRangeSourceTableAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_SOURCE_TABLE_ATTR_DATABASE_NAME : + { + pDataPilotTable->SetDatabaseName(sValue); + } + break; + case XML_TOK_SOURCE_TABLE_ATTR_TABLE_NAME : + { + pDataPilotTable->SetSourceObject(sValue); + } + break; + } + } +} + +ScXMLDPSourceTableContext::~ScXMLDPSourceTableContext() +{ +} + +SvXMLImportContext *ScXMLDPSourceTableContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + SvXMLImportContext *pContext = 0; + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDPSourceTableContext::EndElement() +{ +} + +ScXMLDPSourceQueryContext::ScXMLDPSourceQueryContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotTableContext* pTempDataPilotTable) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDataPilotTable(pTempDataPilotTable) +{ + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDatabaseRangeSourceQueryAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_SOURCE_QUERY_ATTR_DATABASE_NAME : + { + pDataPilotTable->SetDatabaseName(sValue); + } + break; + case XML_TOK_SOURCE_QUERY_ATTR_QUERY_NAME : + { + pDataPilotTable->SetSourceObject(sValue); + } + break; + } + } +} + +ScXMLDPSourceQueryContext::~ScXMLDPSourceQueryContext() +{ +} + +SvXMLImportContext *ScXMLDPSourceQueryContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + SvXMLImportContext *pContext = 0; + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDPSourceQueryContext::EndElement() +{ +} + +ScXMLSourceServiceContext::ScXMLSourceServiceContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotTableContext* pTempDataPilotTable) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDataPilotTable(pTempDataPilotTable) +{ + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotTableSourceServiceAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_SOURCE_SERVICE_ATTR_NAME : + { + pDataPilotTable->SetServiceName(sValue); + } + break; + case XML_TOK_SOURCE_SERVICE_ATTR_SOURCE_NAME : + { + pDataPilotTable->SetServiceSourceName(sValue); + } + break; + case XML_TOK_SOURCE_SERVICE_ATTR_OBJECT_NAME : + { + pDataPilotTable->SetServiceSourceObject(sValue); + } + break; + case XML_TOK_SOURCE_SERVICE_ATTR_USER_NAME : + { + pDataPilotTable->SetServiceUsername(sValue); + } + break; + case XML_TOK_SOURCE_SERVICE_ATTR_PASSWORD : + { + pDataPilotTable->SetServicePassword(sValue); + } + break; + } + } +} + +ScXMLSourceServiceContext::~ScXMLSourceServiceContext() +{ +} + +SvXMLImportContext *ScXMLSourceServiceContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + SvXMLImportContext *pContext = 0; + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLSourceServiceContext::EndElement() +{ +} + +ScXMLImport& ScXMLDataPilotGrandTotalContext::GetScImport() +{ + return static_cast<ScXMLImport&>(GetImport()); +} + +ScXMLDataPilotGrandTotalContext::ScXMLDataPilotGrandTotalContext( + ScXMLImport& rImport, sal_uInt16 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; + sal_uInt16 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: + case XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME_EXT: + maDisplayName = rAttrValue; + break; + default: + ; + } + } +} + +ScXMLDataPilotGrandTotalContext::~ScXMLDataPilotGrandTotalContext() +{ +} + +SvXMLImportContext* ScXMLDataPilotGrandTotalContext::CreateChildContext( + sal_uInt16 /*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, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotTableContext* pTempDataPilotTable) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDataPilotTable(pTempDataPilotTable) +{ + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotTableSourceCellRangeAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_SOURCE_CELL_RANGE_ATTR_CELL_RANGE_ADDRESS : + { + ScRange aSourceRangeAddress; + sal_Int32 nOffset(0); + if (ScRangeStringConverter::GetRangeFromString( aSourceRangeAddress, sValue, GetScImport().GetDocument(), ::formula::FormulaGrammar::CONV_OOO, nOffset )) + pDataPilotTable->SetSourceCellRangeAddress(aSourceRangeAddress); + } + break; + } + } +} + +ScXMLSourceCellRangeContext::~ScXMLSourceCellRangeContext() +{ +} + +SvXMLImportContext *ScXMLSourceCellRangeContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + const SvXMLTokenMap& rTokenMap = GetScImport().GetDataPilotTableSourceCellRangeElemTokenMap(); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_SOURCE_CELL_RANGE_ELEM_FILTER : + pContext = new ScXMLDPFilterContext(GetScImport(), nPrefix, rLName, xAttrList, pDataPilotTable); + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLSourceCellRangeContext::EndElement() +{ +} + +ScXMLDataPilotFieldContext::ScXMLDataPilotFieldContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotTableContext* pTempDataPilotTable) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDataPilotTable(pTempDataPilotTable), + pDim(NULL), + fStart(0.0), + fEnd(0.0), + fStep(0.0), + nUsedHierarchy(1), + nGroupPart(0), + bSelectedPage(sal_False), + bIsGroupField(sal_False), + bDateValue(sal_False), + bAutoStart(sal_False), + bAutoEnd(sal_False), + mbHasHiddenMember(false) +{ + 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 ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_DATA_PILOT_FIELD_ATTR_SOURCE_FIELD_NAME : + { + sName = sValue; + bHasName = sal_True; + } + break; + case XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME: + case XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME_EXT: + { + aDisplayName = sValue; + } + break; + case XML_TOK_DATA_PILOT_FIELD_ATTR_IS_DATA_LAYOUT_FIELD : + { + bDataLayout = IsXMLToken(sValue, XML_TRUE); + } + break; + case XML_TOK_DATA_PILOT_FIELD_ATTR_FUNCTION : + { + nFunction = (sal_Int16) ScXMLConverter::GetFunctionFromString( sValue ); + } + break; + case XML_TOK_DATA_PILOT_FIELD_ATTR_ORIENTATION : + { + nOrientation = (sal_Int16) ScXMLConverter::GetOrientationFromString( sValue ); + } + break; + case XML_TOK_DATA_PILOT_FIELD_ATTR_SELECTED_PAGE : + { + sSelectedPage = sValue; + bSelectedPage = sal_True; + } + break; + case XML_TOK_DATA_PILOT_FIELD_ATTR_USED_HIERARCHY : + { + nUsedHierarchy = sValue.toInt32(); + } + break; + } + } + if (bHasName) + { + pDim = new ScDPSaveDimension(String(sName), bDataLayout); + if (aDisplayName.getLength()) + pDim->SetLayoutName(aDisplayName); + } +} + +ScXMLDataPilotFieldContext::~ScXMLDataPilotFieldContext() +{ +} + +SvXMLImportContext *ScXMLDataPilotFieldContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + const SvXMLTokenMap& rTokenMap = GetScImport().GetDataPilotFieldElemTokenMap(); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_LEVEL : + pContext = new ScXMLDataPilotLevelContext(GetScImport(), nPrefix, rLName, xAttrList, this); + break; + case XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_REFERENCE : + pContext = new ScXMLDataPilotFieldReferenceContext(GetScImport(), nPrefix, rLName, xAttrList, this); + break; + case XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_GROUPS : + pContext = new ScXMLDataPilotGroupsContext(GetScImport(), nPrefix, rLName, xAttrList, this); + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDataPilotFieldContext::AddMember(ScDPSaveMember* pMember) +{ + if (pDim) + pDim->AddMember(pMember); + + if (!pMember->GetIsVisible()) + // This member is hidden. + mbHasHiddenMember = true; +} + +void ScXMLDataPilotFieldContext::SetSubTotalName(const OUString& rName) +{ + if (pDim) + pDim->SetSubtotalName(rName); +} + +void ScXMLDataPilotFieldContext::AddGroup(const ::std::vector<rtl::OUString>& rMembers, const rtl::OUString& rName) +{ + ScXMLDataPilotGroup aGroup; + aGroup.aMembers = rMembers; + aGroup.aName = rName; + aGroups.push_back(aGroup); +} + +void ScXMLDataPilotFieldContext::EndElement() +{ + if (pDim) + { + pDim->SetUsedHierarchy(nUsedHierarchy); + pDim->SetFunction(nFunction); + pDim->SetOrientation(nOrientation); + if (bSelectedPage) + { + String sPage(sSelectedPage); + pDim->SetCurrentPage(&sPage); + } + pDataPilotTable->AddDimension(pDim, mbHasHiddenMember); + if (bIsGroupField) + { + ScDPNumGroupInfo aInfo; + aInfo.Enable = sal_True; + aInfo.DateValues = bDateValue; + aInfo.AutoStart = bAutoStart; + aInfo.AutoEnd = bAutoEnd; + aInfo.Start = fStart; + aInfo.End = fEnd; + aInfo.Step = fStep; + if (sGroupSource.getLength()) + { + ScDPSaveGroupDimension aGroupDim(sGroupSource, sName); + if (nGroupPart) + aGroupDim.SetDateInfo(aInfo, nGroupPart); + else + { + ::std::vector<ScXMLDataPilotGroup>::const_iterator aItr(aGroups.begin()); + ::std::vector<ScXMLDataPilotGroup>::const_iterator aEndItr(aGroups.end()); + while (aItr != aEndItr) + { + ScDPSaveGroupItem aItem(aItr->aName); + ::std::vector<rtl::OUString>::const_iterator aMembersItr(aItr->aMembers.begin()); + ::std::vector<rtl::OUString>::const_iterator aMembersEndItr(aItr->aMembers.end()); + while (aMembersItr != aMembersEndItr) + { + aItem.AddElement(*aMembersItr); + ++aMembersItr; + } + ++aItr; + aGroupDim.AddGroupItem(aItem); + } + } + pDataPilotTable->AddGroupDim(aGroupDim); + } + else //NumGroup + { + ScDPSaveNumGroupDimension aNumGroupDim(sName, aInfo); + if (nGroupPart) + aNumGroupDim.SetDateInfo(aInfo, nGroupPart); + pDataPilotTable->AddGroupDim(aNumGroupDim); + } + } + } +} + +ScXMLDataPilotFieldReferenceContext::ScXMLDataPilotFieldReferenceContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotFieldContext* pDataPilotField) : + SvXMLImportContext( rImport, nPrfx, rLName ) +{ + sheet::DataPilotFieldReference aReference; + + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + for( sal_Int16 i=0; i < nAttrCount; i++ ) + { + rtl::OUString sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + rtl::OUString sValue(xAttrList->getValueByIndex( i )); + + if ( nPrefix == XML_NAMESPACE_TABLE ) + { + if (IsXMLToken(aLocalName, XML_TYPE)) + { + if (IsXMLToken(sValue, XML_NONE)) + aReference.ReferenceType = sheet::DataPilotFieldReferenceType::NONE; + else if (IsXMLToken(sValue, XML_MEMBER_DIFFERENCE)) + aReference.ReferenceType = sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE; + else if (IsXMLToken(sValue, XML_MEMBER_PERCENTAGE)) + aReference.ReferenceType = sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE; + else if (IsXMLToken(sValue, XML_MEMBER_PERCENTAGE_DIFFERENCE)) + aReference.ReferenceType = sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE; + else if (IsXMLToken(sValue, XML_RUNNING_TOTAL)) + aReference.ReferenceType = sheet::DataPilotFieldReferenceType::RUNNING_TOTAL; + else if (IsXMLToken(sValue, XML_ROW_PERCENTAGE)) + aReference.ReferenceType = sheet::DataPilotFieldReferenceType::ROW_PERCENTAGE; + else if (IsXMLToken(sValue, XML_COLUMN_PERCENTAGE)) + aReference.ReferenceType = sheet::DataPilotFieldReferenceType::COLUMN_PERCENTAGE; + else if (IsXMLToken(sValue, XML_TOTAL_PERCENTAGE)) + aReference.ReferenceType = sheet::DataPilotFieldReferenceType::TOTAL_PERCENTAGE; + else if (IsXMLToken(sValue, XML_INDEX)) + aReference.ReferenceType = sheet::DataPilotFieldReferenceType::INDEX; + } + else if (IsXMLToken(aLocalName, XML_FIELD_NAME)) + { + aReference.ReferenceField = sValue; + } + else if (IsXMLToken(aLocalName, XML_MEMBER_TYPE)) + { + if (IsXMLToken(sValue, XML_NAMED)) + aReference.ReferenceItemType = sheet::DataPilotFieldReferenceItemType::NAMED; + else if (IsXMLToken(sValue, XML_PREVIOUS)) + aReference.ReferenceItemType = sheet::DataPilotFieldReferenceItemType::PREVIOUS; + else if (IsXMLToken(sValue, XML_NEXT)) + aReference.ReferenceItemType = sheet::DataPilotFieldReferenceItemType::NEXT; + } + else if (IsXMLToken(aLocalName, XML_MEMBER_NAME)) + { + aReference.ReferenceItemName = sValue; + } + } + } + pDataPilotField->SetFieldReference(aReference); +} + +ScXMLDataPilotFieldReferenceContext::~ScXMLDataPilotFieldReferenceContext() +{ +} + +ScXMLDataPilotLevelContext::ScXMLDataPilotLevelContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotFieldContext* pTempDataPilotField) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDataPilotField(pTempDataPilotField) +{ + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotLevelAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_DATA_PILOT_LEVEL_ATTR_SHOW_EMPTY : + { + pDataPilotField->SetShowEmpty(IsXMLToken(sValue, XML_TRUE)); + } + break; + } + } +} + +ScXMLDataPilotLevelContext::~ScXMLDataPilotLevelContext() +{ +} + +SvXMLImportContext *ScXMLDataPilotLevelContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + const SvXMLTokenMap& rTokenMap = GetScImport().GetDataPilotLevelElemTokenMap(); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_DATA_PILOT_LEVEL_ELEM_DATA_PILOT_SUBTOTALS : + pContext = new ScXMLDataPilotSubTotalsContext(GetScImport(), nPrefix, rLName, xAttrList, pDataPilotField); + break; + case XML_TOK_DATA_PILOT_LEVEL_ELEM_DATA_PILOT_MEMBERS : + pContext = new ScXMLDataPilotMembersContext(GetScImport(), nPrefix, rLName, xAttrList, pDataPilotField); + break; + case XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_DISPLAY_INFO : + pContext = new ScXMLDataPilotDisplayInfoContext(GetScImport(), nPrefix, rLName, xAttrList, pDataPilotField); + break; + case XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_SORT_INFO : + pContext = new ScXMLDataPilotSortInfoContext(GetScImport(), nPrefix, rLName, xAttrList, pDataPilotField); + break; + case XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_LAYOUT_INFO : + pContext = new ScXMLDataPilotLayoutInfoContext(GetScImport(), nPrefix, rLName, xAttrList, pDataPilotField); + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDataPilotLevelContext::EndElement() +{ +} + +ScXMLDataPilotDisplayInfoContext::ScXMLDataPilotDisplayInfoContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotFieldContext* pDataPilotField) : + SvXMLImportContext( rImport, nPrfx, rLName ) +{ + sheet::DataPilotFieldAutoShowInfo aInfo; + + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + for( sal_Int16 i=0; i < nAttrCount; i++ ) + { + rtl::OUString sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + rtl::OUString sValue(xAttrList->getValueByIndex( i )); + + if ( nPrefix == XML_NAMESPACE_TABLE ) + { + if (IsXMLToken(aLocalName, XML_ENABLED)) + { + if (IsXMLToken(sValue, XML_TRUE)) + aInfo.IsEnabled = sal_True; + else + aInfo.IsEnabled = sal_False; + } + else if (IsXMLToken(aLocalName, XML_DISPLAY_MEMBER_MODE)) + { + if (IsXMLToken(sValue, XML_FROM_TOP)) + aInfo.ShowItemsMode = sheet::DataPilotFieldShowItemsMode::FROM_TOP; + else if (IsXMLToken(sValue, XML_FROM_BOTTOM)) + aInfo.ShowItemsMode = sheet::DataPilotFieldShowItemsMode::FROM_BOTTOM; + } + else if (IsXMLToken(aLocalName, XML_MEMBER_COUNT)) + { + aInfo.ItemCount = sValue.toInt32(); + } + else if (IsXMLToken(aLocalName, XML_DATA_FIELD)) + { + aInfo.DataField = sValue; + } + } + } + pDataPilotField->SetAutoShowInfo(aInfo); +} + +ScXMLDataPilotDisplayInfoContext::~ScXMLDataPilotDisplayInfoContext() +{ +} + +ScXMLDataPilotSortInfoContext::ScXMLDataPilotSortInfoContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotFieldContext* pDataPilotField) : + SvXMLImportContext( rImport, nPrfx, rLName ) +{ + sheet::DataPilotFieldSortInfo aInfo; + + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + for( sal_Int16 i=0; i < nAttrCount; i++ ) + { + rtl::OUString sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + rtl::OUString sValue(xAttrList->getValueByIndex( i )); + + if ( nPrefix == XML_NAMESPACE_TABLE ) + { + if (IsXMLToken(aLocalName, XML_ORDER)) + { + if (IsXMLToken(sValue, XML_ASCENDING)) + aInfo.IsAscending = sal_True; + else if (IsXMLToken(sValue, XML_DESCENDING)) + aInfo.IsAscending = sal_False; + } + else if (IsXMLToken(aLocalName, XML_SORT_MODE)) + { + if (IsXMLToken(sValue, XML_NONE)) + aInfo.Mode = sheet::DataPilotFieldSortMode::NONE; + else if (IsXMLToken(sValue, XML_MANUAL)) + aInfo.Mode = sheet::DataPilotFieldSortMode::MANUAL; + else if (IsXMLToken(sValue, XML_NAME)) + aInfo.Mode = sheet::DataPilotFieldSortMode::NAME; + else if (IsXMLToken(sValue, XML_DATA)) + aInfo.Mode = sheet::DataPilotFieldSortMode::DATA; + } + else if (IsXMLToken(aLocalName, XML_DATA_FIELD)) + aInfo.Field = sValue; + } + } + pDataPilotField->SetSortInfo(aInfo); +} + +ScXMLDataPilotSortInfoContext::~ScXMLDataPilotSortInfoContext() +{ +} + +ScXMLDataPilotLayoutInfoContext::ScXMLDataPilotLayoutInfoContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotFieldContext* pDataPilotField) : + SvXMLImportContext( rImport, nPrfx, rLName ) +{ + sheet::DataPilotFieldLayoutInfo aInfo; + + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + for( sal_Int16 i=0; i < nAttrCount; i++ ) + { + rtl::OUString sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + rtl::OUString sValue(xAttrList->getValueByIndex( i )); + + if ( nPrefix == XML_NAMESPACE_TABLE ) + { + if (IsXMLToken(aLocalName, XML_ADD_EMPTY_LINES)) + { + if (IsXMLToken(sValue, XML_TRUE)) + aInfo.AddEmptyLines = sal_True; + else + aInfo.AddEmptyLines = sal_False; + } + else if (IsXMLToken(aLocalName, XML_LAYOUT_MODE)) + { + if (IsXMLToken(sValue, XML_TABULAR_LAYOUT)) + aInfo.LayoutMode = sheet::DataPilotFieldLayoutMode::TABULAR_LAYOUT; + else if (IsXMLToken(sValue, XML_OUTLINE_SUBTOTALS_TOP)) + aInfo.LayoutMode = sheet::DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP; + else if (IsXMLToken(sValue, XML_OUTLINE_SUBTOTALS_BOTTOM)) + aInfo.LayoutMode = sheet::DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM; + } + } + } + pDataPilotField->SetLayoutInfo(aInfo);} + +ScXMLDataPilotLayoutInfoContext::~ScXMLDataPilotLayoutInfoContext() +{ +} + +ScXMLDataPilotSubTotalsContext::ScXMLDataPilotSubTotalsContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */, + ScXMLDataPilotFieldContext* pTempDataPilotField) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDataPilotField(pTempDataPilotField), + nFunctionCount(0), + pFunctions(NULL) +{ + + // has no attributes +} + +ScXMLDataPilotSubTotalsContext::~ScXMLDataPilotSubTotalsContext() +{ +} + +SvXMLImportContext *ScXMLDataPilotSubTotalsContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + const SvXMLTokenMap& rTokenMap = GetScImport().GetDataPilotSubTotalsElemTokenMap(); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_DATA_PILOT_SUBTOTALS_ELEM_DATA_PILOT_SUBTOTAL : + pContext = new ScXMLDataPilotSubTotalContext(GetScImport(), nPrefix, rLName, xAttrList, this); + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDataPilotSubTotalsContext::EndElement() +{ + pDataPilotField->SetSubTotals(pFunctions, nFunctionCount); + if (maDisplayName.getLength()) + pDataPilotField->SetSubTotalName(maDisplayName); +} + +void ScXMLDataPilotSubTotalsContext::AddFunction(sal_Int16 nFunction) +{ + if (nFunctionCount) + { + ++nFunctionCount; + sal_uInt16* pTemp = new sal_uInt16[nFunctionCount]; + for (sal_Int16 i = 0; i < nFunctionCount - 1; ++i) + pTemp[i] = pFunctions[i]; + pTemp[nFunctionCount - 1] = nFunction; + delete[] pFunctions; + pFunctions = pTemp; + } + else + { + nFunctionCount = 1; + pFunctions = new sal_uInt16[nFunctionCount]; + pFunctions[0] = nFunction; + } +} + +void ScXMLDataPilotSubTotalsContext::SetDisplayName(const OUString& rName) +{ + maDisplayName = rName; +} + +ScXMLDataPilotSubTotalContext::ScXMLDataPilotSubTotalContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotSubTotalsContext* pTempDataPilotSubTotals) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDataPilotSubTotals(pTempDataPilotSubTotals) +{ + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotSubTotalAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_FUNCTION : + { + pDataPilotSubTotals->AddFunction( sal::static_int_cast<sal_Int16>( + ScXMLConverter::GetFunctionFromString( sValue ) ) ); + } + break; + case XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME: + case XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME_EXT: + pDataPilotSubTotals->SetDisplayName(sValue); + break; + } + } +} + +ScXMLDataPilotSubTotalContext::~ScXMLDataPilotSubTotalContext() +{ +} + +SvXMLImportContext *ScXMLDataPilotSubTotalContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + SvXMLImportContext *pContext = 0; + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDataPilotSubTotalContext::EndElement() +{ +} + +ScXMLDataPilotMembersContext::ScXMLDataPilotMembersContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */, + ScXMLDataPilotFieldContext* pTempDataPilotField) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDataPilotField(pTempDataPilotField) +{ + // has no attributes +} + +ScXMLDataPilotMembersContext::~ScXMLDataPilotMembersContext() +{ +} + +SvXMLImportContext *ScXMLDataPilotMembersContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + const SvXMLTokenMap& rTokenMap = GetScImport().GetDataPilotMembersElemTokenMap(); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_DATA_PILOT_MEMBERS_ELEM_DATA_PILOT_MEMBER : + pContext = new ScXMLDataPilotMemberContext(GetScImport(), nPrefix, rLName, xAttrList, pDataPilotField); + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDataPilotMembersContext::EndElement() +{ +} + +ScXMLDataPilotMemberContext::ScXMLDataPilotMemberContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotFieldContext* pTempDataPilotField) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDataPilotField(pTempDataPilotField), + bDisplay( sal_True ), + bDisplayDetails( sal_True ), + bHasName( sal_False ) +{ + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotMemberAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_DATA_PILOT_MEMBER_ATTR_NAME : + { + sName = sValue; + bHasName = sal_True; + } + break; + case XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME: + case XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME_EXT: + { + maDisplayName = sValue; + } + case XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY : + { + bDisplay = IsXMLToken(sValue, XML_TRUE); + } + break; + case XML_TOK_DATA_PILOT_MEMBER_ATTR_SHOW_DETAILS : + { + bDisplayDetails = IsXMLToken(sValue, XML_TRUE); + } + break; + } + } +} + +ScXMLDataPilotMemberContext::~ScXMLDataPilotMemberContext() +{ +} + +SvXMLImportContext *ScXMLDataPilotMemberContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + SvXMLImportContext *pContext = 0; + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +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); + } +} + +ScXMLDataPilotGroupsContext::ScXMLDataPilotGroupsContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotFieldContext* pTempDataPilotField) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDataPilotField(pTempDataPilotField) +{ + rtl::OUString sGroupSource; + double fStart(0.0); + double fEnd(0.0); + double fStep(0.0); + sal_Int32 nGroupPart(0); + sal_Bool bDateValue(sal_False); + sal_Bool bAutoStart(sal_True); + sal_Bool bAutoEnd(sal_True); + + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + for( sal_Int16 i=0; i < nAttrCount; i++ ) + { + rtl::OUString sAttrName = xAttrList->getNameByIndex( i ); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + rtl::OUString sValue = xAttrList->getValueByIndex( i ); + + (void)nPrefix; //! compare below! + + if (IsXMLToken(aLocalName, XML_SOURCE_FIELD_NAME)) + sGroupSource = sValue; + else if (IsXMLToken(aLocalName, XML_DATE_START)) + { + bDateValue = sal_True; + if (IsXMLToken(sValue, XML_AUTO)) + bAutoStart = sal_True; + else + { + GetScImport().GetMM100UnitConverter().convertDateTime(fStart, sValue); + bAutoStart = sal_False; + } + } + else if (IsXMLToken(aLocalName, XML_DATE_END)) + { + bDateValue = sal_True; + if (IsXMLToken(sValue, XML_AUTO)) + bAutoEnd = sal_True; + else + { + GetScImport().GetMM100UnitConverter().convertDateTime(fEnd, sValue); + bAutoEnd = sal_False; + } + } + else if (IsXMLToken(aLocalName, XML_START)) + { + if (IsXMLToken(sValue, XML_AUTO)) + bAutoStart = sal_True; + else + { + GetScImport().GetMM100UnitConverter().convertDouble(fStart, sValue); + bAutoStart = sal_False; + } + } + else if (IsXMLToken(aLocalName, XML_END)) + { + if (IsXMLToken(sValue, XML_AUTO)) + bAutoEnd = sal_True; + else + { + GetScImport().GetMM100UnitConverter().convertDouble(fEnd, sValue); + bAutoEnd = sal_False; + } + } + else if (IsXMLToken(aLocalName, XML_STEP)) + GetScImport().GetMM100UnitConverter().convertDouble(fStep, sValue); + else if (IsXMLToken(aLocalName, XML_GROUPED_BY)) + { + if (IsXMLToken(sValue, XML_SECONDS)) + nGroupPart = com::sun::star::sheet::DataPilotFieldGroupBy::SECONDS; + else if (IsXMLToken(sValue, XML_MINUTES)) + nGroupPart = com::sun::star::sheet::DataPilotFieldGroupBy::MINUTES; + else if (IsXMLToken(sValue, XML_HOURS)) + nGroupPart = com::sun::star::sheet::DataPilotFieldGroupBy::HOURS; + else if (IsXMLToken(sValue, XML_DAYS)) + nGroupPart = com::sun::star::sheet::DataPilotFieldGroupBy::DAYS; + else if (IsXMLToken(sValue, XML_MONTHS)) + nGroupPart = com::sun::star::sheet::DataPilotFieldGroupBy::MONTHS; + else if (IsXMLToken(sValue, XML_QUARTERS)) + nGroupPart = com::sun::star::sheet::DataPilotFieldGroupBy::QUARTERS; + else if (IsXMLToken(sValue, XML_YEARS)) + nGroupPart = com::sun::star::sheet::DataPilotFieldGroupBy::YEARS; + } + } + pDataPilotField->SetGrouping(sGroupSource, fStart, fEnd, fStep, nGroupPart, bDateValue, bAutoStart, bAutoEnd); +} + +ScXMLDataPilotGroupsContext::~ScXMLDataPilotGroupsContext() +{ +} + +SvXMLImportContext *ScXMLDataPilotGroupsContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(rLName, XML_DATA_PILOT_GROUP)) + pContext = new ScXMLDataPilotGroupContext(GetScImport(), nPrefix, rLName, xAttrList, pDataPilotField); + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDataPilotGroupsContext::EndElement() +{ +} + +ScXMLDataPilotGroupContext::ScXMLDataPilotGroupContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotFieldContext* pTempDataPilotField) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDataPilotField(pTempDataPilotField) +{ + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + for( sal_Int16 i=0; i < nAttrCount; i++ ) + { + rtl::OUString sAttrName = xAttrList->getNameByIndex( i ); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + rtl::OUString sValue = xAttrList->getValueByIndex( i ); + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(aLocalName, XML_NAME)) + sName = sValue; + } + } +} + +ScXMLDataPilotGroupContext::~ScXMLDataPilotGroupContext() +{ +} + +SvXMLImportContext *ScXMLDataPilotGroupContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(rLName, XML_DATA_PILOT_MEMBER)) + pContext = new ScXMLDataPilotGroupMemberContext(GetScImport(), nPrefix, rLName, xAttrList, this); + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDataPilotGroupContext::EndElement() +{ + pDataPilotField->AddGroup(aMembers, sName); +} + +ScXMLDataPilotGroupMemberContext::ScXMLDataPilotGroupMemberContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotGroupContext* pTempDataPilotGroup) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDataPilotGroup(pTempDataPilotGroup) +{ + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + for( sal_Int16 i=0; i < nAttrCount; i++ ) + { + rtl::OUString sAttrName = xAttrList->getNameByIndex( i ); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + rtl::OUString sValue = xAttrList->getValueByIndex( i ); + + if (nPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(aLocalName, XML_NAME)) + sName = sValue; + } + } +} + +ScXMLDataPilotGroupMemberContext::~ScXMLDataPilotGroupMemberContext() +{ +} + +SvXMLImportContext *ScXMLDataPilotGroupMemberContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + SvXMLImportContext *pContext = 0; + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDataPilotGroupMemberContext::EndElement() +{ + if (sName.getLength()) + pDataPilotGroup->AddMember(sName); +} diff --git a/sc/source/filter/xml/xmldpimp.hxx b/sc/source/filter/xml/xmldpimp.hxx new file mode 100644 index 000000000000..5ff84c587b54 --- /dev/null +++ b/sc/source/filter/xml/xmldpimp.hxx @@ -0,0 +1,693 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef SC_XMLDPIMP_HXX +#define SC_XMLDPIMP_HXX + +#include <xmloff/xmlictxt.hxx> +#include <xmloff/xmlimp.hxx> +#include <com/sun/star/sheet/DataPilotFieldReference.hpp> +#include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp> +#include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp> +#include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp> + +#include "global.hxx" +#include "dpobject.hxx" +#include "dpsave.hxx" +#include "queryparam.hxx" + +#include <hash_set> + +class ScXMLImport; +class ScDPSaveNumGroupDimension; +class ScDPSaveGroupDimension; + +enum ScMySourceType +{ + SQL, + TABLE, + QUERY, + SERVICE, + CELLRANGE +}; + +class ScXMLDataPilotTablesContext : public SvXMLImportContext +{ + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDataPilotTablesContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList); + + virtual ~ScXMLDataPilotTablesContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLDataPilotTableContext : public SvXMLImportContext +{ + typedef ::std::hash_set< ::rtl::OUString, ::rtl::OUStringHash > StringSet; + StringSet maHiddenMemberFields; + + 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; + rtl::OUString sDatabaseName; + rtl::OUString sSourceObject; + rtl::OUString sServiceName; + rtl::OUString sServiceSourceName; + rtl::OUString sServiceSourceObject; + rtl::OUString sServiceUsername; + rtl::OUString sServicePassword; + rtl::OUString sButtons; + ScRange aSourceCellRangeAddress; + ScRange aTargetRangeAddress; + ScRange aFilterSourceRange; + ScAddress aFilterOutputPosition; + ScQueryParam aSourceQueryParam; + ScMySourceType nSourceType; + sal_uInt32 mnRowFieldCount; + sal_uInt32 mnColFieldCount; + sal_uInt32 mnPageFieldCount; + sal_uInt32 mnDataFieldCount; + sal_Bool bIsNative; + sal_Bool bIgnoreEmptyRows; + sal_Bool bIdentifyCategories; + sal_Bool bUseRegularExpression; + sal_Bool bIsCaseSensitive; + sal_Bool bSkipDuplicates; + sal_Bool bFilterCopyOutputData; + sal_Bool bTargetRangeAddress; + sal_Bool bSourceCellRange; + sal_Bool bShowFilter; + sal_Bool bDrillDown; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDataPilotTableContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList); + + virtual ~ScXMLDataPilotTableContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + 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; } + void SetServiceName(const rtl::OUString& sValue) { sServiceName = sValue; } + void SetServiceSourceName(const rtl::OUString& sValue) { sServiceSourceName = sValue; } + void SetServiceSourceObject(const rtl::OUString& sValue) { sServiceSourceObject = sValue; } + void SetServiceUsername(const rtl::OUString& sValue) { sServiceUsername = sValue; } + void SetServicePassword(const rtl::OUString& sValue) { sServicePassword = sValue; } + void SetSourceCellRangeAddress(const ScRange& aValue) { aSourceCellRangeAddress = aValue; bSourceCellRange = sal_True; } + void SetSourceQueryParam(const ScQueryParam& aValue) { aSourceQueryParam = aValue; } +// void SetFilterUseRegularExpressions(const sal_Bool bValue) { aSourceQueryParam.bRegExp = bValue; } + void SetFilterOutputPosition(const ScAddress& aValue) { aFilterOutputPosition = aValue; } + void SetFilterCopyOutputData(const sal_Bool bValue) { bFilterCopyOutputData = bValue; } + void SetFilterSourceRange(const ScRange& aValue) { aFilterSourceRange = aValue; } +// void SetFilterIsCaseSensitive(const sal_Bool bValue) { aSourceQueryParam.bCaseSens = bValue; } +// void SetFilterSkipDuplicates(const sal_Bool bValue) { aSourceQueryParam.bDuplicate = !bValue; } + void AddDimension(ScDPSaveDimension* pDim, bool bHasHiddenMember); + void AddGroupDim(const ScDPSaveNumGroupDimension& aNumGroupDim); + void AddGroupDim(const ScDPSaveGroupDimension& aGroupDim); + void SetButtons(); +}; + +class ScXMLDPSourceSQLContext : public SvXMLImportContext +{ + ScXMLDataPilotTableContext* pDataPilotTable; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDPSourceSQLContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotTableContext* pDataPilotTable); + + virtual ~ScXMLDPSourceSQLContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLDPSourceTableContext : public SvXMLImportContext +{ + ScXMLDataPilotTableContext* pDataPilotTable; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDPSourceTableContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotTableContext* pDataPilotTable); + + virtual ~ScXMLDPSourceTableContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLDPSourceQueryContext : public SvXMLImportContext +{ + ScXMLDataPilotTableContext* pDataPilotTable; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDPSourceQueryContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotTableContext* pDataPilotTable); + + virtual ~ScXMLDPSourceQueryContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLSourceServiceContext : public SvXMLImportContext +{ + ScXMLDataPilotTableContext* pDataPilotTable; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLSourceServiceContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotTableContext* pDataPilotTable); + + virtual ~ScXMLSourceServiceContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + 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, sal_uInt16 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( sal_uInt16 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; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLSourceCellRangeContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotTableContext* pDataPilotTable); + + virtual ~ScXMLSourceCellRangeContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +struct ScXMLDataPilotGroup +{ + ::std::vector<rtl::OUString> aMembers; + rtl::OUString aName; +}; + +class ScXMLDataPilotFieldContext : public SvXMLImportContext +{ + ScXMLDataPilotTableContext* pDataPilotTable; + ScDPSaveDimension* pDim; + + ::std::vector<ScXMLDataPilotGroup> aGroups; + rtl::OUString sGroupSource; + rtl::OUString sSelectedPage; + rtl::OUString sName; + double fStart; + double fEnd; + double fStep; + sal_Int32 nUsedHierarchy; + sal_Int32 nGroupPart; + sal_Int16 nFunction; + sal_Int16 nOrientation; + sal_Bool bShowEmpty:1; + sal_Bool bSelectedPage:1; + sal_Bool bIsGroupField:1; + sal_Bool bDateValue:1; + sal_Bool bAutoStart:1; + sal_Bool bAutoEnd:1; + bool mbHasHiddenMember:1; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDataPilotFieldContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotTableContext* pDataPilotTable); + + virtual ~ScXMLDataPilotFieldContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); + + 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 AddMember(ScDPSaveMember* pMember); + void SetSubTotalName(const ::rtl::OUString& rName); + 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); } + void SetSortInfo(const com::sun::star::sheet::DataPilotFieldSortInfo& aInfo) { if (pDim) pDim->SetSortInfo(&aInfo); } + void SetLayoutInfo(const com::sun::star::sheet::DataPilotFieldLayoutInfo& aInfo) { if (pDim) pDim->SetLayoutInfo(&aInfo); } + void SetGrouping(const rtl::OUString& rGroupSource, const double& rStart, const double& rEnd, const double& rStep, + sal_Int32 nPart, sal_Bool bDate, sal_Bool bAutoSt, sal_Bool bAutoE) + { + bIsGroupField = sal_True; + sGroupSource = rGroupSource; + fStart = rStart; + fEnd = rEnd; + fStep = rStep; + nGroupPart = nPart; + bDateValue = bDate; + bAutoStart = bAutoSt; + bAutoEnd = bAutoE; + } + void AddGroup(const ::std::vector<rtl::OUString>& rMembers, const rtl::OUString& rName); +}; + +class ScXMLDataPilotFieldReferenceContext : public SvXMLImportContext +{ +// com::sun::star::sheet::DataPilotFieldReference aReference; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDataPilotFieldReferenceContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotFieldContext* pDataPilotField); + + virtual ~ScXMLDataPilotFieldReferenceContext(); +}; + +class ScXMLDataPilotLevelContext : public SvXMLImportContext +{ + ScXMLDataPilotFieldContext* pDataPilotField; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDataPilotLevelContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotFieldContext* pDataPilotField); + + virtual ~ScXMLDataPilotLevelContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLDataPilotDisplayInfoContext : public SvXMLImportContext +{ +// com::sun::star::sheet::DataPilotFieldAutoShowInfo aInfo; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDataPilotDisplayInfoContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotFieldContext* pDataPilotField); + + virtual ~ScXMLDataPilotDisplayInfoContext(); +}; + +class ScXMLDataPilotSortInfoContext : public SvXMLImportContext +{ +// com::sun::star::sheet::DataPilotFieldSortInfo aInfo; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDataPilotSortInfoContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotFieldContext* pDataPilotField); + + virtual ~ScXMLDataPilotSortInfoContext(); +}; + +class ScXMLDataPilotLayoutInfoContext : public SvXMLImportContext +{ +// com::sun::star::sheet::DataPilotFieldLayoutInfo aInfo; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDataPilotLayoutInfoContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotFieldContext* pDataPilotField); + + virtual ~ScXMLDataPilotLayoutInfoContext(); +}; + +class ScXMLDataPilotSubTotalsContext : public SvXMLImportContext +{ + ScXMLDataPilotFieldContext* pDataPilotField; + + sal_Int16 nFunctionCount; + sal_uInt16* pFunctions; + ::rtl::OUString maDisplayName; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDataPilotFieldContext* GetDataPilotField() { return pDataPilotField; } + + ScXMLDataPilotSubTotalsContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotFieldContext* pDataPilotField); + + virtual ~ScXMLDataPilotSubTotalsContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); + void AddFunction(sal_Int16 nFunction); + void SetDisplayName(const ::rtl::OUString& rName); +}; + +class ScXMLDataPilotSubTotalContext : public SvXMLImportContext +{ + ScXMLDataPilotSubTotalsContext* pDataPilotSubTotals; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDataPilotSubTotalContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotSubTotalsContext* pDataPilotSubTotals); + + virtual ~ScXMLDataPilotSubTotalContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLDataPilotMembersContext : public SvXMLImportContext +{ + ScXMLDataPilotFieldContext* pDataPilotField; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDataPilotMembersContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotFieldContext* pDataPilotField); + + virtual ~ScXMLDataPilotMembersContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLDataPilotMemberContext : public SvXMLImportContext +{ + ScXMLDataPilotFieldContext* pDataPilotField; + + rtl::OUString sName; + rtl::OUString maDisplayName; + sal_Bool bDisplay; + sal_Bool bDisplayDetails; + sal_Bool bHasName; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDataPilotMemberContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotFieldContext* pDataPilotField); + + virtual ~ScXMLDataPilotMemberContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLDataPilotGroupsContext : public SvXMLImportContext +{ + ScXMLDataPilotFieldContext* pDataPilotField; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDataPilotGroupsContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotFieldContext* pDataPilotField); + + virtual ~ScXMLDataPilotGroupsContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLDataPilotGroupContext : public SvXMLImportContext +{ + ScXMLDataPilotFieldContext* pDataPilotField; + + rtl::OUString sName; + ::std::vector<rtl::OUString> aMembers; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDataPilotGroupContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotFieldContext* pDataPilotField); + + virtual ~ScXMLDataPilotGroupContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); + + void AddMember(const rtl::OUString& sMember) { aMembers.push_back(sMember); } +}; + +class ScXMLDataPilotGroupMemberContext : public SvXMLImportContext +{ + ScXMLDataPilotGroupContext* pDataPilotGroup; + + rtl::OUString sName; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDataPilotGroupMemberContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotGroupContext* pDataPilotGroup); + + virtual ~ScXMLDataPilotGroupMemberContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +#endif + diff --git a/sc/source/filter/xml/xmldrani.cxx b/sc/source/filter/xml/xmldrani.cxx new file mode 100644 index 000000000000..c91602d7e568 --- /dev/null +++ b/sc/source/filter/xml/xmldrani.cxx @@ -0,0 +1,991 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- + +#include "xmldrani.hxx" +#include "xmlimprt.hxx" +#include "xmlfilti.hxx" +#include "xmlsorti.hxx" +#include "document.hxx" +#include "globstr.hrc" +#include "docuno.hxx" +#include "dbcolect.hxx" +#include "datauno.hxx" +#include "attrib.hxx" +#include "unonames.hxx" +#include "convuno.hxx" +#include "XMLConverter.hxx" +#include "rangeutl.hxx" + +#include <xmloff/xmltkmap.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/xmluconv.hxx> +#include <xmloff/xmlerror.hxx> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include <com/sun/star/sheet/XDatabaseRanges.hpp> +#include <com/sun/star/sheet/XDatabaseRange.hpp> +#include <com/sun/star/table/CellRangeAddress.hpp> +#include <comphelper/extract.hxx> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/xml/sax/XLocator.hpp> + +#define SC_ENABLEUSERSORTLIST "EnableUserSortList" +#define SC_USERSORTLISTINDEX "UserSortListIndex" +#define SC_USERLIST "UserList" + +using namespace com::sun::star; +using namespace xmloff::token; + +//------------------------------------------------------------------ + +ScXMLDatabaseRangesContext::ScXMLDatabaseRangesContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) : + SvXMLImportContext( rImport, nPrfx, rLName ) +{ + // has no attributes + rImport.LockSolarMutex(); +} + +ScXMLDatabaseRangesContext::~ScXMLDatabaseRangesContext() +{ + GetScImport().UnlockSolarMutex(); +} + +SvXMLImportContext *ScXMLDatabaseRangesContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + const SvXMLTokenMap& rTokenMap = GetScImport().GetDatabaseRangesElemTokenMap(); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_DATABASE_RANGE : + { + pContext = new ScXMLDatabaseRangeContext( GetScImport(), nPrefix, + rLName, xAttrList); + } + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDatabaseRangesContext::EndElement() +{ +} + +ScXMLDatabaseRangeContext::ScXMLDatabaseRangeContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList) : + SvXMLImportContext( rImport, nPrfx, rLName ), + sDatabaseRangeName(ScGlobal::GetRscString(STR_DB_NONAME)), + aSortSequence(), + eOrientation(table::TableOrientation_ROWS), + nRefresh(0), + nSubTotalsUserListIndex(0), + bContainsSort(sal_False), + bContainsSubTotal(sal_False), + bNative(sal_True), + bIsSelection(sal_False), + bKeepFormats(sal_False), + bMoveCells(sal_False), + bStripData(sal_False), + bContainsHeader(sal_True), + bAutoFilter(sal_False), + bSubTotalsBindFormatsToContent(sal_False), + bSubTotalsIsCaseSensitive(sal_False), + bSubTotalsInsertPageBreaks(sal_False), + bSubTotalsSortGroups(sal_False), + bSubTotalsEnabledUserList(sal_False), + bSubTotalsAscending(sal_True), + bFilterCopyOutputData(sal_False), + bFilterIsCaseSensitive(sal_False), + bFilterSkipDuplicates(sal_False), + bFilterUseRegularExpressions(sal_False), + bFilterConditionSourceRange(sal_False) +{ + nSourceType = sheet::DataImportMode_NONE; + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDatabaseRangeAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_DATABASE_RANGE_ATTR_NAME : + { + sDatabaseRangeName = sValue; + } + break; + case XML_TOK_DATABASE_RANGE_ATTR_IS_SELECTION : + { + bIsSelection = IsXMLToken(sValue, XML_TRUE); + } + break; + case XML_TOK_DATABASE_RANGE_ATTR_ON_UPDATE_KEEP_STYLES : + { + bKeepFormats = IsXMLToken(sValue, XML_TRUE); + } + break; + case XML_TOK_DATABASE_RANGE_ATTR_ON_UPDATE_KEEP_SIZE : + { + bMoveCells = !IsXMLToken(sValue, XML_TRUE); + } + break; + case XML_TOK_DATABASE_RANGE_ATTR_HAS_PERSISTENT_DATA : + { + bStripData = !IsXMLToken(sValue, XML_TRUE); + } + break; + case XML_TOK_DATABASE_RANGE_ATTR_ORIENTATION : + { + if (IsXMLToken(sValue, XML_COLUMN)) + eOrientation = table::TableOrientation_COLUMNS; + } + break; + case XML_TOK_DATABASE_RANGE_ATTR_CONTAINS_HEADER : + { + bContainsHeader = IsXMLToken(sValue, XML_TRUE); + } + break; + case XML_TOK_DATABASE_RANGE_ATTR_DISPLAY_FILTER_BUTTONS : + { + bAutoFilter = IsXMLToken(sValue, XML_TRUE); + } + break; + case XML_TOK_DATABASE_RANGE_ATTR_TARGET_RANGE_ADDRESS : + { + sRangeAddress = sValue; + } + break; + case XML_TOK_DATABASE_RANGE_ATTR_REFRESH_DELAY : + { + double fTime; + if( SvXMLUnitConverter::convertTime( fTime, sValue ) ) + nRefresh = Max( (sal_Int32)(fTime * 86400.0), (sal_Int32)0 ); + } + break; + } + } +} + +ScXMLDatabaseRangeContext::~ScXMLDatabaseRangeContext() +{ +} + +SvXMLImportContext *ScXMLDatabaseRangeContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + const SvXMLTokenMap& rTokenMap = GetScImport().GetDatabaseRangeElemTokenMap(); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_DATABASE_RANGE_SOURCE_SQL : + { + pContext = new ScXMLSourceSQLContext( GetScImport(), nPrefix, + rLName, xAttrList, this); + } + break; + case XML_TOK_DATABASE_RANGE_SOURCE_TABLE : + { + pContext = new ScXMLSourceTableContext( GetScImport(), nPrefix, + rLName, xAttrList, this); + } + break; + case XML_TOK_DATABASE_RANGE_SOURCE_QUERY : + { + pContext = new ScXMLSourceQueryContext( GetScImport(), nPrefix, + rLName, xAttrList, this); + } + break; + case XML_TOK_FILTER : + { + pContext = new ScXMLFilterContext( GetScImport(), nPrefix, + rLName, xAttrList, this); + } + break; + case XML_TOK_SORT : + { + bContainsSort = sal_True; + pContext = new ScXMLSortContext( GetScImport(), nPrefix, + rLName, xAttrList, this); + } + break; + case XML_TOK_DATABASE_RANGE_SUBTOTAL_RULES : + { + bContainsSubTotal = sal_True; + pContext = new ScXMLSubTotalRulesContext( GetScImport(), nPrefix, + rLName, xAttrList, this); + } + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDatabaseRangeContext::EndElement() +{ + if (GetScImport().GetModel().is()) + { + uno::Reference <beans::XPropertySet> xPropertySet( GetScImport().GetModel(), uno::UNO_QUERY ); + ScDocument* pDoc = GetScImport().GetDocument(); + if (pDoc && xPropertySet.is()) + { + uno::Reference <sheet::XDatabaseRanges> xDatabaseRanges(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DATABASERNG))), uno::UNO_QUERY); + if (xDatabaseRanges.is()) + { + table::CellRangeAddress aCellRangeAddress; + sal_Int32 nOffset(0); + if (ScRangeStringConverter::GetRangeFromString( aCellRangeAddress, sRangeAddress, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset )) + { + sal_Bool bInsert(sal_True); + try + { + xDatabaseRanges->addNewByName(sDatabaseRangeName, aCellRangeAddress); + } + catch ( uno::RuntimeException& rRuntimeException ) + { + bInsert = sal_False; + rtl::OUString sErrorMessage(RTL_CONSTASCII_USTRINGPARAM("DatabaseRange ")); + sErrorMessage += sDatabaseRangeName; + sErrorMessage += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" could not be created with the range ")); + sErrorMessage += sRangeAddress; + uno::Sequence<rtl::OUString> aSeq(1); + aSeq[0] = sErrorMessage; + uno::Reference<xml::sax::XLocator> xLocator; + GetScImport().SetError(XMLERROR_API | XMLERROR_FLAG_ERROR, aSeq, rRuntimeException.Message, xLocator); + } + if (bInsert) + { + uno::Reference <sheet::XDatabaseRange> xDatabaseRange(xDatabaseRanges->getByName(sDatabaseRangeName), uno::UNO_QUERY); + if (xDatabaseRange.is()) + { + uno::Reference <beans::XPropertySet> xDatabaseRangePropertySet (xDatabaseRange, uno::UNO_QUERY); + if (xDatabaseRangePropertySet.is()) + { + xDatabaseRangePropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_KEEPFORM)), uno::makeAny(bKeepFormats)); + xDatabaseRangePropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_MOVCELLS)), uno::makeAny(bMoveCells)); + xDatabaseRangePropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_STRIPDAT)), uno::makeAny(bStripData)); + } + uno::Sequence <beans::PropertyValue> aImportDescriptor(xDatabaseRange->getImportDescriptor()); + sal_Int32 nImportProperties = aImportDescriptor.getLength(); + for (sal_Int16 i = 0; i < nImportProperties; ++i) + { + if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_DBNAME))) + { + if (sDatabaseName.getLength()) + { + aImportDescriptor[i].Value <<= sDatabaseName; + } + else + { + aImportDescriptor[i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CONRES)); + aImportDescriptor[i].Value <<= sConnectionRessource; + } + } + else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SRCOBJ))) + aImportDescriptor[i].Value <<= sSourceObject; + else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SRCTYPE))) + aImportDescriptor[i].Value <<= nSourceType; + else if (aImportDescriptor[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ISNATIVE))) + aImportDescriptor[i].Value <<= bNative; + } + ScDBCollection* pDBCollection = pDoc->GetDBCollection(); + sal_uInt16 nIndex; + pDBCollection->SearchName(sDatabaseRangeName, nIndex); + ScDBData* pDBData = (*pDBCollection)[nIndex]; + pDBData->SetImportSelection(bIsSelection); + pDBData->SetAutoFilter(bAutoFilter); + if (bAutoFilter) + pDoc->ApplyFlagsTab( static_cast<SCCOL>(aCellRangeAddress.StartColumn), static_cast<SCROW>(aCellRangeAddress.StartRow), + static_cast<SCCOL>(aCellRangeAddress.EndColumn), static_cast<SCROW>(aCellRangeAddress.StartRow), + aCellRangeAddress.Sheet, SC_MF_AUTO ); + ScImportParam aImportParam; + ScImportDescriptor::FillImportParam(aImportParam, aImportDescriptor); + pDBData->SetImportParam(aImportParam); + if (bContainsSort) + { + sal_uInt32 nOldSize(aSortSequence.getLength()); + aSortSequence.realloc(nOldSize + 1); + beans::PropertyValue aProperty; + aProperty.Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ORIENT)); + aProperty.Value <<= eOrientation; + aSortSequence[nOldSize] = aProperty; + ScSortParam aSortParam; + ScSortDescriptor::FillSortParam(aSortParam, aSortSequence); + + //#98317#; until now the Fields are relative to the left top edge of the range, but the + // core wants to have the absolute position (column/row) + SCCOLROW nFieldStart = aSortParam.bByRow ? static_cast<SCCOLROW>(aCellRangeAddress.StartColumn) : static_cast<SCCOLROW>(aCellRangeAddress.StartRow); + for (sal_uInt16 i = 0; i < MAXSORT; ++i) + { + if (aSortParam.bDoSort[i]) + aSortParam.nField[i] += nFieldStart; + } + + pDBData->SetSortParam(aSortParam); + } + uno::Reference< sheet::XSheetFilterDescriptor2 > xSheetFilterDescriptor( + xDatabaseRange->getFilterDescriptor(), uno::UNO_QUERY ); + if (xSheetFilterDescriptor.is()) + { + uno::Reference <beans::XPropertySet> xFilterPropertySet (xSheetFilterDescriptor, uno::UNO_QUERY); + if (xFilterPropertySet.is()) + { + sal_Bool bOrientation(table::TableOrientation_COLUMNS == eOrientation); + xFilterPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ORIENT)), uno::makeAny(bOrientation)); + xFilterPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CONTHDR)), uno::makeAny(bContainsHeader)); + xFilterPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_COPYOUT)), uno::makeAny(bFilterCopyOutputData)); + xFilterPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ISCASE)), uno::makeAny(bFilterIsCaseSensitive)); + xFilterPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SKIPDUP)), uno::makeAny(bFilterSkipDuplicates)); + xFilterPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_USEREGEX)), uno::makeAny(bFilterUseRegularExpressions)); + xFilterPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_OUTPOS)), uno::makeAny(aFilterOutputPosition)); + } + xSheetFilterDescriptor->setFilterFields2(aFilterFields); + if (bFilterConditionSourceRange) + { + ScRange aAdvSource; + ScUnoConversion::FillScRange( aAdvSource, aFilterConditionSourceRangeAddress ); + pDBData->SetAdvancedQuerySource(&aAdvSource); + } + } + if (bContainsSubTotal) + { + uno::Reference <sheet::XSubTotalDescriptor> xSubTotalDescriptor(xDatabaseRange->getSubTotalDescriptor()); + if (xSubTotalDescriptor.is()) + { + uno::Reference <beans::XPropertySet> xSubTotalPropertySet (xSubTotalDescriptor, uno::UNO_QUERY); + if( xSubTotalPropertySet.is()) + { + xSubTotalPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_BINDFMT)), uno::makeAny(bSubTotalsBindFormatsToContent)); + xSubTotalPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ENABLEUSERSORTLIST)), uno::makeAny(bSubTotalsEnabledUserList)); + xSubTotalPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_USERSORTLISTINDEX)), uno::makeAny(nSubTotalsUserListIndex)); + xSubTotalPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_INSBRK)), uno::makeAny(bSubTotalsInsertPageBreaks)); + xSubTotalPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ISCASE)), uno::makeAny(bSubTotalsIsCaseSensitive)); + } + ScSubTotalParam aSubTotalParam; + aSubTotalParam.bDoSort = bSubTotalsSortGroups; + aSubTotalParam.bAscending = bSubTotalsAscending; + aSubTotalParam.bUserDef = bSubTotalsEnabledUserList; + aSubTotalParam.nUserIndex = nSubTotalsUserListIndex; + pDBData->SetSubTotalParam(aSubTotalParam); + std::vector < ScSubTotalRule >::iterator aItr(aSubTotalRules.begin()); + while (!aSubTotalRules.empty()) + { + xSubTotalDescriptor->addNew(aItr->aSubTotalColumns, aItr->nSubTotalRuleGroupFieldNumber); + aItr = aSubTotalRules.erase(aItr); + } + } + } + if ( pDBData->HasImportParam() && !pDBData->HasImportSelection() ) + { + pDBData->SetRefreshDelay( nRefresh ); + pDBData->SetRefreshHandler( pDBCollection->GetRefreshHandler() ); + pDBData->SetRefreshControl( pDoc->GetRefreshTimerControlAddress() ); + } + } + } + } + } + } + } +} + +ScXMLSourceSQLContext::ScXMLSourceSQLContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDatabaseRangeContext(pTempDatabaseRangeContext) +{ + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDatabaseRangeSourceSQLAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_SOURCE_SQL_ATTR_DATABASE_NAME : + { + sDBName = sValue; + } + break; + case XML_TOK_SOURCE_SQL_ATTR_SQL_STATEMENT : + { + pDatabaseRangeContext->SetSourceObject(sValue); + } + break; + case XML_TOK_SOURCE_SQL_ATTR_PARSE_SQL_STATEMENT : + { + pDatabaseRangeContext->SetNative(IsXMLToken(sValue, XML_TRUE)); + } + break; + } + } + pDatabaseRangeContext->SetSourceType(sheet::DataImportMode_SQL); +} + +ScXMLSourceSQLContext::~ScXMLSourceSQLContext() +{ +} + +SvXMLImportContext *ScXMLSourceSQLContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + if ( nPrefix == XML_NAMESPACE_FORM ) + { + if (IsXMLToken(rLName, XML_CONNECTION_RESOURCE) && (sDBName.getLength() == 0)) + { + pContext = new ScXMLConResContext( GetScImport(), nPrefix, + rLName, xAttrList, pDatabaseRangeContext); + } + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLSourceSQLContext::EndElement() +{ + if (sDBName.getLength()) + pDatabaseRangeContext->SetDatabaseName(sDBName); +} + +ScXMLSourceTableContext::ScXMLSourceTableContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDatabaseRangeContext(pTempDatabaseRangeContext) +{ + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDatabaseRangeSourceTableAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_SOURCE_TABLE_ATTR_DATABASE_NAME : + { + sDBName = sValue; + } + break; + case XML_TOK_SOURCE_TABLE_ATTR_TABLE_NAME : + { + pDatabaseRangeContext->SetSourceObject(sValue); + } + break; + } + } + pDatabaseRangeContext->SetSourceType(sheet::DataImportMode_TABLE); +} + +ScXMLSourceTableContext::~ScXMLSourceTableContext() +{ +} + +SvXMLImportContext *ScXMLSourceTableContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + if ( nPrefix == XML_NAMESPACE_FORM ) + { + if (IsXMLToken(rLName, XML_CONNECTION_RESOURCE) && (sDBName.getLength() == 0)) + { + pContext = new ScXMLConResContext( GetScImport(), nPrefix, + rLName, xAttrList, pDatabaseRangeContext); + } + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLSourceTableContext::EndElement() +{ + if (sDBName.getLength()) + pDatabaseRangeContext->SetDatabaseName(sDBName); +} + +ScXMLSourceQueryContext::ScXMLSourceQueryContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDatabaseRangeContext(pTempDatabaseRangeContext) +{ + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDatabaseRangeSourceQueryAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_SOURCE_QUERY_ATTR_DATABASE_NAME : + { + sDBName = sValue; + } + break; + case XML_TOK_SOURCE_QUERY_ATTR_QUERY_NAME : + { + pDatabaseRangeContext->SetSourceObject(sValue); + } + break; + } + } + pDatabaseRangeContext->SetSourceType(sheet::DataImportMode_QUERY); +} + +ScXMLSourceQueryContext::~ScXMLSourceQueryContext() +{ +} + +SvXMLImportContext *ScXMLSourceQueryContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + if ( nPrefix == XML_NAMESPACE_FORM ) + { + if (IsXMLToken(rLName, XML_CONNECTION_RESOURCE) && (sDBName.getLength() == 0)) + { + pContext = new ScXMLConResContext( GetScImport(), nPrefix, + rLName, xAttrList, pDatabaseRangeContext); + } + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLSourceQueryContext::EndElement() +{ + if (sDBName.getLength()) + pDatabaseRangeContext->SetDatabaseName(sDBName); +} + +ScXMLConResContext::ScXMLConResContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDatabaseRangeContext( pTempDatabaseRangeContext ) +{ + rtl::OUString sConRes; + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + for( sal_Int16 i=0; i < nAttrCount; i++ ) + { + rtl::OUString sAttrName = xAttrList->getNameByIndex( i ); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + rtl::OUString sValue = xAttrList->getValueByIndex( i ); + + if (nPrefix == XML_NAMESPACE_XLINK) + { + if (IsXMLToken(aLocalName, XML_HREF)) + sConRes = sValue; + } + } + if (sConRes.getLength()) + pDatabaseRangeContext->SetConnectionRessource(sConRes); +} + +ScXMLConResContext::~ScXMLConResContext() +{ +} + +SvXMLImportContext *ScXMLConResContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + SvXMLImportContext *pContext = 0; + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLConResContext::EndElement() +{ +} + +ScXMLSubTotalRulesContext::ScXMLSubTotalRulesContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDatabaseRangeContext(pTempDatabaseRangeContext) +{ + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDatabaseRangeSubTotalRulesAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_SUBTOTAL_RULES_ATTR_BIND_STYLES_TO_CONTENT : + { + pDatabaseRangeContext->SetSubTotalsBindFormatsToContent(IsXMLToken(sValue, XML_TRUE)); + } + break; + case XML_TOK_SUBTOTAL_RULES_ATTR_CASE_SENSITIVE : + { + pDatabaseRangeContext->SetSubTotalsIsCaseSensitive(IsXMLToken(sValue, XML_TRUE)); + } + break; + case XML_TOK_SUBTOTAL_RULES_ATTR_PAGE_BREAKS_ON_GROUP_CHANGE : + { + pDatabaseRangeContext->SetSubTotalsInsertPageBreaks(IsXMLToken(sValue, XML_TRUE)); + } + break; + } + } +} + +ScXMLSubTotalRulesContext::~ScXMLSubTotalRulesContext() +{ +} + +SvXMLImportContext *ScXMLSubTotalRulesContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + const SvXMLTokenMap& rTokenMap = GetScImport().GetDatabaseRangeSubTotalRulesElemTokenMap(); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_SUBTOTAL_RULES_SORT_GROUPS : + { + pContext = new ScXMLSortGroupsContext( GetScImport(), nPrefix, + rLName, xAttrList, pDatabaseRangeContext); + } + break; + case XML_TOK_SUBTOTAL_RULES_SUBTOTAL_RULE : + { + pContext = new ScXMLSubTotalRuleContext( GetScImport(), nPrefix, + rLName, xAttrList, pDatabaseRangeContext); + } + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLSubTotalRulesContext::EndElement() +{ +} + +ScXMLSortGroupsContext::ScXMLSortGroupsContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDatabaseRangeContext(pTempDatabaseRangeContext) +{ + pDatabaseRangeContext->SetSubTotalsSortGroups(sal_True); + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetSubTotalRulesSortGroupsAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_SORT_GROUPS_ATTR_DATA_TYPE : + { + if (sValue.getLength() > 8) + { + rtl::OUString sTemp = sValue.copy(0, 8); + if (sTemp.compareToAscii(SC_USERLIST) == 0) + { + pDatabaseRangeContext->SetSubTotalsEnabledUserList(sal_True); + sTemp = sValue.copy(8); + pDatabaseRangeContext->SetSubTotalsUserListIndex(static_cast<sal_Int16>(sTemp.toInt32())); + } + else + { + //if (IsXMLToken(sValue, XML_AUTOMATIC)) + //aSortField.FieldType = util::SortFieldType_AUTOMATIC; + // is not supported by StarOffice + } + } + else + { + //if (IsXMLToken(sValue, XML_TEXT)) + //aSortField.FieldType = util::SortFieldType_ALPHANUMERIC; + // is not supported by StarOffice + //else if (IsXMLToken(sValue, XML_NUMBER)) + //aSortField.FieldType = util::SortFieldType_NUMERIC; + // is not supported by StarOffice + } + } + break; + case XML_TOK_SORT_GROUPS_ATTR_ORDER : + { + if (IsXMLToken(sValue, XML_ASCENDING)) + pDatabaseRangeContext->SetSubTotalsAscending(sal_True); + else + pDatabaseRangeContext->SetSubTotalsAscending(sal_False); + } + break; + } + } +} + +ScXMLSortGroupsContext::~ScXMLSortGroupsContext() +{ +} + +SvXMLImportContext *ScXMLSortGroupsContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + SvXMLImportContext *pContext = 0; + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLSortGroupsContext::EndElement() +{ +} + +ScXMLSubTotalRuleContext::ScXMLSubTotalRuleContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDatabaseRangeContext(pTempDatabaseRangeContext) +{ + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetSubTotalRulesSubTotalRuleAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_SUBTOTAL_RULE_ATTR_GROUP_BY_FIELD_NUMBER : + { + aSubTotalRule.nSubTotalRuleGroupFieldNumber = static_cast<sal_Int16>(sValue.toInt32()); + } + break; + } + } +} + +ScXMLSubTotalRuleContext::~ScXMLSubTotalRuleContext() +{ +} + +SvXMLImportContext *ScXMLSubTotalRuleContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + const SvXMLTokenMap& rTokenMap = GetScImport().GetSubTotalRulesSubTotalRuleElemTokenMap(); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_SUBTOTAL_RULE_SUBTOTAL_FIELD : + { + pContext = new ScXMLSubTotalFieldContext( GetScImport(), nPrefix, + rLName, xAttrList, this); + } + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLSubTotalRuleContext::EndElement() +{ + if (pDatabaseRangeContext) + pDatabaseRangeContext->AddSubTotalRule(aSubTotalRule); +} + +ScXMLSubTotalFieldContext::ScXMLSubTotalFieldContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLSubTotalRuleContext* pTempSubTotalRuleContext) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pSubTotalRuleContext(pTempSubTotalRuleContext) +{ + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetSubTotalRuleSubTotalFieldAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_SUBTOTAL_FIELD_ATTR_FIELD_NUMBER : + { + sFieldNumber = sValue; + } + break; + case XML_TOK_SUBTOTAL_FIELD_ATTR_FUNCTION : + { + sFunction = sValue; + } + break; + } + } +} + +ScXMLSubTotalFieldContext::~ScXMLSubTotalFieldContext() +{ +} + +SvXMLImportContext *ScXMLSubTotalFieldContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + SvXMLImportContext *pContext = 0; + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLSubTotalFieldContext::EndElement() +{ + sheet::SubTotalColumn aSubTotalColumn; + aSubTotalColumn.Column = sFieldNumber.toInt32(); + aSubTotalColumn.Function = ScXMLConverter::GetFunctionFromString( sFunction ); + pSubTotalRuleContext->AddSubTotalColumn(aSubTotalColumn); +} + diff --git a/sc/source/filter/xml/xmldrani.hxx b/sc/source/filter/xml/xmldrani.hxx new file mode 100644 index 000000000000..1191925c2bcc --- /dev/null +++ b/sc/source/filter/xml/xmldrani.hxx @@ -0,0 +1,362 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef SC_XMLDRANI_HXX +#define SC_XMLDRANI_HXX + +#include <xmloff/xmlictxt.hxx> +#include <xmloff/xmlimp.hxx> +#include <com/sun/star/sheet/DataImportMode.hpp> +#include <com/sun/star/sheet/SubTotalColumn.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/sheet/TableFilterField2.hpp> +#include <com/sun/star/table/CellAddress.hpp> +#include <com/sun/star/table/CellRangeAddress.hpp> +#include <com/sun/star/table/TableOrientation.hpp> + +class ScXMLImport; + +class ScXMLDatabaseRangesContext : public SvXMLImportContext +{ + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDatabaseRangesContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList); + + virtual ~ScXMLDatabaseRangesContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +struct ScSubTotalRule +{ + sal_Int16 nSubTotalRuleGroupFieldNumber; + com::sun::star::uno::Sequence <com::sun::star::sheet::SubTotalColumn> aSubTotalColumns; +}; + +class ScXMLDatabaseRangeContext : public SvXMLImportContext +{ + rtl::OUString sDatabaseRangeName; + rtl::OUString sConnectionRessource; + rtl::OUString sRangeAddress; + rtl::OUString sDatabaseName; + rtl::OUString sSourceObject; + com::sun::star::uno::Sequence <com::sun::star::beans::PropertyValue> aSortSequence; + com::sun::star::uno::Sequence <com::sun::star::sheet::TableFilterField2> aFilterFields; + std::vector < ScSubTotalRule > aSubTotalRules; + com::sun::star::table::CellAddress aFilterOutputPosition; + com::sun::star::table::CellRangeAddress aFilterConditionSourceRangeAddress; + com::sun::star::sheet::DataImportMode nSourceType; + com::sun::star::table::TableOrientation eOrientation; + sal_Int32 nRefresh; + sal_Int16 nSubTotalsUserListIndex; + sal_Int16 nSubTotalRuleGroupFieldNumber; + sal_Bool bContainsSort; + sal_Bool bContainsSubTotal; + sal_Bool bNative; + sal_Bool bIsSelection; + sal_Bool bKeepFormats; + sal_Bool bMoveCells; + sal_Bool bStripData; + sal_Bool bContainsHeader; + sal_Bool bAutoFilter; + sal_Bool bSubTotalsBindFormatsToContent; + sal_Bool bSubTotalsIsCaseSensitive; + sal_Bool bSubTotalsInsertPageBreaks; + sal_Bool bSubTotalsSortGroups; + sal_Bool bSubTotalsEnabledUserList; + sal_Bool bSubTotalsAscending; + sal_Bool bFilterCopyOutputData; + sal_Bool bFilterIsCaseSensitive; + sal_Bool bFilterSkipDuplicates; + sal_Bool bFilterUseRegularExpressions; + sal_Bool bFilterConditionSourceRange; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDatabaseRangeContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList); + + virtual ~ScXMLDatabaseRangeContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); + + void SetDatabaseName(const rtl::OUString sTempDatabaseName) { sDatabaseName = sTempDatabaseName; } + void SetConnectionRessource(const rtl::OUString sTempConRes) { sConnectionRessource = sTempConRes; } + void SetSourceObject(const rtl::OUString sTempSourceObject) { sSourceObject = sTempSourceObject; } + void SetSourceType(const com::sun::star::sheet::DataImportMode nTempSourceType) { nSourceType = nTempSourceType; } + void SetNative(const sal_Bool bTempNative) { bNative = bTempNative; } + void SetSubTotalsBindFormatsToContent(const sal_Bool bTemp ) { bSubTotalsBindFormatsToContent = bTemp; } + void SetSubTotalsIsCaseSensitive(const sal_Bool bTemp) { bSubTotalsIsCaseSensitive = bTemp; } + void SetSubTotalsInsertPageBreaks(const sal_Bool bTemp) { bSubTotalsInsertPageBreaks = bTemp; } + void SetSubTotalsEnabledUserList(const sal_Bool bTemp) { bSubTotalsEnabledUserList = bTemp; } + void SetSubTotalsUserListIndex(const sal_Int16 nTemp) { nSubTotalsUserListIndex = nTemp; } + void SetSubTotalsAscending(const sal_Bool bTemp) { bSubTotalsAscending = bTemp; } + void SetSubTotalsSortGroups(const sal_Bool bTemp) { bSubTotalsSortGroups = bTemp; } + void AddSubTotalRule(const ScSubTotalRule& rRule) { aSubTotalRules.push_back(rRule); } + void SetSortSequence(const com::sun::star::uno::Sequence <com::sun::star::beans::PropertyValue>& aTempSortSequence) { aSortSequence = aTempSortSequence; } + void SetFilterCopyOutputData(const sal_Bool bTemp) { bFilterCopyOutputData = bTemp; } + void SetFilterIsCaseSensitive(const sal_Bool bTemp) { bFilterIsCaseSensitive = bTemp; } + void SetFilterSkipDuplicates(const sal_Bool bTemp) { bFilterSkipDuplicates = bTemp; } + void SetFilterUseRegularExpressions(const sal_Bool bTemp) { bFilterUseRegularExpressions = bTemp; } + void SetFilterFields(const com::sun::star::uno::Sequence <com::sun::star::sheet::TableFilterField2>& aTemp) { aFilterFields = aTemp; } + void SetFilterOutputPosition(const com::sun::star::table::CellAddress& aTemp) { aFilterOutputPosition = aTemp; } + void SetFilterConditionSourceRangeAddress(const com::sun::star::table::CellRangeAddress& aTemp) { aFilterConditionSourceRangeAddress = aTemp; + bFilterConditionSourceRange = sal_True; } +}; + +class ScXMLSourceSQLContext : public SvXMLImportContext +{ + ScXMLDatabaseRangeContext* pDatabaseRangeContext; + rtl::OUString sDBName; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLSourceSQLContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDatabaseRangeContext* pTempDatabaseRangeContext); + + virtual ~ScXMLSourceSQLContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLSourceTableContext : public SvXMLImportContext +{ + ScXMLDatabaseRangeContext* pDatabaseRangeContext; + rtl::OUString sDBName; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLSourceTableContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDatabaseRangeContext* pTempDatabaseRangeContext); + + virtual ~ScXMLSourceTableContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLSourceQueryContext : public SvXMLImportContext +{ + ScXMLDatabaseRangeContext* pDatabaseRangeContext; + rtl::OUString sDBName; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLSourceQueryContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDatabaseRangeContext* pTempDatabaseRangeContext); + + virtual ~ScXMLSourceQueryContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLConResContext : public SvXMLImportContext +{ + ScXMLDatabaseRangeContext* pDatabaseRangeContext; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLConResContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDatabaseRangeContext* pTempDatabaseRangeContext); + + virtual ~ScXMLConResContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLSubTotalRulesContext : public SvXMLImportContext +{ + ScXMLDatabaseRangeContext* pDatabaseRangeContext; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLSubTotalRulesContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDatabaseRangeContext* pTempDatabaseRangeContext); + + virtual ~ScXMLSubTotalRulesContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLSortGroupsContext : public SvXMLImportContext +{ + ScXMLDatabaseRangeContext* pDatabaseRangeContext; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLSortGroupsContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDatabaseRangeContext* pTempDatabaseRangeContext); + + virtual ~ScXMLSortGroupsContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLSubTotalRuleContext : public SvXMLImportContext +{ + ScXMLDatabaseRangeContext* pDatabaseRangeContext; + ScSubTotalRule aSubTotalRule; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLSubTotalRuleContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDatabaseRangeContext* pTempDatabaseRangeContext); + + virtual ~ScXMLSubTotalRuleContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); + + void AddSubTotalColumn(const com::sun::star::sheet::SubTotalColumn aSubTotalColumn) + { aSubTotalRule.aSubTotalColumns.realloc(aSubTotalRule.aSubTotalColumns.getLength() + 1); + aSubTotalRule.aSubTotalColumns[aSubTotalRule.aSubTotalColumns.getLength() - 1] = aSubTotalColumn; } +}; + +class ScXMLSubTotalFieldContext : public SvXMLImportContext +{ + ScXMLSubTotalRuleContext* pSubTotalRuleContext; + rtl::OUString sFieldNumber; + rtl::OUString sFunction; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLSubTotalFieldContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLSubTotalRuleContext* pSubTotalRuleContext); + + virtual ~ScXMLSubTotalFieldContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +#endif diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx new file mode 100644 index 000000000000..f8769cc95ffb --- /dev/null +++ b/sc/source/filter/xml/xmlexprt.cxx @@ -0,0 +1,4623 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +// INCLUDE --------------------------------------------------------------- + +#include <editeng/eeitem.hxx> + +#include "xmlexprt.hxx" +#include "XMLConverter.hxx" +#include "xmlstyle.hxx" +#include "unonames.hxx" +#include "document.hxx" +#include "olinetab.hxx" +#include "cellsuno.hxx" +#include "cell.hxx" +#include "rangenam.hxx" +#include "XMLTableMasterPageExport.hxx" +#include "drwlayer.hxx" +#include "XMLExportDataPilot.hxx" +#include "XMLExportDatabaseRanges.hxx" +#include "XMLExportDDELinks.hxx" +#include "XMLExportIterator.hxx" +#include "XMLColumnRowGroupExport.hxx" +#include "XMLStylesExportHelper.hxx" +#include "XMLChangeTrackingExportHelper.hxx" +#include "sheetdata.hxx" +#include "docoptio.hxx" +#include "XMLExportSharedData.hxx" +#include "chgviset.hxx" +#include "docuno.hxx" +#include "textuno.hxx" +#include "chartlis.hxx" +#include "unoguard.hxx" +#include "scitems.hxx" +#include "docpool.hxx" +#include "userdat.hxx" +#include "dociter.hxx" +#include "chgtrack.hxx" +#include "rangeutl.hxx" +#include "convuno.hxx" +#include "postit.hxx" +#include "externalrefmgr.hxx" +#include "editutil.hxx" +#include "tabprotection.hxx" + +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/xmluconv.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/families.hxx> +#include <xmloff/numehelp.hxx> +#include <xmloff/xmluconv.hxx> +#include <xmloff/txtparae.hxx> +#include <xmloff/xmlcnitm.hxx> +#include <xmloff/xmlerror.hxx> +#include <xmloff/XMLEventExport.hxx> + +#include <rtl/ustring.hxx> + +#include <tools/debug.hxx> +#include "tools/color.hxx" +#include <rtl/math.hxx> +#include <svl/zforlist.hxx> +#include <svx/unoshape.hxx> +#include <comphelper/extract.hxx> +#include <editeng/eeitem.hxx> +#include <toolkit/helper/convert.hxx> +#include <svx/svdobj.hxx> +#include <svx/svdocapt.hxx> +#include <editeng/outlobj.hxx> +#include <svx/svditer.hxx> +#include <svx/svdpage.hxx> + +#include <comphelper/processfactory.hxx> +#include <com/sun/star/sheet/XUsedAreaCursor.hpp> +#include <com/sun/star/sheet/XCellRangeAddressable.hpp> +#include <com/sun/star/sheet/XAreaLinks.hpp> +#include <com/sun/star/sheet/XAreaLink.hpp> +#include <com/sun/star/drawing/XDrawPageSupplier.hpp> +#include <com/sun/star/table/XColumnRowRange.hpp> +#include <com/sun/star/sheet/XPrintAreas.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/util/XProtectable.hpp> +#include <com/sun/star/style/XStyleFamiliesSupplier.hpp> +#include <com/sun/star/sheet/XUniqueCellFormatRangesSupplier.hpp> +#include <com/sun/star/sheet/XCellRangesQuery.hpp> +#include <com/sun/star/sheet/CellFlags.hpp> +#include <com/sun/star/util/XMergeable.hpp> +#include <com/sun/star/sheet/XArrayFormulaRange.hpp> +#include <com/sun/star/text/XText.hpp> +#include <com/sun/star/sheet/XLabelRanges.hpp> +#include <com/sun/star/sheet/XLabelRange.hpp> +#include <com/sun/star/sheet/XNamedRanges.hpp> +#include <com/sun/star/sheet/XNamedRange.hpp> +#include <com/sun/star/sheet/XCellRangeReferrer.hpp> +#include <com/sun/star/sheet/NamedRangeFlag.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/sheet/XSheetLinkable.hpp> +#include <com/sun/star/form/XFormsSupplier2.hpp> +#include <com/sun/star/io/XActiveDataSource.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> + +#include <com/sun/star/chart2/XChartDocument.hpp> +#include <com/sun/star/chart2/data/XRangeXMLConversion.hpp> +#include <com/sun/star/chart2/data/XDataReceiver.hpp> + +#include <com/sun/star/document/XDocumentProperties.hpp> +#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> + +#include "XMLCodeNameProvider.hxx" + +#include <sfx2/objsh.hxx> + +#include <vector> + +//! not found in unonames.hxx +#define SC_STANDARDFORMAT "StandardFormat" +#define SC_LAYERID "LayerID" + +#define SC_DEFAULT_TABLE_COUNT 3 +#define SC_VIEWCHANGES_COUNT 13 +#define SC_SHOW_CHANGES 0 +#define SC_SHOW_ACCEPTED_CHANGES 1 +#define SC_SHOW_REJECTED_CHANGES 2 +#define SC_SHOW_CHANGES_BY_DATETIME 3 +#define SC_SHOW_CHANGES_BY_DATETIME_MODE 4 +#define SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME 5 +#define SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME 6 +#define SC_SHOW_CHANGES_BY_AUTHOR 7 +#define SC_SHOW_CHANGES_BY_AUTHOR_NAME 8 +#define SC_SHOW_CHANGES_BY_COMMENT 9 +#define SC_SHOW_CHANGES_BY_COMMENT_TEXT 10 +#define SC_SHOW_CHANGES_BY_RANGES 11 +#define SC_SHOW_CHANGES_BY_RANGES_LIST 12 + +using namespace rtl; +using namespace formula; +using namespace com::sun::star; +using namespace xmloff::token; +using ::std::vector; +using ::com::sun::star::uno::UNO_QUERY; + +//---------------------------------------------------------------------------- + +namespace +{ +OUString lcl_RangeSequenceToString( + const uno::Sequence< OUString > & rRanges, + const uno::Reference< chart2::data::XRangeXMLConversion > & xFormatConverter ) +{ + OUStringBuffer aResult; + const sal_Int32 nMaxIndex( rRanges.getLength() - 1 ); + const sal_Unicode cSep( sal_Char(' ')); + for( sal_Int32 i=0; i<=nMaxIndex; ++i ) + { + OUString aRange( rRanges[i] ); + if( xFormatConverter.is()) + aRange = xFormatConverter->convertRangeToXML( aRange ); + aResult.append( aRange ); + if( i < nMaxIndex ) + aResult.append( cSep ); + } + return aResult.makeStringAndClear(); +} + +OUString lcl_GetRawString( ScDocument* pDoc, const ScAddress& rPos ) +{ + // return text/edit cell string content, with line feeds in edit cells + + String aVal; // document uses tools-strings + if (pDoc) + { + ScBaseCell* pCell = pDoc->GetCell( rPos ); + if (pCell) + { + CellType eType = pCell->GetCellType(); + if ( eType == CELLTYPE_STRING ) + static_cast<ScStringCell*>(pCell)->GetString(aVal); // string cell: content + else if ( eType == CELLTYPE_EDIT ) + { + // edit cell: text with line breaks + const EditTextObject* pData = static_cast<ScEditCell*>(pCell)->GetData(); + if (pData) + { + EditEngine& rEngine = pDoc->GetEditEngine(); + rEngine.SetText( *pData ); + aVal = rEngine.GetText( LINEEND_LF ); + } + } + } + } + return aVal; +} +} // anonymous namespace + +//---------------------------------------------------------------------------- + +OUString SAL_CALL ScXMLOOoExport_getImplementationName() throw() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLExporter" ) ); +} + +uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_getSupportedServiceNames() throw() +{ + const rtl::OUString aServiceName( ScXMLOOoExport_getImplementationName() ); + return uno::Sequence< rtl::OUString >( &aServiceName, 1 ); +} + +uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_createInstance( + const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception ) +{ + // #110680# + // return (cppu::OWeakObject*)new ScXMLExport(EXPORT_ALL); + return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_ALL ); +} + +OUString SAL_CALL ScXMLOOoExport_Meta_getImplementationName() throw() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLMetaExporter" ) ); +} + +uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_Meta_getSupportedServiceNames() throw() +{ + const rtl::OUString aServiceName( ScXMLOOoExport_Meta_getImplementationName() ); + return uno::Sequence< rtl::OUString > ( &aServiceName, 1 ); +} + +uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_Meta_createInstance( + const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception ) +{ + // #110680# + // return (cppu::OWeakObject*)new ScXMLExport(EXPORT_META); + return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_META ); +} + +OUString SAL_CALL ScXMLOOoExport_Styles_getImplementationName() throw() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLStylesExporter" ) ); +} + +uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_Styles_getSupportedServiceNames() throw() +{ + const rtl::OUString aServiceName( ScXMLOOoExport_Styles_getImplementationName() ); + return uno::Sequence< rtl::OUString > ( &aServiceName, 1 ); +} + +uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_Styles_createInstance( + const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception ) +{ + // #110680# + // return (cppu::OWeakObject*)new ScXMLExport(EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS); + return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS); +} + +OUString SAL_CALL ScXMLOOoExport_Content_getImplementationName() throw() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLContentExporter" ) ); +} + +uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_Content_getSupportedServiceNames() throw() +{ + const rtl::OUString aServiceName( ScXMLOOoExport_Content_getImplementationName() ); + return uno::Sequence< rtl::OUString > ( &aServiceName, 1 ); +} + +uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_Content_createInstance( + const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception ) +{ + // #110680# + // return (cppu::OWeakObject*)new ScXMLExport(EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS); + return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS); +} + +OUString SAL_CALL ScXMLOOoExport_Settings_getImplementationName() throw() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLSettingsExporter" ) ); +} + +uno::Sequence< rtl::OUString > SAL_CALL ScXMLOOoExport_Settings_getSupportedServiceNames() throw() +{ + const rtl::OUString aServiceName( ScXMLOOoExport_Settings_getImplementationName() ); + return uno::Sequence< rtl::OUString > ( &aServiceName, 1 ); +} + +uno::Reference< uno::XInterface > SAL_CALL ScXMLOOoExport_Settings_createInstance( + const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception ) +{ + // #110680# + // return (cppu::OWeakObject*)new ScXMLExport(EXPORT_SETTINGS); + return (cppu::OWeakObject*)new ScXMLExport( rSMgr, EXPORT_SETTINGS ); +} + +// Oasis Filter + +OUString SAL_CALL ScXMLOasisExport_getImplementationName() throw() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisExporter" ) ); +} + +uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_getSupportedServiceNames() throw() +{ + const rtl::OUString aServiceName( ScXMLOasisExport_getImplementationName() ); + const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 ); + return aSeq; +} + +uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_createInstance( + const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception ) +{ + return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_ALL|EXPORT_OASIS); +} + +OUString SAL_CALL ScXMLOasisExport_Meta_getImplementationName() throw() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisMetaExporter" ) ); +} + +uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_Meta_getSupportedServiceNames() throw() +{ + const rtl::OUString aServiceName( ScXMLOasisExport_Meta_getImplementationName() ); + const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 ); + return aSeq; +} + +uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_Meta_createInstance( + const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception ) +{ + return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_META|EXPORT_OASIS); +} + +OUString SAL_CALL ScXMLOasisExport_Styles_getImplementationName() throw() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisStylesExporter" ) ); +} + +uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_Styles_getSupportedServiceNames() throw() +{ + const rtl::OUString aServiceName( ScXMLOasisExport_Styles_getImplementationName() ); + const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 ); + return aSeq; +} + +uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_Styles_createInstance( + const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception ) +{ + return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS|EXPORT_OASIS); +} + +OUString SAL_CALL ScXMLOasisExport_Content_getImplementationName() throw() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisContentExporter" ) ); +} + +uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_Content_getSupportedServiceNames() throw() +{ + const rtl::OUString aServiceName( ScXMLOasisExport_Content_getImplementationName() ); + const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 ); + return aSeq; +} + +uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_Content_createInstance( + const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception ) +{ + return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS|EXPORT_OASIS); +} + +OUString SAL_CALL ScXMLOasisExport_Settings_getImplementationName() throw() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisSettingsExporter" ) ); +} + +uno::Sequence< rtl::OUString > SAL_CALL ScXMLOasisExport_Settings_getSupportedServiceNames() throw() +{ + const rtl::OUString aServiceName( ScXMLOasisExport_Settings_getImplementationName() ); + const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 ); + return aSeq; +} + +uno::Reference< uno::XInterface > SAL_CALL ScXMLOasisExport_Settings_createInstance( + const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception ) +{ + return (cppu::OWeakObject*)new ScXMLExport(rSMgr, EXPORT_SETTINGS|EXPORT_OASIS); +} +//---------------------------------------------------------------------------- + +class ScXMLShapeExport : public XMLShapeExport +{ +public: + ScXMLShapeExport(SvXMLExport& rExp) : XMLShapeExport(rExp) {} + ~ScXMLShapeExport(); + + /** is called before a shape element for the given XShape is exported */ + virtual void onExport( const uno::Reference < drawing::XShape >& xShape ); +}; + +ScXMLShapeExport::~ScXMLShapeExport() +{ +} + +void ScXMLShapeExport::onExport( const uno::Reference < drawing::XShape >& xShape ) +{ + uno::Reference< beans::XPropertySet > xShapeProp( xShape, uno::UNO_QUERY ); + if( xShapeProp.is() ) + { + sal_Int16 nLayerID = 0; + if( (xShapeProp->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_LAYERID ))) >>= nLayerID) && (nLayerID == SC_LAYER_BACK) ) + GetExport().AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_BACKGROUND, XML_TRUE); + } +} + +//---------------------------------------------------------------------------- + +sal_Int16 ScXMLExport::GetFieldUnit() +{ + com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> xProperties( + comphelper::getProcessServiceFactory()->createInstance( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.GlobalSheetSettings" )) ), + com::sun::star::uno::UNO_QUERY); + if (xProperties.is()) + { + sal_Int16 nFieldUnit = 0; + if (xProperties->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Metric"))) >>= nFieldUnit) + return nFieldUnit; + } + return 0; +} + + +// #110680# +ScXMLExport::ScXMLExport( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory, + const sal_uInt16 nExportFlag) +: SvXMLExport( xServiceFactory, SvXMLUnitConverter::GetMapUnit(GetFieldUnit()), XML_SPREADSHEET, nExportFlag ), + pDoc(NULL), + nSourceStreamPos(0), + pNumberFormatAttributesExportHelper(NULL), + pSharedData(NULL), + pColumnStyles(NULL), + pRowStyles(NULL), + pCellStyles(NULL), + pRowFormatRanges(NULL), + aTableStyles(), + pGroupColumns (NULL), + pGroupRows (NULL), + pDefaults(NULL), + pChartListener(NULL), + pCurrentCell(NULL), + pMergedRangesContainer(NULL), + pValidationsContainer(NULL), + pCellsItr(NULL), + pChangeTrackingExportHelper(NULL), + sLayerID(RTL_CONSTASCII_USTRINGPARAM( SC_LAYERID )), + sCaptionShape(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.CaptionShape")), + nOpenRow(-1), + nProgressCount(0), + nCurrentTable(0), + bHasRowHeader(sal_False), + bRowHeaderOpen(sal_False), + mbShowProgress( sal_False ) +{ + if (getExportFlags() & EXPORT_CONTENT) + { + pGroupColumns = new ScMyOpenCloseColumnRowGroup(*this, XML_TABLE_COLUMN_GROUP); + pGroupRows = new ScMyOpenCloseColumnRowGroup(*this, XML_TABLE_ROW_GROUP); + pColumnStyles = new ScColumnStyles(); + pRowStyles = new ScRowStyles(); + pRowFormatRanges = new ScRowFormatRanges(); + pMergedRangesContainer = new ScMyMergedRangesContainer(); + pValidationsContainer = new ScMyValidationsContainer(); + pCellsItr = new ScMyNotEmptyCellsIterator(*this); + pDefaults = new ScMyDefaultStyles(); + } + pCellStyles = new ScFormatRangeStyles(); + + // document is not set here - create ScChangeTrackingExportHelper later + + xScPropHdlFactory = new XMLScPropHdlFactory; + xCellStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScCellStylesProperties, xScPropHdlFactory); + xColumnStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScColumnStylesProperties, xScPropHdlFactory); + xRowStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScRowStylesProperties, xScPropHdlFactory); + xTableStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScTableStylesProperties, xScPropHdlFactory); + xCellStylesExportPropertySetMapper = new ScXMLCellExportPropertyMapper(xCellStylesPropertySetMapper); + xCellStylesExportPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(*this)); + xColumnStylesExportPropertySetMapper = new ScXMLColumnExportPropertyMapper(xColumnStylesPropertySetMapper); + xRowStylesExportPropertySetMapper = new ScXMLRowExportPropertyMapper(xRowStylesPropertySetMapper); + xTableStylesExportPropertySetMapper = new ScXMLTableExportPropertyMapper(xTableStylesPropertySetMapper); + + GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_CELL, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME)), + xCellStylesExportPropertySetMapper, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX))); + GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_COLUMN, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_NAME)), + xColumnStylesExportPropertySetMapper, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX))); + GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_ROW, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_ROW_STYLES_NAME)), + xRowStylesExportPropertySetMapper, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX))); + GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_TABLE, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_TABLE_STYLES_NAME)), + xTableStylesExportPropertySetMapper, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_TABLE_STYLES_PREFIX))); + + if( (getExportFlags() & (EXPORT_STYLES|EXPORT_AUTOSTYLES|EXPORT_MASTERSTYLES|EXPORT_CONTENT) ) != 0 ) + { + // This name is reserved for the external ref cache tables. This + // should not conflict with user-defined styles since this name is + // used for a table style which is not available in the UI. + sExternalRefTabStyleName = rtl::OUString::createFromAscii("ta_extref"); + GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_TABLE, sExternalRefTabStyleName); + + sAttrName = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_NAME)); + sAttrStyleName = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_STYLE_NAME)); + sAttrColumnsRepeated = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_NUMBER_COLUMNS_REPEATED)); + sAttrFormula = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_FORMULA)); + sAttrStringValue = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_STRING_VALUE)); + sAttrValueType = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_VALUE_TYPE)); + sElemCell = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_CELL)); + sElemCoveredCell = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_COVERED_TABLE_CELL)); + sElemCol = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_COLUMN)); + sElemRow = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE_ROW)); + sElemTab = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_TABLE)); + sElemP = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TEXT, GetXMLToken(XML_P)); + } +} + + +ScXMLExport::~ScXMLExport() +{ + if (pGroupColumns) + delete pGroupColumns; + if (pGroupRows) + delete pGroupRows; + if (pColumnStyles) + delete pColumnStyles; + if (pRowStyles) + delete pRowStyles; + if (pCellStyles) + delete pCellStyles; + if (pRowFormatRanges) + delete pRowFormatRanges; + if (pMergedRangesContainer) + delete pMergedRangesContainer; + if (pValidationsContainer) + delete pValidationsContainer; + if (pChangeTrackingExportHelper) + delete pChangeTrackingExportHelper; + if (pChartListener) + delete pChartListener; + if (pCellsItr) + delete pCellsItr; + if (pDefaults) + delete pDefaults; + if (pNumberFormatAttributesExportHelper) + delete pNumberFormatAttributesExportHelper; +} + +void ScXMLExport::SetSourceStream( const uno::Reference<io::XInputStream>& xNewStream ) +{ + xSourceStream = xNewStream; + + if ( xSourceStream.is() ) + { + // make sure it's a plain UTF-8 stream as written by OOo itself + + const sal_Char pXmlHeader[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; + sal_Int32 nLen = strlen(pXmlHeader); + + uno::Sequence<sal_Int8> aFileStart(nLen); + sal_Int32 nRead = xSourceStream->readBytes( aFileStart, nLen ); + + if ( nRead != nLen || rtl_compareMemory( aFileStart.getConstArray(), pXmlHeader, nLen ) != 0 ) + { + // invalid - ignore stream, save normally + xSourceStream.clear(); + } + else + { + // keep track of the bytes already read + nSourceStreamPos = nRead; + + const ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetModel())->GetSheetSaveData(); + if (pSheetData) + { + // add the loaded namespaces to the name space map + + if ( !pSheetData->AddLoadedNamespaces( _GetNamespaceMap() ) ) + { + // conflicts in the namespaces - ignore the stream, save normally + xSourceStream.clear(); + } + } + } + } +} + +sal_Int32 ScXMLExport::GetNumberFormatStyleIndex(sal_Int32 nNumFmt) const +{ + NumberFormatIndexMap::const_iterator itr = aNumFmtIndexMap.find(nNumFmt); + if (itr == aNumFmtIndexMap.end()) + return -1; + + return itr->second; +} + +sal_Bool ScXMLExport::HasDrawPages(uno::Reference <sheet::XSpreadsheetDocument>& xDoc) +{ + uno::Reference <beans::XPropertySet> xDocProps( xDoc, uno::UNO_QUERY ); + return (xDocProps.is() && ::cppu::any2bool( xDocProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_HASDRAWPAGES))) )); +} + +void ScXMLExport::CollectSharedData(sal_Int32& nTableCount, sal_Int32& nShapesCount, const sal_Int32 nCellCount) +{ + if (GetModel().is()) + { + uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY ); + if ( xSpreadDoc.is()) + { + uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY ); + if ( xIndex.is() ) + { + nTableCount = xIndex->getCount(); + if (!pSharedData) + CreateSharedData(nTableCount); + pCellStyles->AddNewTable(nTableCount - 1); + pDoc->InitializeAllNoteCaptions( true ); + if (HasDrawPages(xSpreadDoc)) + { + rtl::OUString sCaptionPoint( RTL_CONSTASCII_USTRINGPARAM( "CaptionPoint" )); + for (SCTAB nTable = 0; nTable < nTableCount; ++nTable) + { + nCurrentTable = sal::static_int_cast<sal_uInt16>( nTable ); + uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(xIndex->getByIndex(nTable), uno::UNO_QUERY); + if (xDrawPageSupplier.is()) + { + uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPageSupplier->getDrawPage()); + ScMyDrawPage aDrawPage; + aDrawPage.bHasForms = sal_False; + aDrawPage.xDrawPage.set(xDrawPage); + pSharedData->AddDrawPage(aDrawPage, nTable); + uno::Reference<container::XIndexAccess> xShapesIndex (xDrawPage, uno::UNO_QUERY); + if (xShapesIndex.is()) + { + sal_Int32 nShapes(xShapesIndex->getCount()); + for (sal_Int32 nShape = 0; nShape < nShapes; ++nShape) + { + uno::Reference<drawing::XShape> xShape(xShapesIndex->getByIndex(nShape), uno::UNO_QUERY); + if (xShape.is()) + { + uno::Reference< beans::XPropertySet > xShapeProp( xShape, uno::UNO_QUERY ); + if( xShapeProp.is() ) + { + sal_Int16 nLayerID = 0; + if( xShapeProp->getPropertyValue(sLayerID) >>= nLayerID ) + { + if( (nLayerID == SC_LAYER_INTERN) || (nLayerID == SC_LAYER_HIDDEN) ) + CollectInternalShape( xShape ); + else + { + ++nShapesCount; + SvxShape* pShapeImp(SvxShape::getImplementation(xShape)); + if (pShapeImp) + { + SdrObject *pSdrObj(pShapeImp->GetSdrObject()); + if (pSdrObj) + { + if (ScDrawLayer::GetAnchor(pSdrObj) == SCA_CELL) + { + if (pDoc) + { + + awt::Point aPoint(xShape->getPosition()); + awt::Size aSize(xShape->getSize()); + rtl::OUString sType(xShape->getShapeType()); + Rectangle aRectangle(aPoint.X, aPoint.Y, aPoint.X + aSize.Width, aPoint.Y + aSize.Height); + if ( sType.equals(sCaptionShape) ) + { + awt::Point aRelativeCaptionPoint; + xShapeProp->getPropertyValue( sCaptionPoint ) >>= aRelativeCaptionPoint; + Point aCoreRelativeCaptionPoint(aRelativeCaptionPoint.X, aRelativeCaptionPoint.Y); + Point aCoreAbsoluteCaptionPoint(aPoint.X, aPoint.Y); + aCoreAbsoluteCaptionPoint += aCoreRelativeCaptionPoint; + aRectangle.Union(Rectangle(aCoreAbsoluteCaptionPoint, aCoreAbsoluteCaptionPoint)); + } + ScRange aRange(pDoc->GetRange(static_cast<SCTAB>(nTable), aRectangle)); + ScMyShape aMyShape; + aMyShape.aAddress = aRange.aStart; + aMyShape.aEndAddress = aRange.aEnd; + aMyShape.xShape = xShape; + pSharedData->AddNewShape(aMyShape); + pSharedData->SetLastColumn(nTable, aRange.aStart.Col()); + pSharedData->SetLastRow(nTable, aRange.aStart.Row()); + } + } + else + pSharedData->AddTableShape(nTable, xShape); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + sal_Int32 nRef(nCellCount + (2 * nTableCount) + (2 * nShapesCount)); + GetProgressBarHelper()->SetReference(nRef); + GetProgressBarHelper()->SetValue(0); +} + +void ScXMLExport::CollectShapesAutoStyles(const sal_Int32 nTableCount) +{ + // #i84077# To avoid compiler warnings about uninitialized aShapeItr, + // it's initialized using this dummy list. The iterator contains shapes + // from all sheets, so it can't be declared inside the nTable loop where + // it is used. + ScMyShapeList aDummyInitList; + + pSharedData->SortShapesContainer(); + pSharedData->SortNoteShapes(); + const ScMyShapeList* pShapeList(NULL); + ScMyShapeList::const_iterator aShapeItr = aDummyInitList.end(); + if (pSharedData->GetShapesContainer()) + { + pShapeList = pSharedData->GetShapesContainer()->GetShapes(); + aShapeItr = pShapeList->begin(); + } + if (pSharedData->HasDrawPage()) + { + for (SCTAB nTable = 0; nTable < nTableCount; ++nTable) + { + uno::Reference<drawing::XDrawPage> xDrawPage(pSharedData->GetDrawPage(nTable)); + uno::Reference<drawing::XShapes> xShapes (xDrawPage, uno::UNO_QUERY); + + if (xShapes.is()) + { + GetShapeExport()->seekShapes(xShapes); + uno::Reference< form::XFormsSupplier2 > xFormsSupplier( xDrawPage, uno::UNO_QUERY ); + if( xFormsSupplier.is() && xFormsSupplier->hasForms() ) + { + GetFormExport()->examineForms(xDrawPage); + pSharedData->SetDrawPageHasForms(nTable, sal_True); + } + ScMyTableShapes* pTableShapes(pSharedData->GetTableShapes()); + if (pTableShapes) + { + ScMyTableXShapes::iterator aItr((*pTableShapes)[nTable].begin()); + ScMyTableXShapes::iterator aEndItr((*pTableShapes)[nTable].end()); + while (aItr != aEndItr) + { + GetShapeExport()->collectShapeAutoStyles(*aItr); + IncrementProgressBar(sal_False); + ++aItr; + } + } + if (pShapeList) + { + ScMyShapeList::const_iterator aEndItr(pShapeList->end()); + while (aShapeItr != aEndItr && (static_cast<sal_Int32>(aShapeItr->aAddress.Tab()) == nTable)) + { + GetShapeExport()->collectShapeAutoStyles(aShapeItr->xShape); + IncrementProgressBar(sal_False); + ++aShapeItr; + } + } + const ScMyNoteShapeList* pNoteShapes = NULL; + ScMyNoteShapeList::const_iterator aNoteShapeItr; + ScMyNoteShapeList::const_iterator aNoteShapeEndItr; + if (pSharedData->GetNoteShapes()) + { + pNoteShapes = pSharedData->GetNoteShapes()->GetNotes(); + if (pNoteShapes) + { + aNoteShapeItr = pNoteShapes->begin(); + aNoteShapeEndItr = pNoteShapes->end(); + } + } + if (pNoteShapes) + { + while (aNoteShapeItr != aNoteShapeEndItr) + { + if (static_cast<sal_Int32>(aNoteShapeItr->aPos.Tab()) == nTable) + GetShapeExport()->collectShapeAutoStyles(aNoteShapeItr->xShape); + ++aNoteShapeItr; + } + } + } + } + } + pSharedData->SortNoteShapes(); // sort twice, because some more shapes are added +} + +void ScXMLExport::_ExportMeta() +{ + sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0); + sal_Int32 nTableCount(0); + sal_Int32 nShapesCount(0); + GetAutoStylePool()->ClearEntries(); + CollectSharedData(nTableCount, nShapesCount, nCellCount); + + uno::Sequence<beans::NamedValue> stats(3); + stats[0] = beans::NamedValue(::rtl::OUString::createFromAscii("TableCount"), + uno::makeAny(nTableCount)); + stats[1] = beans::NamedValue(::rtl::OUString::createFromAscii("CellCount"), + uno::makeAny(nCellCount)); + stats[2] = beans::NamedValue(::rtl::OUString::createFromAscii("ObjectCount"), + uno::makeAny(nShapesCount)); + + // update document statistics at the model + uno::Reference<document::XDocumentPropertiesSupplier> xPropSup(GetModel(), + uno::UNO_QUERY_THROW); + uno::Reference<document::XDocumentProperties> xDocProps( + xPropSup->getDocumentProperties()); + if (xDocProps.is()) { + xDocProps->setDocumentStatistics(stats); + } + + // export document properties + SvXMLExport::_ExportMeta(); +} + +void ScXMLExport::_ExportFontDecls() +{ + GetFontAutoStylePool(); // make sure the pool is created + SvXMLExport::_ExportFontDecls(); +} + +table::CellRangeAddress ScXMLExport::GetEndAddress(const uno::Reference<sheet::XSpreadsheet>& xTable, const sal_Int32 /* nTable */) +{ + table::CellRangeAddress aCellAddress; + uno::Reference<sheet::XSheetCellCursor> xCursor(xTable->createCursor()); + uno::Reference<sheet::XUsedAreaCursor> xUsedArea (xCursor, uno::UNO_QUERY); + uno::Reference<sheet::XCellRangeAddressable> xCellAddress (xCursor, uno::UNO_QUERY); + if (xUsedArea.is() && xCellAddress.is()) + { + xUsedArea->gotoEndOfUsedArea(sal_True); + aCellAddress = xCellAddress->getRangeAddress(); + } + return aCellAddress; +} + +void ScXMLExport::GetAreaLinks( uno::Reference< sheet::XSpreadsheetDocument>& xSpreadDoc, + ScMyAreaLinksContainer& rAreaLinks ) +{ + uno::Reference< beans::XPropertySet > xPropSet( xSpreadDoc, uno::UNO_QUERY ); + if( !xPropSet.is() ) return; + + uno::Reference< container::XIndexAccess > xLinksIAccess( xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_AREALINKS ) ) ), uno::UNO_QUERY); + if( xLinksIAccess.is() ) + { + const OUString sFilter( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FILTER ) ); + const OUString sFilterOpt( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FILTOPT ) ); + const OUString sURL( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_LINKURL ) ); + const OUString sRefresh( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_REFDELAY ) ); + + sal_Int32 nCount(xLinksIAccess->getCount()); + for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex ) + { + uno::Reference< sheet::XAreaLink > xAreaLink(xLinksIAccess->getByIndex( nIndex ), uno::UNO_QUERY); + if( xAreaLink.is() ) + { + ScMyAreaLink aAreaLink; + aAreaLink.aDestRange = xAreaLink->getDestArea(); + aAreaLink.sSourceStr = xAreaLink->getSourceArea(); + uno::Reference< beans::XPropertySet > xLinkProp( xAreaLink, uno::UNO_QUERY ); + if( xLinkProp.is() ) + { + xLinkProp->getPropertyValue( sFilter ) >>= aAreaLink.sFilter; + xLinkProp->getPropertyValue( sFilterOpt ) >>= aAreaLink.sFilterOptions; + xLinkProp->getPropertyValue( sURL ) >>= aAreaLink.sURL; + xLinkProp->getPropertyValue( sRefresh ) >>= aAreaLink.nRefresh; + } + rAreaLinks.AddNewAreaLink( aAreaLink ); + } + } + } + rAreaLinks.Sort(); +} + +// core implementation +void ScXMLExport::GetDetectiveOpList( ScMyDetectiveOpContainer& rDetOp ) +{ + if (pDoc) + { + ScDetOpList* pOpList(pDoc->GetDetOpList()); + if( pOpList ) + { + sal_uInt32 nCount(pOpList->Count()); + for( sal_uInt32 nIndex = 0; nIndex < nCount; ++nIndex ) + { + ScDetOpData* pDetData(pOpList->GetObject( static_cast<sal_uInt16>(nIndex) )); + if( pDetData ) + { + const ScAddress& rDetPos = pDetData->GetPos(); + SCTAB nTab = rDetPos.Tab(); + if ( nTab < pDoc->GetTableCount() ) + { + rDetOp.AddOperation( pDetData->GetOperation(), rDetPos, nIndex ); + + // #123981# cells with detective operations are written even if empty + pSharedData->SetLastColumn( nTab, rDetPos.Col() ); + pSharedData->SetLastRow( nTab, rDetPos.Row() ); + } + } + } + rDetOp.Sort(); + } + } +} + +void ScXMLExport::WriteSingleColumn(const sal_Int32 nRepeatColumns, const sal_Int32 nStyleIndex, + const sal_Int32 nIndex, const sal_Bool bIsAutoStyle, const sal_Bool bIsVisible) +{ + CheckAttrList(); + AddAttribute(sAttrStyleName, *pColumnStyles->GetStyleNameByIndex(nStyleIndex)); + if (!bIsVisible) + AddAttribute(XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_COLLAPSE); + if (nRepeatColumns > 1) + { + OUString sOUEndCol(OUString::valueOf(static_cast <sal_Int32> (nRepeatColumns))); + AddAttribute(sAttrColumnsRepeated, sOUEndCol); + } + if (nIndex != -1) + AddAttribute(XML_NAMESPACE_TABLE, XML_DEFAULT_CELL_STYLE_NAME, *pCellStyles->GetStyleNameByIndex(nIndex, bIsAutoStyle)); + SvXMLElementExport aElemC(*this, sElemCol, sal_True, sal_True); +} + +void ScXMLExport::WriteColumn(const sal_Int32 nColumn, const sal_Int32 nRepeatColumns, + const sal_Int32 nStyleIndex, const sal_Bool bIsVisible) +{ + sal_Int32 nRepeat(1); + sal_Int32 nPrevIndex((*pDefaults->GetColDefaults())[nColumn].nIndex); + sal_Bool bPrevAutoStyle((*pDefaults->GetColDefaults())[nColumn].bIsAutoStyle); + for (sal_Int32 i = nColumn + 1; i < nColumn + nRepeatColumns; ++i) + { + if (((*pDefaults->GetColDefaults())[i].nIndex != nPrevIndex) || + ((*pDefaults->GetColDefaults())[i].bIsAutoStyle != bPrevAutoStyle)) + { + WriteSingleColumn(nRepeat, nStyleIndex, nPrevIndex, bPrevAutoStyle, bIsVisible); + nPrevIndex = (*pDefaults->GetColDefaults())[i].nIndex; + bPrevAutoStyle = (*pDefaults->GetColDefaults())[i].bIsAutoStyle; + nRepeat = 1; + } + else + ++nRepeat; + } + WriteSingleColumn(nRepeat, nStyleIndex, nPrevIndex, bPrevAutoStyle, bIsVisible); +} + +void ScXMLExport::OpenHeaderColumn() +{ + StartElement( XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, sal_True ); +} + +void ScXMLExport::CloseHeaderColumn() +{ + EndElement(XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, sal_True); +} + +void ScXMLExport::ExportColumns(const sal_Int32 nTable, const table::CellRangeAddress& aColumnHeaderRange, const sal_Bool bHasColumnHeader) +{ + sal_Int32 nColsRepeated (1); + rtl::OUString sParent; + sal_Int32 nIndex; + sal_Int32 nPrevColumn(0); + sal_Bool bPrevIsVisible (sal_True); + sal_Bool bWasHeader (sal_False); + sal_Bool bIsHeader (sal_False); + sal_Bool bIsClosed (sal_True); + sal_Bool bIsFirst (sal_False); + sal_Int32 nPrevIndex (-1); + sal_Int32 nColumn; + for (nColumn = 0; nColumn <= pSharedData->GetLastColumn(nTable); ++nColumn) + { + CheckAttrList(); + sal_Bool bIsVisible(sal_True); + nIndex = pColumnStyles->GetStyleNameIndex(nTable, nColumn, bIsVisible); + + bIsHeader = bHasColumnHeader && (aColumnHeaderRange.StartColumn <= nColumn) && (nColumn <= aColumnHeaderRange.EndColumn); + if (bIsHeader != bWasHeader) + { + if (bIsHeader) + { + bIsFirst = sal_False; + if (nColumn > 0) + { + WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible); + if (pGroupColumns->IsGroupEnd(nColumn - 1)) + pGroupColumns->CloseGroups(nColumn - 1); + } + bPrevIsVisible = bIsVisible; + nPrevIndex = nIndex; + nPrevColumn = nColumn; + nColsRepeated = 1; + bIsFirst = sal_True; + if(pGroupColumns->IsGroupStart(nColumn)) + pGroupColumns->OpenGroups(nColumn); + OpenHeaderColumn(); + bWasHeader = sal_True; + bIsClosed = sal_False; + } + else + { + WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible); + CloseHeaderColumn(); + if (pGroupColumns->IsGroupEnd(nColumn - 1)) + pGroupColumns->CloseGroups(nColumn - 1); + if(pGroupColumns->IsGroupStart(nColumn)) + pGroupColumns->OpenGroups(nColumn); + bPrevIsVisible = bIsVisible; + nPrevIndex = nIndex; + nPrevColumn = nColumn; + nColsRepeated = 1; + bWasHeader = sal_False; + bIsClosed = sal_True; + } + } + else if (nColumn == 0) + { + if (pGroupColumns->IsGroupStart(nColumn)) + pGroupColumns->OpenGroups(nColumn); + bPrevIsVisible = bIsVisible; + nPrevIndex = nIndex; + bIsFirst = sal_True; + } + else if ((bIsVisible == bPrevIsVisible) && (nIndex == nPrevIndex) && + !pGroupColumns->IsGroupStart(nColumn) && !pGroupColumns->IsGroupEnd(nColumn - 1)) + ++nColsRepeated; + else + { + bIsFirst = sal_False; + WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible); + if (pGroupColumns->IsGroupEnd(nColumn - 1)) + { + if (bIsHeader) + CloseHeaderColumn(); + pGroupColumns->CloseGroups(nColumn - 1); + if (bIsHeader) + OpenHeaderColumn(); + } + if (pGroupColumns->IsGroupStart(nColumn)) + { + if (bIsHeader) + CloseHeaderColumn(); + pGroupColumns->OpenGroups(nColumn); + if (bIsHeader) + OpenHeaderColumn(); + } + bPrevIsVisible = bIsVisible; + nPrevIndex = nIndex; + nPrevColumn = nColumn; + nColsRepeated = 1; + } + } + //if (nColsRepeated > 1 || bIsFirst) + WriteColumn(nPrevColumn, nColsRepeated, nPrevIndex, bPrevIsVisible); + if (!bIsClosed) + CloseHeaderColumn(); + if (pGroupColumns->IsGroupEnd(nColumn - 1)) + pGroupColumns->CloseGroups(nColumn - 1); +} + +void ScXMLExport::ExportExternalRefCacheStyles() +{ + sal_Int32 nEntryIndex = GetCellStylesPropertySetMapper()->FindEntryIndex( + "NumberFormat", XML_NAMESPACE_STYLE, OUString::createFromAscii("data-style-name")); + + if (nEntryIndex < 0) + // No entry index for the number format is found. + return; + + ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager(); + if (!pRefMgr->hasExternalData()) + // No external reference data cached. + return; + + // Export each unique number format used in the external ref cache. + vector<sal_uInt32> aNumFmts; + pRefMgr->getAllCachedNumberFormats(aNumFmts); + const OUString aDefaultStyle = OUString::createFromAscii("Default").intern(); + for (vector<sal_uInt32>::const_iterator itr = aNumFmts.begin(), itrEnd = aNumFmts.end(); + itr != itrEnd; ++itr) + { + sal_Int32 nNumFmt = static_cast<sal_Int32>(*itr); + + addDataStyle(nNumFmt); + + uno::Any aVal; + aVal <<= nNumFmt; + vector<XMLPropertyState> aProps; + aProps.push_back(XMLPropertyState(nEntryIndex, aVal)); + aVal <<= aDefaultStyle; + aProps.push_back(XMLPropertyState(nEntryIndex, aVal)); + + OUString aName; + sal_Int32 nIndex; + if (GetAutoStylePool()->Add(aName, XML_STYLE_FAMILY_TABLE_CELL, aDefaultStyle, aProps)) + { + OUString* pTemp(new OUString(aName)); + if (!pCellStyles->AddStyleName(pTemp, nIndex, true)) + delete pTemp; + } + else + { + sal_Bool bIsAuto; + nIndex = pCellStyles->GetIndexOfStyleName( + aName, OUString::createFromAscii(XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX), bIsAuto); + } + + // store the number format to index mapping for later use. + aNumFmtIndexMap.insert(NumberFormatIndexMap::value_type(nNumFmt, nIndex)); + } +} + +void ScXMLExport::WriteRowContent() +{ + ScMyRowFormatRange aRange; + sal_Int32 nIndex(-1); +#ifdef DBG_UTIL + sal_Int32 nPrevCol(0); +#endif + sal_Int32 nCols(0); + sal_Int32 nPrevValidationIndex(-1); + sal_Bool bIsAutoStyle(sal_True); + sal_Bool bIsFirst(sal_True); + while (pRowFormatRanges->GetNext(aRange)) + { +#ifdef DBG_UTIL + DBG_ASSERT(bIsFirst || (!bIsFirst && (nPrevCol + nCols == aRange.nStartColumn)), "here are some columns missing"); +#endif + if (bIsFirst) + { + nIndex = aRange.nIndex; + nPrevValidationIndex = aRange.nValidationIndex; + bIsAutoStyle = aRange.bIsAutoStyle; + nCols = aRange.nRepeatColumns; + bIsFirst = sal_False; +#ifdef DBG_UTIL + nPrevCol = aRange.nStartColumn; +#endif + } + else + { + if (((aRange.nIndex == nIndex && aRange.bIsAutoStyle == bIsAutoStyle) || + (aRange.nIndex == nIndex && nIndex == -1)) && + nPrevValidationIndex == aRange.nValidationIndex) + nCols += aRange.nRepeatColumns; + else + { + if (nIndex != -1) + AddAttribute(sAttrStyleName, *pCellStyles->GetStyleNameByIndex(nIndex, bIsAutoStyle)); + if (nPrevValidationIndex > -1) + AddAttribute(XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, pValidationsContainer->GetValidationName(nPrevValidationIndex)); + if (nCols > 1) + { + rtl::OUStringBuffer aBuf; + GetMM100UnitConverter().convertNumber(aBuf, nCols); + AddAttribute(sAttrColumnsRepeated, aBuf.makeStringAndClear()); + } + SvXMLElementExport aElemC(*this, sElemCell, sal_True, sal_True); + nIndex = aRange.nIndex; + bIsAutoStyle = aRange.bIsAutoStyle; + nCols = aRange.nRepeatColumns; + nPrevValidationIndex = aRange.nValidationIndex; +#ifdef DBG_UTIL + nPrevCol = aRange.nStartColumn; +#endif + } + } + } + if (!bIsFirst) + { + table::CellAddress aCellAddress; + if (nIndex != -1) + AddAttribute(sAttrStyleName, *pCellStyles->GetStyleNameByIndex(nIndex, bIsAutoStyle)); + if (nPrevValidationIndex > -1) + AddAttribute(XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, pValidationsContainer->GetValidationName(nPrevValidationIndex)); + if (nCols > 1) + { + rtl::OUStringBuffer aBuf; + GetMM100UnitConverter().convertNumber(aBuf, nCols); + AddAttribute(sAttrColumnsRepeated, aBuf.makeStringAndClear()); + } + SvXMLElementExport aElemC(*this, sElemCell, sal_True, sal_True); + } +} + +void ScXMLExport::WriteRowStartTag(sal_Int32 nRow, const sal_Int32 nIndex, + const sal_Int8 nFlag, const sal_Int32 nEqualRows) +{ + AddAttribute(sAttrStyleName, *pRowStyles->GetStyleNameByIndex(nIndex)); + if (nFlag) + if (nFlag & CR_HIDDEN) + { + if (nFlag & CR_FILTERED) + AddAttribute(XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_FILTER); + else + AddAttribute(XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_COLLAPSE); + } + if (nEqualRows > 1) + { + rtl::OUStringBuffer aBuf; + GetMM100UnitConverter().convertNumber(aBuf, nEqualRows); + AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, aBuf.makeStringAndClear()); + } + + const ScMyDefaultStyleList& rRowDefaults = *pDefaults->GetRowDefaults(); + if ( nRow >= sal::static_int_cast<sal_Int32>( rRowDefaults.size() ) ) + { + // #123981# used to happen with detective operations - if there are more cases, use the last row's style + DBG_ERRORFILE("WriteRowStartTag: not enough defaults"); + nRow = rRowDefaults.size() - 1; + } + sal_Int32 nCellStyleIndex(rRowDefaults[nRow].nIndex); + if (nCellStyleIndex != -1) + AddAttribute(XML_NAMESPACE_TABLE, XML_DEFAULT_CELL_STYLE_NAME, + *pCellStyles->GetStyleNameByIndex(nCellStyleIndex, + (*pDefaults->GetRowDefaults())[nRow].bIsAutoStyle)); + StartElement( sElemRow, sal_True); +} + +void ScXMLExport::OpenHeaderRows() +{ + StartElement( XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, sal_True); + bRowHeaderOpen = sal_True; +} + +void ScXMLExport::CloseHeaderRows() +{ + EndElement(XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, sal_True); +} + +void ScXMLExport::OpenNewRow(const sal_Int32 nIndex, const sal_Int8 nFlag, const sal_Int32 nStartRow, const sal_Int32 nEqualRows) +{ + nOpenRow = nStartRow; + if (pGroupRows->IsGroupStart(nStartRow)) + { + if (bHasRowHeader && bRowHeaderOpen) + CloseHeaderRows(); + pGroupRows->OpenGroups(nStartRow); + if (bHasRowHeader && bRowHeaderOpen) + OpenHeaderRows(); + } + if (bHasRowHeader && !bRowHeaderOpen && nStartRow >= aRowHeaderRange.StartRow && nStartRow <= aRowHeaderRange.EndRow) + { + if (nStartRow == aRowHeaderRange.StartRow) + OpenHeaderRows(); + sal_Int32 nEquals; + if (aRowHeaderRange.EndRow < nStartRow + nEqualRows - 1) + nEquals = aRowHeaderRange.EndRow - nStartRow + 1; + else + nEquals = nEqualRows; + WriteRowStartTag(nStartRow, nIndex, nFlag, nEquals); + nOpenRow = nStartRow + nEquals - 1; + if (nEquals < nEqualRows) + { + CloseRow(nStartRow + nEquals - 1); + WriteRowStartTag(nStartRow, nIndex, nFlag, nEqualRows - nEquals); + nOpenRow = nStartRow + nEqualRows - 1; + } + } + else + WriteRowStartTag(nStartRow, nIndex, nFlag, nEqualRows); +} + +void ScXMLExport::OpenAndCloseRow(const sal_Int32 nIndex, const sal_Int8 nFlag, + const sal_Int32 nStartRow, const sal_Int32 nEqualRows) +{ + OpenNewRow(nIndex, nFlag, nStartRow, nEqualRows); + WriteRowContent(); + CloseRow(nStartRow + nEqualRows - 1); + pRowFormatRanges->Clear(); +} + +void ScXMLExport::OpenRow(const sal_Int32 nTable, const sal_Int32 nStartRow, const sal_Int32 nRepeatRow) +{ + if (nRepeatRow > 1) + { + sal_Int32 nPrevIndex(0), nIndex; + sal_Int8 nPrevFlag(0); + sal_Int8 nFlag(0); + sal_Int32 nEqualRows(1); + sal_Int32 nEndRow(nStartRow + nRepeatRow); + sal_Int32 nRow; + for (nRow = nStartRow; nRow < nEndRow; ++nRow) + { + if (nRow == nStartRow) + { + nPrevIndex = pRowStyles->GetStyleNameIndex(nTable, nRow); + if (pDoc) + nPrevFlag = (pDoc->GetRowFlags(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTable))) & (CR_HIDDEN | CR_FILTERED); + } + else + { + nIndex = pRowStyles->GetStyleNameIndex(nTable, nRow); + if (pDoc) + nFlag = (pDoc->GetRowFlags(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTable))) & (CR_HIDDEN | CR_FILTERED); + if (nIndex == nPrevIndex && nFlag == nPrevFlag && + !(bHasRowHeader && ((nRow == aRowHeaderRange.StartRow) || (nRow - 1 == aRowHeaderRange.EndRow))) && + !(pGroupRows->IsGroupStart(nRow)) && + !(pGroupRows->IsGroupEnd(nRow - 1))) + ++nEqualRows; + else + { + if (nRow < nEndRow) + { + ScRowFormatRanges* pTempRowFormatRanges = new ScRowFormatRanges(pRowFormatRanges); + OpenAndCloseRow(nPrevIndex, nPrevFlag, nRow - nEqualRows, nEqualRows); + delete pRowFormatRanges; + pRowFormatRanges = pTempRowFormatRanges; + } + else + OpenAndCloseRow(nPrevIndex, nPrevFlag, nRow - nEqualRows, nEqualRows); + nEqualRows = 1; + nPrevIndex = nIndex; + nPrevFlag = nFlag; + } + } + } + OpenNewRow(nPrevIndex, nPrevFlag, nRow - nEqualRows, nEqualRows); + } + else + { + sal_Int32 nIndex = pRowStyles->GetStyleNameIndex(nTable, nStartRow); + sal_Int8 nFlag(0); + if (pDoc) + nFlag = (pDoc->GetRowFlags(static_cast<SCROW>(nStartRow), static_cast<SCTAB>(nTable))) & (CR_HIDDEN | CR_FILTERED); + OpenNewRow(nIndex, nFlag, nStartRow, 1); + } + nOpenRow = nStartRow + nRepeatRow - 1; +} + +void ScXMLExport::CloseRow(const sal_Int32 nRow) +{ + if (nOpenRow > -1) + { + EndElement(sElemRow, sal_True); + if (bHasRowHeader && nRow == aRowHeaderRange.EndRow) + { + CloseHeaderRows(); + bRowHeaderOpen = sal_False; + } + if (pGroupRows->IsGroupEnd(nRow)) + { + if (bHasRowHeader && bRowHeaderOpen) + CloseHeaderRows(); + pGroupRows->CloseGroups(nRow); + if (bHasRowHeader && bRowHeaderOpen) + OpenHeaderRows(); + } + } + nOpenRow = -1; +} + +void ScXMLExport::ExportFormatRanges(const sal_Int32 nStartCol, const sal_Int32 nStartRow, + const sal_Int32 nEndCol, const sal_Int32 nEndRow, const sal_Int32 nSheet) +{ + pRowFormatRanges->Clear(); + if (nStartRow == nEndRow) + { + pCellStyles->GetFormatRanges(nStartCol, nEndCol, nStartRow, nSheet, pRowFormatRanges); + if (nOpenRow == - 1) + OpenRow(nSheet, nStartRow, 1); + WriteRowContent(); + pRowFormatRanges->Clear(); + } + else + { + if (nOpenRow > -1) + { + pCellStyles->GetFormatRanges(nStartCol, pSharedData->GetLastColumn(nSheet), nStartRow, nSheet, pRowFormatRanges); + WriteRowContent(); + CloseRow(nStartRow); + sal_Int32 nRows(1); + sal_Int32 nTotalRows(nEndRow - nStartRow + 1 - 1); + while (nRows < nTotalRows) + { + pRowFormatRanges->Clear(); + pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges); + sal_Int32 nMaxRows = pRowFormatRanges->GetMaxRows(); + DBG_ASSERT(nMaxRows, "something wents wrong"); + if (nMaxRows >= nTotalRows - nRows) + { + OpenRow(nSheet, nStartRow + nRows, nTotalRows - nRows); + nRows += nTotalRows - nRows; + } + else + { + OpenRow(nSheet, nStartRow + nRows, nMaxRows); + nRows += nMaxRows; + } + if (!pRowFormatRanges->GetSize()) + pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges); + WriteRowContent(); + CloseRow(nStartRow + nRows - 1); + } + if (nTotalRows == 1) + CloseRow(nStartRow); + OpenRow(nSheet, nEndRow, 1); + pRowFormatRanges->Clear(); + pCellStyles->GetFormatRanges(0, nEndCol, nEndRow, nSheet, pRowFormatRanges); + WriteRowContent(); + } + else + { + sal_Int32 nRows(0); + sal_Int32 nTotalRows(nEndRow - nStartRow + 1 - 1); + while (nRows < nTotalRows) + { + pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges); + sal_Int32 nMaxRows = pRowFormatRanges->GetMaxRows(); + if (nMaxRows >= nTotalRows - nRows) + { + OpenRow(nSheet, nStartRow + nRows, nTotalRows - nRows); + nRows += nTotalRows - nRows; + } + else + { + OpenRow(nSheet, nStartRow + nRows, nMaxRows); + nRows += nMaxRows; + } + if (!pRowFormatRanges->GetSize()) + pCellStyles->GetFormatRanges(0, pSharedData->GetLastColumn(nSheet), nStartRow + nRows, nSheet, pRowFormatRanges); + WriteRowContent(); + CloseRow(nStartRow + nRows - 1); + } + OpenRow(nSheet, nEndRow, 1); + pRowFormatRanges->Clear(); + pCellStyles->GetFormatRanges(0, nEndCol, nEndRow, nSheet, pRowFormatRanges); + WriteRowContent(); + } + } +} + +void ScXMLExport::GetColumnRowHeader(sal_Bool& rHasColumnHeader, table::CellRangeAddress& rColumnHeaderRange, + sal_Bool& rHasRowHeader, table::CellRangeAddress& rRowHeaderRange, + rtl::OUString& rPrintRanges) const +{ + uno::Reference <sheet::XPrintAreas> xPrintAreas (xCurrentTable, uno::UNO_QUERY); + if (xPrintAreas.is()) + { + rHasRowHeader = xPrintAreas->getPrintTitleRows(); + rHasColumnHeader = xPrintAreas->getPrintTitleColumns(); + rRowHeaderRange = xPrintAreas->getTitleRows(); + rColumnHeaderRange = xPrintAreas->getTitleColumns(); + uno::Sequence< table::CellRangeAddress > aRangeList( xPrintAreas->getPrintAreas() ); + ScRangeStringConverter::GetStringFromRangeList( rPrintRanges, aRangeList, pDoc, FormulaGrammar::CONV_OOO ); + } +} + +void ScXMLExport::FillFieldGroup(ScOutlineArray* pFields, ScMyOpenCloseColumnRowGroup* pGroups) +{ + sal_Int32 nDepth(pFields->GetDepth()); + for(sal_Int32 i = 0; i < nDepth; ++i) + { + sal_Int32 nFields = pFields->GetCount(static_cast<sal_uInt16>(i)); + for (sal_Int32 j = 0; j < nFields; ++j) + { + ScMyColumnRowGroup aGroup; + ScOutlineEntry* pEntry(pFields->GetEntry(static_cast<sal_uInt16>(i), static_cast<sal_uInt16>(j))); + aGroup.nField = pEntry->GetStart(); + aGroup.nLevel = static_cast<sal_Int16>(i); + aGroup.bDisplay = !(pEntry->IsHidden()); + pGroups->AddGroup(aGroup, pEntry->GetEnd()); + } + } + if (nDepth) + pGroups->Sort(); +} + +void ScXMLExport::FillColumnRowGroups() +{ + if (pDoc) + { + ScOutlineTable* pOutlineTable = pDoc->GetOutlineTable( static_cast<SCTAB>(nCurrentTable), sal_False ); + if(pOutlineTable) + { + ScOutlineArray* pCols(pOutlineTable->GetColArray()); + ScOutlineArray* pRows(pOutlineTable->GetRowArray()); + if (pCols) + FillFieldGroup(pCols, pGroupColumns); + if (pRows) + FillFieldGroup(pRows, pGroupRows); + pSharedData->SetLastColumn(nCurrentTable, pGroupColumns->GetLast()); + pSharedData->SetLastRow(nCurrentTable, pGroupRows->GetLast()); + } + } +} + +void ScXMLExport::SetBodyAttributes() +{ + if (pDoc && pDoc->IsDocProtected()) + { + AddAttribute(XML_NAMESPACE_TABLE, XML_STRUCTURE_PROTECTED, XML_TRUE); + rtl::OUStringBuffer aBuffer; + uno::Sequence<sal_Int8> aPassHash; + const ScDocProtection* p = pDoc->GetDocProtection(); + if (p) + aPassHash = p->getPasswordHash(PASSHASH_OOO); + SvXMLUnitConverter::encodeBase64(aBuffer, aPassHash); + if (aBuffer.getLength()) + AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, aBuffer.makeStringAndClear()); + } +} + +static bool lcl_CopyStreamElement( const uno::Reference< io::XInputStream >& xInput, + const uno::Reference< io::XOutputStream >& xOutput, + sal_Int32 nCount ) +{ + const sal_Int32 nBufSize = 16*1024; + uno::Sequence<sal_Int8> aSequence(nBufSize); + + sal_Int32 nRemaining = nCount; + bool bFirst = true; + + while ( nRemaining > 0 ) + { + sal_Int32 nRead = xInput->readBytes( aSequence, std::min( nRemaining, nBufSize ) ); + if (bFirst) + { + // safety check: Make sure the copied part actually points to the start of an element + if ( nRead < 1 || aSequence[0] != static_cast<sal_Int8>('<') ) + { + return false; // abort and set an error + } + bFirst = false; + } + if (nRead == nRemaining) + { + // safety check: Make sure the copied part also ends at the end of an element + if ( aSequence[nRead-1] != static_cast<sal_Int8>('>') ) + { + return false; // abort and set an error + } + } + + if ( nRead == nBufSize ) + { + xOutput->writeBytes( aSequence ); + nRemaining -= nRead; + } + else + { + if ( nRead > 0 ) + { + uno::Sequence<sal_Int8> aTempBuf( aSequence.getConstArray(), nRead ); + xOutput->writeBytes( aTempBuf ); + } + nRemaining = 0; + } + } + return true; // successful +} + +static void lcl_SkipBytesInBlocks( const uno::Reference< io::XInputStream >& xInput, sal_Int32 nBytesToSkip ) +{ + // skipBytes in zip stream is implemented as reading. + // For now, split into several calls to avoid allocating a large buffer. + // Later, skipBytes should be changed. + + const sal_Int32 nMaxSize = 32*1024; + + if ( nBytesToSkip > 0 ) + { + sal_Int32 nRemaining = nBytesToSkip; + while ( nRemaining > 0 ) + { + sal_Int32 nSkip = std::min( nRemaining, nMaxSize ); + xInput->skipBytes( nSkip ); + nRemaining -= nSkip; + } + } +} + +void ScXMLExport::CopySourceStream( sal_Int32 nStartOffset, sal_Int32 nEndOffset, sal_Int32& rNewStart, sal_Int32& rNewEnd ) +{ + uno::Reference<xml::sax::XDocumentHandler> xHandler = GetDocHandler(); + uno::Reference<io::XActiveDataSource> xDestSource( xHandler, uno::UNO_QUERY ); + if ( xDestSource.is() ) + { + uno::Reference<io::XOutputStream> xDestStream = xDestSource->getOutputStream(); + uno::Reference<io::XSeekable> xDestSeek( xDestStream, uno::UNO_QUERY ); + if ( xDestSeek.is() ) + { + // temporary: set same stream again to clear buffer + xDestSource->setOutputStream( xDestStream ); + + if ( getExportFlags() & EXPORT_PRETTY ) + { + ByteString aOutStr("\n "); + uno::Sequence<sal_Int8> aOutSeq( (sal_Int8*)aOutStr.GetBuffer(), aOutStr.Len() ); + xDestStream->writeBytes( aOutSeq ); + } + + rNewStart = (sal_Int32)xDestSeek->getPosition(); + + if ( nStartOffset > nSourceStreamPos ) + lcl_SkipBytesInBlocks( xSourceStream, nStartOffset - nSourceStreamPos ); + + if ( !lcl_CopyStreamElement( xSourceStream, xDestStream, nEndOffset - nStartOffset ) ) + { + // If copying went wrong, set an error. + // ScXMLImportWrapper then resets all stream flags, so the next save attempt will use normal saving. + + uno::Sequence<OUString> aEmptySeq; + SetError(XMLERROR_CANCEL|XMLERROR_FLAG_SEVERE, aEmptySeq); + } + nSourceStreamPos = nEndOffset; + + rNewEnd = (sal_Int32)xDestSeek->getPosition(); + } + } +} + +void ScXMLExport::_ExportContent() +{ + nCurrentTable = 0; + if (!pSharedData) + { + sal_Int32 nTableCount(0); + sal_Int32 nShapesCount(0); + sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0); + CollectSharedData(nTableCount, nShapesCount, nCellCount); + DBG_ERROR("no shared data setted"); + } + ScXMLExportDatabaseRanges aExportDatabaseRanges(*this); + if (!GetModel().is()) + return; + + uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY ); + if ( !xSpreadDoc.is() ) + return; + + ScSheetSaveData* pSheetData = ScModelObj::getImplementation(xSpreadDoc)->GetSheetSaveData(); + if (pSheetData) + pSheetData->ResetSaveEntries(); + + uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY ); + if ( xIndex.is() ) + { + //_GetNamespaceMap().ClearQNamesCache(); + pChangeTrackingExportHelper->CollectAndWriteChanges(); + WriteCalculationSettings(xSpreadDoc); + sal_Int32 nTableCount(xIndex->getCount()); + ScMyAreaLinksContainer aAreaLinks; + GetAreaLinks( xSpreadDoc, aAreaLinks ); + ScMyEmptyDatabaseRangesContainer aEmptyRanges(aExportDatabaseRanges.GetEmptyDatabaseRanges()); + ScMyDetectiveOpContainer aDetectiveOpContainer; + GetDetectiveOpList( aDetectiveOpContainer ); + + pCellStyles->Sort(); + pMergedRangesContainer->Sort(); + pSharedData->GetDetectiveObjContainer()->Sort(); + + pCellsItr->Clear(); + pCellsItr->SetShapes( pSharedData->GetShapesContainer() ); + pCellsItr->SetNoteShapes( pSharedData->GetNoteShapes() ); + pCellsItr->SetMergedRanges( pMergedRangesContainer ); + pCellsItr->SetAreaLinks( &aAreaLinks ); + pCellsItr->SetEmptyDatabaseRanges( &aEmptyRanges ); + pCellsItr->SetDetectiveObj( pSharedData->GetDetectiveObjContainer() ); + pCellsItr->SetDetectiveOp( &aDetectiveOpContainer ); + + if (nTableCount > 0) + pValidationsContainer->WriteValidations(*this); + WriteTheLabelRanges( xSpreadDoc ); + for (sal_Int32 nTable = 0; nTable < nTableCount; ++nTable) + { + sal_Int32 nStartOffset = -1; + sal_Int32 nEndOffset = -1; + if (pSheetData && pDoc && pDoc->IsStreamValid((SCTAB)nTable)) + pSheetData->GetStreamPos( nTable, nStartOffset, nEndOffset ); + + if ( nStartOffset >= 0 && nEndOffset >= 0 && xSourceStream.is() ) + { + sal_Int32 nNewStart = -1; + sal_Int32 nNewEnd = -1; + CopySourceStream( nStartOffset, nEndOffset, nNewStart, nNewEnd ); + + // store position of copied sheet in output + pSheetData->AddSavePos( nTable, nNewStart, nNewEnd ); + + // skip iterator entries for this sheet + pCellsItr->SkipTable(static_cast<SCTAB>(nTable)); + } + else + { + uno::Reference<sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY); + if (xTable.is()) + { + xCurrentTable.set(xTable); + xCurrentTableCellRange.set(xTable, uno::UNO_QUERY); + uno::Reference<container::XNamed> xName (xTable, uno::UNO_QUERY ); + if ( xName.is() ) + { + nCurrentTable = sal::static_int_cast<sal_uInt16>( nTable ); + rtl::OUString sOUTableName(xName->getName()); + AddAttribute(sAttrName, sOUTableName); + AddAttribute(sAttrStyleName, aTableStyles[nTable]); + + uno::Reference<util::XProtectable> xProtectable (xTable, uno::UNO_QUERY); + if (xProtectable.is() && xProtectable->isProtected()) + { + AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TRUE); + rtl::OUStringBuffer aBuffer; + if (pDoc) + { + ScTableProtection* pProtect = pDoc->GetTabProtection(static_cast<SCTAB>(nTable)); + if (pProtect) + SvXMLUnitConverter::encodeBase64(aBuffer, pProtect->getPasswordHash(PASSHASH_OOO)); + } + if (aBuffer.getLength()) + AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, aBuffer.makeStringAndClear()); + } + rtl::OUString sPrintRanges; + table::CellRangeAddress aColumnHeaderRange; + sal_Bool bHasColumnHeader; + GetColumnRowHeader(bHasColumnHeader, aColumnHeaderRange, bHasRowHeader, aRowHeaderRange, sPrintRanges); + if( sPrintRanges.getLength() ) + AddAttribute( XML_NAMESPACE_TABLE, XML_PRINT_RANGES, sPrintRanges ); + else if (!pDoc->IsPrintEntireSheet(static_cast<SCTAB>(nTable))) + AddAttribute( XML_NAMESPACE_TABLE, XML_PRINT, XML_FALSE); + SvXMLElementExport aElemT(*this, sElemTab, sal_True, sal_True); + CheckAttrList(); + + if ( pDoc && pDoc->GetSheetEvents( static_cast<SCTAB>(nTable) ) && + getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST ) + { + // store sheet events + uno::Reference<document::XEventsSupplier> xSupplier(xTable, uno::UNO_QUERY); + uno::Reference<container::XNameAccess> xEvents(xSupplier->getEvents(), uno::UNO_QUERY); + GetEventExport().ExportExt( xEvents ); + } + + WriteTableSource(); + WriteScenario(); + uno::Reference<drawing::XDrawPage> xDrawPage; + if (pSharedData->HasForm(nTable, xDrawPage) && xDrawPage.is()) + { + ::xmloff::OOfficeFormsExport aForms(*this); + GetFormExport()->exportForms( xDrawPage ); + sal_Bool bRet(GetFormExport()->seekPage( xDrawPage )); + DBG_ASSERT( bRet, "OFormLayerXMLExport::seekPage failed!" ); + (void)bRet; // avoid warning in product version + } + if (pSharedData->HasDrawPage()) + { + GetShapeExport()->seekShapes(uno::Reference<drawing::XShapes>(pSharedData->GetDrawPage(nTable), uno::UNO_QUERY)); + WriteTableShapes(); + } + table::CellRangeAddress aRange(GetEndAddress(xTable, nTable)); + pSharedData->SetLastColumn(nTable, aRange.EndColumn); + pSharedData->SetLastRow(nTable, aRange.EndRow); + pCellsItr->SetCurrentTable(static_cast<SCTAB>(nTable), xCurrentTable); + pGroupColumns->NewTable(); + pGroupRows->NewTable(); + FillColumnRowGroups(); + if (bHasColumnHeader) + pSharedData->SetLastColumn(nTable, aColumnHeaderRange.EndColumn); + bRowHeaderOpen = sal_False; + if (bHasRowHeader) + pSharedData->SetLastRow(nTable, aRowHeaderRange.EndRow); + pDefaults->FillDefaultStyles(nTable, pSharedData->GetLastRow(nTable), + pSharedData->GetLastColumn(nTable), pCellStyles, pDoc); + pRowFormatRanges->SetRowDefaults(pDefaults->GetRowDefaults()); + pRowFormatRanges->SetColDefaults(pDefaults->GetColDefaults()); + pCellStyles->SetRowDefaults(pDefaults->GetRowDefaults()); + pCellStyles->SetColDefaults(pDefaults->GetColDefaults()); + ExportColumns(nTable, aColumnHeaderRange, bHasColumnHeader); + sal_Bool bIsFirst(sal_True); + sal_Int32 nEqualCells(0); + ScMyCell aCell; + ScMyCell aPrevCell; + while(pCellsItr->GetNext(aCell, pCellStyles)) + { + if (bIsFirst) + { + ExportFormatRanges(0, 0, aCell.aCellAddress.Column - 1, aCell.aCellAddress.Row, nTable); + aPrevCell = aCell; + bIsFirst = sal_False; + } + else + { + if ((aPrevCell.aCellAddress.Row == aCell.aCellAddress.Row) && + (aPrevCell.aCellAddress.Column + nEqualCells + 1 == aCell.aCellAddress.Column)) + { + if(IsCellEqual(aPrevCell, aCell)) + ++nEqualCells; + else + { + SetRepeatAttribute(nEqualCells); + WriteCell(aPrevCell); + nEqualCells = 0; + aPrevCell = aCell; + } + } + else + { + SetRepeatAttribute(nEqualCells); + WriteCell(aPrevCell); + ExportFormatRanges(aPrevCell.aCellAddress.Column + nEqualCells + 1, aPrevCell.aCellAddress.Row, + aCell.aCellAddress.Column - 1, aCell.aCellAddress.Row, nTable); + nEqualCells = 0; + aPrevCell = aCell; + } + } + } + if (!bIsFirst) + { + SetRepeatAttribute(nEqualCells); + WriteCell(aPrevCell); + ExportFormatRanges(aPrevCell.aCellAddress.Column + nEqualCells + 1, aPrevCell.aCellAddress.Row, + pSharedData->GetLastColumn(nTable), pSharedData->GetLastRow(nTable), nTable); + } + else + ExportFormatRanges(0, 0, pSharedData->GetLastColumn(nTable), pSharedData->GetLastRow(nTable), nTable); + CloseRow(pSharedData->GetLastRow(nTable)); + nEqualCells = 0; + } + } + } + IncrementProgressBar(sal_False); + } + } + WriteExternalRefCaches(); + WriteNamedExpressions(xSpreadDoc); + aExportDatabaseRanges.WriteDatabaseRanges(xSpreadDoc); + ScXMLExportDataPilot aExportDataPilot(*this); + aExportDataPilot.WriteDataPilots(xSpreadDoc); + WriteConsolidation(); + ScXMLExportDDELinks aExportDDELinks(*this); + aExportDDELinks.WriteDDELinks(xSpreadDoc); + IncrementProgressBar(sal_True, 0); + GetProgressBarHelper()->SetValue(GetProgressBarHelper()->GetReference()); +} + +void ScXMLExport::_ExportStyles( sal_Bool bUsed ) +{ + if (!pSharedData) + { + sal_Int32 nTableCount(0); + sal_Int32 nShapesCount(0); + sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0); + CollectSharedData(nTableCount, nShapesCount, nCellCount); + //DBG_ERROR("no shared data setted"); + } + ScXMLStyleExport aStylesExp(*this, rtl::OUString(), GetAutoStylePool().get()); + if (GetModel().is()) + { + uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY); + if (xMultiServiceFactory.is()) + { + uno::Reference <beans::XPropertySet> xProperties(xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.Defaults"))), uno::UNO_QUERY); + if (xProperties.is()) + aStylesExp.exportDefaultStyle(xProperties, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME)), xCellStylesExportPropertySetMapper); + if (pSharedData->HasShapes()) + { + GetShapeExport()->ExportGraphicDefaults(); +/* xInterface = xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.Defaults"))); + uno::Reference <beans::XPropertySet> xDrawProperties(xInterface, uno::UNO_QUERY); + if (xDrawProperties.is()) + aStylesExp.exportDefaultStyle(xDrawProperties, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_SD_GRAPHICS_NAME)), GetShapeExport()->CreateShapePropMapper(*this));*/ + } + } + uno::Reference <style::XStyleFamiliesSupplier> xStyleFamiliesSupplier (GetModel(), uno::UNO_QUERY); + if (xStyleFamiliesSupplier.is()) + { + uno::Reference <container::XNameAccess> xStylesFamilies(xStyleFamiliesSupplier->getStyleFamilies()); + if (xStylesFamilies.is()) + { + uno::Reference <container::XIndexAccess> xCellStyles(xStylesFamilies->getByName(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CellStyles"))), uno::UNO_QUERY); + if (xCellStyles.is()) + { + sal_Int32 nCount(xCellStyles->getCount()); + rtl::OUString sNumberFormat(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_NUMFMT)); + for (sal_Int32 i = 0; i < nCount; ++i) + { + uno::Reference <beans::XPropertySet> xCellProperties(xCellStyles->getByIndex(i), uno::UNO_QUERY); + if (xCellProperties.is()) + { + sal_Int32 nNumberFormat = 0; + if (xCellProperties->getPropertyValue(sNumberFormat) >>= nNumberFormat) + addDataStyle(nNumberFormat); + } + } + } + } + } + } + exportDataStyles(); + + aStylesExp.exportStyleFamily(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CellStyles")), + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME)), xCellStylesExportPropertySetMapper, sal_False, XML_STYLE_FAMILY_TABLE_CELL); + + SvXMLExport::_ExportStyles(bUsed); +} + +void ScXMLExport::AddStyleFromCells(const uno::Reference<beans::XPropertySet>& xProperties, + const uno::Reference<sheet::XSpreadsheet>& xTable, + sal_Int32 nTable, const rtl::OUString* pOldName) +{ + //! pass xCellRanges instead + uno::Reference<sheet::XSheetCellRanges> xCellRanges( xProperties, uno::UNO_QUERY ); + + rtl::OUString SC_SCELLPREFIX(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX)); + rtl::OUString SC_NUMBERFORMAT(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_NUMFMT)); + + rtl::OUString sStyleName; + sal_Int32 nNumberFormat(-1); + sal_Int32 nValidationIndex(-1); + std::vector< XMLPropertyState > xPropStates(xCellStylesExportPropertySetMapper->Filter( xProperties )); + std::vector< XMLPropertyState >::iterator aItr(xPropStates.begin()); + std::vector< XMLPropertyState >::iterator aEndItr(xPropStates.end()); + sal_Int32 nCount(0); + while (aItr != aEndItr) + { + if (aItr->mnIndex != -1) + { + switch (xCellStylesPropertySetMapper->GetEntryContextId(aItr->mnIndex)) + { + case CTF_SC_VALIDATION : + { + pValidationsContainer->AddValidation(aItr->maValue, nValidationIndex); + // this is not very slow, because it is most the last property or + // if it is not the last property it is the property before the last property, + // so in the worst case only one property has to be copied, but in the best case no + // property has to be copied + aItr = xPropStates.erase(aItr); + aEndItr = xPropStates.end(); // #120346# old aEndItr is invalidated! + } + break; + case CTF_SC_CELLSTYLE : + { + aItr->maValue >>= sStyleName; + aItr->mnIndex = -1; + ++aItr; + ++nCount; + } + break; + case CTF_SC_NUMBERFORMAT : + { + if (aItr->maValue >>= nNumberFormat) + addDataStyle(nNumberFormat); + ++aItr; + ++nCount; + } + break; + default: + { + ++aItr; + ++nCount; + } + break; + } + } + else + { + ++aItr; + ++nCount; + } + } + if (nCount == 1) // this is the CellStyle and should be removed if alone + xPropStates.clear(); + if (nNumberFormat == -1) + xProperties->getPropertyValue(SC_NUMBERFORMAT) >>= nNumberFormat; + if (sStyleName.getLength()) + { + if (xPropStates.size()) + { + sal_Int32 nIndex; + if (pOldName) + { + if (GetAutoStylePool()->AddNamed(*pOldName, XML_STYLE_FAMILY_TABLE_CELL, sStyleName, xPropStates)) + { + GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_CELL, *pOldName); + // add to pCellStyles, so the name is found for normal sheets + rtl::OUString* pTemp(new rtl::OUString(*pOldName)); + if (!pCellStyles->AddStyleName(pTemp, nIndex)) + delete pTemp; + } + } + else + { + rtl::OUString sName; + sal_Bool bIsAutoStyle(sal_True); + if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_CELL, sStyleName, xPropStates)) + { + rtl::OUString* pTemp(new rtl::OUString(sName)); + if (!pCellStyles->AddStyleName(pTemp, nIndex)) + delete pTemp; + } + else + nIndex = pCellStyles->GetIndexOfStyleName(sName, SC_SCELLPREFIX, bIsAutoStyle); + + uno::Sequence<table::CellRangeAddress> aAddresses(xCellRanges->getRangeAddresses()); + table::CellRangeAddress* pAddresses(aAddresses.getArray()); + sal_Bool bGetMerge(sal_True); + for (sal_Int32 i = 0; i < aAddresses.getLength(); ++i, ++pAddresses) + { + pSharedData->SetLastColumn(nTable, pAddresses->EndColumn); + pSharedData->SetLastRow(nTable, pAddresses->EndRow); + pCellStyles->AddRangeStyleName(*pAddresses, nIndex, bIsAutoStyle, nValidationIndex, nNumberFormat); + if (bGetMerge) + bGetMerge = GetMerged(pAddresses, xTable); + } + } + } + else + { + rtl::OUString* pTemp(new rtl::OUString(EncodeStyleName(sStyleName))); + sal_Int32 nIndex(0); + if (!pCellStyles->AddStyleName(pTemp, nIndex, sal_False)) + { + delete pTemp; + pTemp = NULL; + } + if ( !pOldName ) + { + uno::Sequence<table::CellRangeAddress> aAddresses(xCellRanges->getRangeAddresses()); + table::CellRangeAddress* pAddresses(aAddresses.getArray()); + sal_Bool bGetMerge(sal_True); + for (sal_Int32 i = 0; i < aAddresses.getLength(); ++i, ++pAddresses) + { + if (bGetMerge) + bGetMerge = GetMerged(pAddresses, xTable); + pCellStyles->AddRangeStyleName(*pAddresses, nIndex, sal_False, nValidationIndex, nNumberFormat); + if (!sStyleName.equalsAsciiL("Default", 7) || nValidationIndex != -1) + { + pSharedData->SetLastColumn(nTable, pAddresses->EndColumn); + pSharedData->SetLastRow(nTable, pAddresses->EndRow); + } + } + } + } + } +} + +void ScXMLExport::AddStyleFromColumn(const uno::Reference<beans::XPropertySet>& xColumnProperties, + const rtl::OUString* pOldName, sal_Int32& rIndex, sal_Bool& rIsVisible) +{ + rtl::OUString SC_SCOLUMNPREFIX(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX)); + + std::vector<XMLPropertyState> xPropStates(xColumnStylesExportPropertySetMapper->Filter(xColumnProperties)); + if(xPropStates.size()) + { + std::vector< XMLPropertyState >::iterator aItr(xPropStates.begin()); + std::vector< XMLPropertyState >::iterator aEndItr(xPropStates.end()); + while (aItr != aEndItr) + { + if (xColumnStylesPropertySetMapper->GetEntryContextId(aItr->mnIndex) == CTF_SC_ISVISIBLE) + { + aItr->maValue >>= rIsVisible; + break; + } + ++aItr; + } + + rtl::OUString sParent; + if (pOldName) + { + if (GetAutoStylePool()->AddNamed(*pOldName, XML_STYLE_FAMILY_TABLE_COLUMN, sParent, xPropStates)) + { + GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_COLUMN, *pOldName); + // add to pColumnStyles, so the name is found for normal sheets + rtl::OUString* pTemp(new rtl::OUString(*pOldName)); + rIndex = pColumnStyles->AddStyleName(pTemp); + } + } + else + { + rtl::OUString sName; + if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_COLUMN, sParent, xPropStates)) + { + rtl::OUString* pTemp(new rtl::OUString(sName)); + rIndex = pColumnStyles->AddStyleName(pTemp); + } + else + rIndex = pColumnStyles->GetIndexOfStyleName(sName, SC_SCOLUMNPREFIX); + } + } +} + +void ScXMLExport::AddStyleFromRow(const uno::Reference<beans::XPropertySet>& xRowProperties, + const rtl::OUString* pOldName, sal_Int32& rIndex) +{ + rtl::OUString SC_SROWPREFIX(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX)); + + std::vector<XMLPropertyState> xPropStates(xRowStylesExportPropertySetMapper->Filter(xRowProperties)); + if(xPropStates.size()) + { + rtl::OUString sParent; + if (pOldName) + { + if (GetAutoStylePool()->AddNamed(*pOldName, XML_STYLE_FAMILY_TABLE_ROW, sParent, xPropStates)) + { + GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_ROW, *pOldName); + // add to pRowStyles, so the name is found for normal sheets + rtl::OUString* pTemp(new rtl::OUString(*pOldName)); + rIndex = pRowStyles->AddStyleName(pTemp); + } + } + else + { + rtl::OUString sName; + if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_ROW, sParent, xPropStates)) + { + rtl::OUString* pTemp(new rtl::OUString(sName)); + rIndex = pRowStyles->AddStyleName(pTemp); + } + else + rIndex = pRowStyles->GetIndexOfStyleName(sName, SC_SROWPREFIX); + } + } +} + +uno::Any lcl_GetEnumerated( uno::Reference<container::XEnumerationAccess> xEnumAccess, sal_Int32 nIndex ) +{ + uno::Any aRet; + uno::Reference<container::XEnumeration> xEnum( xEnumAccess->createEnumeration() ); + try + { + sal_Int32 nSkip = nIndex; + while ( nSkip > 0 ) + { + (void) xEnum->nextElement(); + --nSkip; + } + aRet = xEnum->nextElement(); + } + catch (container::NoSuchElementException&) + { + // leave aRet empty + } + return aRet; +} + +void ScXMLExport::_ExportAutoStyles() +{ + if (!GetModel().is()) + return; + + uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY ); + if (!xSpreadDoc.is()) + return; + + uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY ); + if (!xIndex.is()) + return; + + if (getExportFlags() & EXPORT_CONTENT) + { + // re-create automatic styles with old names from stored data + ScSheetSaveData* pSheetData = ScModelObj::getImplementation(xSpreadDoc)->GetSheetSaveData(); + if (pSheetData && pDoc) + { + // formulas have to be calculated now, to detect changed results + // (during normal save, they will be calculated anyway) + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab=0; nTab<nTabCount; ++nTab) + if (pDoc->IsStreamValid(nTab)) + { + ScCellIterator aIter( pDoc, 0,0,nTab, MAXCOL,MAXROW,nTab ); + ScBaseCell* pCell = aIter.GetFirst(); + while (pCell) + { + if (pCell->GetCellType() == CELLTYPE_FORMULA) + static_cast<ScFormulaCell*>(pCell)->IsValue(); // interpret if dirty + pCell = aIter.GetNext(); + } + } + + // stored cell styles + const std::vector<ScCellStyleEntry>& rCellEntries = pSheetData->GetCellStyles(); + std::vector<ScCellStyleEntry>::const_iterator aCellIter = rCellEntries.begin(); + std::vector<ScCellStyleEntry>::const_iterator aCellEnd = rCellEntries.end(); + while (aCellIter != aCellEnd) + { + ScAddress aPos = aCellIter->maCellPos; + sal_Int32 nTable = aPos.Tab(); + bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); + if (bCopySheet) + { + uno::Reference <sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY); + uno::Reference <beans::XPropertySet> xProperties( + xTable->getCellByPosition( aPos.Col(), aPos.Row() ), uno::UNO_QUERY ); + + AddStyleFromCells(xProperties, xTable, nTable, &aCellIter->maName); + } + ++aCellIter; + } + + // stored column styles + const std::vector<ScCellStyleEntry>& rColumnEntries = pSheetData->GetColumnStyles(); + std::vector<ScCellStyleEntry>::const_iterator aColumnIter = rColumnEntries.begin(); + std::vector<ScCellStyleEntry>::const_iterator aColumnEnd = rColumnEntries.end(); + while (aColumnIter != aColumnEnd) + { + ScAddress aPos = aColumnIter->maCellPos; + sal_Int32 nTable = aPos.Tab(); + bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); + if (bCopySheet) + { + uno::Reference<table::XColumnRowRange> xColumnRowRange(xIndex->getByIndex(nTable), uno::UNO_QUERY); + uno::Reference<table::XTableColumns> xTableColumns(xColumnRowRange->getColumns()); + uno::Reference<beans::XPropertySet> xColumnProperties(xTableColumns->getByIndex( aPos.Col() ), uno::UNO_QUERY); + + sal_Int32 nIndex(-1); + sal_Bool bIsVisible(sal_True); + AddStyleFromColumn( xColumnProperties, &aColumnIter->maName, nIndex, bIsVisible ); + } + ++aColumnIter; + } + + // stored row styles + const std::vector<ScCellStyleEntry>& rRowEntries = pSheetData->GetRowStyles(); + std::vector<ScCellStyleEntry>::const_iterator aRowIter = rRowEntries.begin(); + std::vector<ScCellStyleEntry>::const_iterator aRowEnd = rRowEntries.end(); + while (aRowIter != aRowEnd) + { + ScAddress aPos = aRowIter->maCellPos; + sal_Int32 nTable = aPos.Tab(); + bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); + if (bCopySheet) + { + uno::Reference<table::XColumnRowRange> xColumnRowRange(xIndex->getByIndex(nTable), uno::UNO_QUERY); + uno::Reference<table::XTableRows> xTableRows(xColumnRowRange->getRows()); + uno::Reference<beans::XPropertySet> xRowProperties(xTableRows->getByIndex( aPos.Row() ), uno::UNO_QUERY); + + sal_Int32 nIndex(-1); + AddStyleFromRow( xRowProperties, &aRowIter->maName, nIndex ); + } + ++aRowIter; + } + + // stored table styles + const std::vector<ScCellStyleEntry>& rTableEntries = pSheetData->GetTableStyles(); + std::vector<ScCellStyleEntry>::const_iterator aTableIter = rTableEntries.begin(); + std::vector<ScCellStyleEntry>::const_iterator aTableEnd = rTableEntries.end(); + while (aTableIter != aTableEnd) + { + ScAddress aPos = aTableIter->maCellPos; + sal_Int32 nTable = aPos.Tab(); + bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); + if (bCopySheet) + { + //! separate method AddStyleFromTable needed? + uno::Reference<beans::XPropertySet> xTableProperties(xIndex->getByIndex(nTable), uno::UNO_QUERY); + if (xTableProperties.is()) + { + std::vector<XMLPropertyState> xPropStates(xTableStylesExportPropertySetMapper->Filter(xTableProperties)); + rtl::OUString sParent; + rtl::OUString sName( aTableIter->maName ); + GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TABLE_TABLE, sParent, xPropStates); + GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_TABLE, sName); + } + } + ++aTableIter; + } + + // stored styles for notes + + UniReference<SvXMLExportPropertyMapper> xShapeMapper = XMLShapeExport::CreateShapePropMapper( *this ); + GetShapeExport(); // make sure the graphics styles family is added + + const std::vector<ScNoteStyleEntry>& rNoteEntries = pSheetData->GetNoteStyles(); + std::vector<ScNoteStyleEntry>::const_iterator aNoteIter = rNoteEntries.begin(); + std::vector<ScNoteStyleEntry>::const_iterator aNoteEnd = rNoteEntries.end(); + while (aNoteIter != aNoteEnd) + { + ScAddress aPos = aNoteIter->maCellPos; + sal_Int32 nTable = aPos.Tab(); + bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); + if (bCopySheet) + { + //! separate method AddStyleFromNote needed? + + ScPostIt* pNote = pDoc->GetNote( aPos ); + DBG_ASSERT( pNote, "note not found" ); + if (pNote) + { + SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos ); + // all uno shapes are created anyway in CollectSharedData + uno::Reference<beans::XPropertySet> xShapeProperties( pDrawObj->getUnoShape(), uno::UNO_QUERY ); + if (xShapeProperties.is()) + { + if ( aNoteIter->maStyleName.getLength() ) + { + std::vector<XMLPropertyState> xPropStates(xShapeMapper->Filter(xShapeProperties)); + rtl::OUString sParent; + rtl::OUString sName( aNoteIter->maStyleName ); + GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_SD_GRAPHICS_ID, sParent, xPropStates); + GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_SD_GRAPHICS_ID, sName); + } + if ( aNoteIter->maTextStyle.getLength() ) + { + std::vector<XMLPropertyState> xPropStates( + GetTextParagraphExport()->GetParagraphPropertyMapper()->Filter(xShapeProperties)); + rtl::OUString sParent; + rtl::OUString sName( aNoteIter->maTextStyle ); + GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_PARAGRAPH, sParent, xPropStates); + GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_PARAGRAPH, sName); + } + } + } + } + ++aNoteIter; + } + + // note paragraph styles + + //UniReference<SvXMLExportPropertyMapper> xParaPropMapper = XMLTextParagraphExport::CreateParaExtPropMapper( *this ); + UniReference<SvXMLExportPropertyMapper> xParaPropMapper = GetTextParagraphExport()->GetParagraphPropertyMapper(); + + const std::vector<ScTextStyleEntry>& rNoteParaEntries = pSheetData->GetNoteParaStyles(); + std::vector<ScTextStyleEntry>::const_iterator aNoteParaIter = rNoteParaEntries.begin(); + std::vector<ScTextStyleEntry>::const_iterator aNoteParaEnd = rNoteParaEntries.end(); + while (aNoteParaIter != aNoteParaEnd) + { + ScAddress aPos = aNoteParaIter->maCellPos; + sal_Int32 nTable = aPos.Tab(); + bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); + if (bCopySheet) + { + ScPostIt* pNote = pDoc->GetNote( aPos ); + DBG_ASSERT( pNote, "note not found" ); + if (pNote) + { + SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos ); + uno::Reference<container::XEnumerationAccess> xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xParaProp( + lcl_GetEnumerated( xCellText, aNoteParaIter->maSelection.nStartPara ), uno::UNO_QUERY ); + if ( xParaProp.is() ) + { + std::vector<XMLPropertyState> xPropStates(xParaPropMapper->Filter(xParaProp)); + rtl::OUString sParent; + rtl::OUString sName( aNoteParaIter->maName ); + GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_PARAGRAPH, sParent, xPropStates); + GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_PARAGRAPH, sName); + } + } + } + ++aNoteParaIter; + } + + // note text styles + + UniReference<SvXMLExportPropertyMapper> xTextPropMapper = XMLTextParagraphExport::CreateCharExtPropMapper( *this ); + + const std::vector<ScTextStyleEntry>& rNoteTextEntries = pSheetData->GetNoteTextStyles(); + std::vector<ScTextStyleEntry>::const_iterator aNoteTextIter = rNoteTextEntries.begin(); + std::vector<ScTextStyleEntry>::const_iterator aNoteTextEnd = rNoteTextEntries.end(); + while (aNoteTextIter != aNoteTextEnd) + { + ScAddress aPos = aNoteTextIter->maCellPos; + sal_Int32 nTable = aPos.Tab(); + bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); + if (bCopySheet) + { + ScPostIt* pNote = pDoc->GetNote( aPos ); + DBG_ASSERT( pNote, "note not found" ); + if (pNote) + { + SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos ); + uno::Reference<text::XSimpleText> xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xCursorProp(xCellText->createTextCursor(), uno::UNO_QUERY); + ScDrawTextCursor* pCursor = ScDrawTextCursor::getImplementation( xCursorProp ); + if (pCursor) + { + pCursor->SetSelection( aNoteTextIter->maSelection ); + + std::vector<XMLPropertyState> xPropStates(xTextPropMapper->Filter(xCursorProp)); + rtl::OUString sParent; + rtl::OUString sName( aNoteTextIter->maName ); + GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_TEXT, sParent, xPropStates); + GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_TEXT, sName); + } + } + } + ++aNoteTextIter; + } + + // stored text styles + + //UniReference<SvXMLExportPropertyMapper> xTextPropMapper = XMLTextParagraphExport::CreateCharExtPropMapper( *this ); + + const std::vector<ScTextStyleEntry>& rTextEntries = pSheetData->GetTextStyles(); + std::vector<ScTextStyleEntry>::const_iterator aTextIter = rTextEntries.begin(); + std::vector<ScTextStyleEntry>::const_iterator aTextEnd = rTextEntries.end(); + while (aTextIter != aTextEnd) + { + ScAddress aPos = aTextIter->maCellPos; + sal_Int32 nTable = aPos.Tab(); + bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); + if (bCopySheet) + { + //! separate method AddStyleFromText needed? + //! cache sheet object + + uno::Reference<table::XCellRange> xCellRange(xIndex->getByIndex(nTable), uno::UNO_QUERY); + uno::Reference<text::XSimpleText> xCellText(xCellRange->getCellByPosition(aPos.Col(), aPos.Row()), uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xCursorProp(xCellText->createTextCursor(), uno::UNO_QUERY); + ScCellTextCursor* pCursor = ScCellTextCursor::getImplementation( xCursorProp ); + if (pCursor) + { + pCursor->SetSelection( aTextIter->maSelection ); + + std::vector<XMLPropertyState> xPropStates(xTextPropMapper->Filter(xCursorProp)); + rtl::OUString sParent; + rtl::OUString sName( aTextIter->maName ); + GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_TEXT, sParent, xPropStates); + GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_TEXT, sName); + } + } + ++aTextIter; + } + } + + ExportExternalRefCacheStyles(); + + if (!pSharedData) + { + sal_Int32 nTableCount(0); + sal_Int32 nShapesCount(0); + sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0); + CollectSharedData(nTableCount, nShapesCount, nCellCount); + //DBG_ERROR("no shared data setted"); + } + sal_Int32 nTableCount(xIndex->getCount()); + pCellStyles->AddNewTable(nTableCount - 1); + CollectShapesAutoStyles(nTableCount); + for (sal_Int32 nTable = 0; nTable < nTableCount; ++nTable) + { + bool bUseStream = pSheetData && pDoc && pDoc->IsStreamValid((SCTAB)nTable) && + pSheetData->HasStreamPos(nTable) && xSourceStream.is(); + + uno::Reference <sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY); + if (xTable.is()) + { + // table styles array must be complete, including copied tables - Add should find the stored style + uno::Reference<beans::XPropertySet> xTableProperties(xTable, uno::UNO_QUERY); + if (xTableProperties.is()) + { + std::vector<XMLPropertyState> xPropStates(xTableStylesExportPropertySetMapper->Filter(xTableProperties)); + if(xPropStates.size()) + { + rtl::OUString sParent; + rtl::OUString sName; + GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_TABLE, sParent, xPropStates); + aTableStyles.push_back(sName); + } + } + } + // collect other auto-styles only for non-copied sheets + if (xTable.is() && !bUseStream) + { + uno::Reference<sheet::XUniqueCellFormatRangesSupplier> xCellFormatRanges ( xTable, uno::UNO_QUERY ); + if ( xCellFormatRanges.is() ) + { + uno::Reference<container::XIndexAccess> xFormatRangesIndex(xCellFormatRanges->getUniqueCellFormatRanges()); + if (xFormatRangesIndex.is()) + { + sal_Int32 nFormatRangesCount(xFormatRangesIndex->getCount()); + GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nFormatRangesCount); + for (sal_Int32 nFormatRange = 0; nFormatRange < nFormatRangesCount; ++nFormatRange) + { + uno::Reference< sheet::XSheetCellRanges> xCellRanges(xFormatRangesIndex->getByIndex(nFormatRange), uno::UNO_QUERY); + if (xCellRanges.is()) + { + uno::Reference <beans::XPropertySet> xProperties (xCellRanges, uno::UNO_QUERY); + if (xProperties.is()) + { + AddStyleFromCells(xProperties, xTable, nTable, NULL); + IncrementProgressBar(sal_False); + } + } + } + } + } + uno::Reference<table::XColumnRowRange> xColumnRowRange (xTable, uno::UNO_QUERY); + if (xColumnRowRange.is()) + { + if (pDoc) + { + pDoc->SyncColRowFlags(); + uno::Reference<table::XTableColumns> xTableColumns(xColumnRowRange->getColumns()); + if (xTableColumns.is()) + { + sal_Int32 nColumns(pDoc->GetLastChangedCol(sal::static_int_cast<SCTAB>(nTable))); + pSharedData->SetLastColumn(nTable, nColumns); + table::CellRangeAddress aCellAddress(GetEndAddress(xTable, nTable)); + if (aCellAddress.EndColumn > nColumns) + { + ++nColumns; + pColumnStyles->AddNewTable(nTable, aCellAddress.EndColumn); + } +// else if (nColumns < MAXCOL) +// pColumnStyles->AddNewTable(nTable, ++nColumns); + else + pColumnStyles->AddNewTable(nTable, nColumns); + sal_Int32 nColumn = 0; + while (/*nColumn <= nColumns && */nColumn <= MAXCOL) + { + sal_Int32 nIndex(-1); + sal_Bool bIsVisible(sal_True); + uno::Reference <beans::XPropertySet> xColumnProperties(xTableColumns->getByIndex(nColumn), uno::UNO_QUERY); + if (xColumnProperties.is()) + { + AddStyleFromColumn( xColumnProperties, NULL, nIndex, bIsVisible ); + //if(xPropStates.size()) + pColumnStyles->AddFieldStyleName(nTable, nColumn, nIndex, bIsVisible); + } + sal_Int32 nOld(nColumn); + nColumn = pDoc->GetNextDifferentChangedCol(sal::static_int_cast<SCTAB>(nTable), static_cast<SCCOL>(nColumn)); + for (sal_Int32 i = nOld + 1; i < nColumn; ++i) + pColumnStyles->AddFieldStyleName(nTable, i, nIndex, bIsVisible); + } + if (aCellAddress.EndColumn > nColumns) + { + sal_Bool bIsVisible(sal_True); + sal_Int32 nIndex(pColumnStyles->GetStyleNameIndex(nTable, nColumns, bIsVisible)); + for (sal_Int32 i = nColumns + 1; i <= aCellAddress.EndColumn; ++i) + pColumnStyles->AddFieldStyleName(nTable, i, nIndex, bIsVisible); + } + } + uno::Reference<table::XTableRows> xTableRows(xColumnRowRange->getRows()); + if (xTableRows.is()) + { + sal_Int32 nRows(pDoc->GetLastChangedRow(sal::static_int_cast<SCTAB>(nTable))); + pSharedData->SetLastRow(nTable, nRows); + table::CellRangeAddress aCellAddress(GetEndAddress(xTable, nTable)); + if (aCellAddress.EndRow > nRows) + { + ++nRows; + pRowStyles->AddNewTable(nTable, aCellAddress.EndRow); + } +// else if (nRows < MAXROW) +// pRowStyles->AddNewTable(nTable, ++nRows); + else + pRowStyles->AddNewTable(nTable, nRows); + sal_Int32 nRow = 0; + while (nRow <= nRows && nRow <= MAXROW) + { + sal_Int32 nIndex = 0; + uno::Reference <beans::XPropertySet> xRowProperties(xTableRows->getByIndex(nRow), uno::UNO_QUERY); + if(xRowProperties.is()) + { + AddStyleFromRow( xRowProperties, NULL, nIndex ); + //if(xPropStates.size()) + pRowStyles->AddFieldStyleName(nTable, nRow, nIndex); + } + sal_Int32 nOld(nRow); + nRow = pDoc->GetNextDifferentChangedRow(sal::static_int_cast<SCTAB>(nTable), static_cast<SCROW>(nRow), false); + if (nRow > nOld + 1) + pRowStyles->AddFieldStyleName(nTable, nOld + 1, nIndex, nRow - 1); + } + if (aCellAddress.EndRow > nRows) + { + sal_Int32 nIndex(pRowStyles->GetStyleNameIndex(nTable, nRows)); + pRowStyles->AddFieldStyleName(nTable, nRows + 1, nIndex, aCellAddress.EndRow); + } + } + } + } + uno::Reference<sheet::XCellRangesQuery> xCellRangesQuery (xTable, uno::UNO_QUERY); + if (xCellRangesQuery.is()) + { + uno::Reference<sheet::XSheetCellRanges> xSheetCellRanges(xCellRangesQuery->queryContentCells(sheet::CellFlags::FORMATTED)); + uno::Reference<sheet::XSheetOperation> xSheetOperation(xSheetCellRanges, uno::UNO_QUERY); + if (xSheetCellRanges.is() && xSheetOperation.is()) + { + sal_uInt32 nCount(sal_uInt32(xSheetOperation->computeFunction(sheet::GeneralFunction_COUNT))); + uno::Reference<container::XEnumerationAccess> xCellsAccess(xSheetCellRanges->getCells()); + if (xCellsAccess.is()) + { + GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nCount); + uno::Reference<container::XEnumeration> xCells(xCellsAccess->createEnumeration()); + if (xCells.is()) + { + sal_uInt32 nCount2(0); + while (xCells->hasMoreElements()) + { + uno::Reference<text::XText> xText(xCells->nextElement(), uno::UNO_QUERY); + if (xText.is()) + GetTextParagraphExport()->collectTextAutoStyles(xText, sal_False, sal_False); + ++nCount2; + IncrementProgressBar(sal_False); + } + if(nCount2 > nCount) + GetProgressBarHelper()->SetReference(GetProgressBarHelper()->GetReference() + nCount2 - nCount); + } + } + } + } + } + IncrementProgressBar(sal_False); + } + pChangeTrackingExportHelper->CollectAutoStyles(); + + GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_COLUMN, + GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap()); + GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_ROW, + GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap()); + GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_TABLE, + GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap()); + exportAutoDataStyles(); + GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_CELL, + GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap()); + + GetShapeExport()->exportAutoStyles(); + GetFormExport()->exportAutoStyles( ); + + if (pDoc) + { + ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager(); + // #i100879# write the table style for cached tables only if there are cached tables + // (same logic as in ExportExternalRefCacheStyles) + if (pRefMgr->hasExternalData()) + { + // Special table style for the external ref cache tables. + AddAttribute(XML_NAMESPACE_STYLE, XML_NAME, sExternalRefTabStyleName); + AddAttribute(XML_NAMESPACE_STYLE, XML_FAMILY, XML_TABLE); + SvXMLElementExport aElemStyle(*this, XML_NAMESPACE_STYLE, XML_STYLE, sal_True, sal_True); + AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, XML_FALSE); + SvXMLElementExport aElemStyleTabProps(*this, XML_NAMESPACE_STYLE, XML_TABLE_PROPERTIES, sal_True, sal_True); + } + } + } + + if (getExportFlags() & EXPORT_MASTERSTYLES) + { + GetPageExport()->collectAutoStyles(sal_True); + GetPageExport()->exportAutoStyles(); + } + + // #i30251#; only write Text Styles once + + if ((getExportFlags() & EXPORT_CONTENT) || (getExportFlags() & EXPORT_MASTERSTYLES)) + GetTextParagraphExport()->exportTextAutoStyles(); +} + +void ScXMLExport::_ExportMasterStyles() +{ + GetPageExport()->exportMasterStyles( sal_True ); +} + +void ScXMLExport::CollectInternalShape( uno::Reference< drawing::XShape > xShape ) +{ + // detective objects and notes + if( SvxShape* pShapeImp = SvxShape::getImplementation( xShape ) ) + { + if( SdrObject* pObject = pShapeImp->GetSdrObject() ) + { + // collect note caption objects from all layers (internal or hidden) + if( ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObject, static_cast< SCTAB >( nCurrentTable ) ) ) + { + pSharedData->AddNoteObj( xShape, pCaptData->maStart ); + + // #i60851# When the file is saved while editing a new note, + // the cell is still empty -> last column/row must be updated + DBG_ASSERT( pCaptData->maStart.Tab() == nCurrentTable, "invalid table in object data" ); + pSharedData->SetLastColumn( nCurrentTable, pCaptData->maStart.Col() ); + pSharedData->SetLastRow( nCurrentTable, pCaptData->maStart.Row() ); + } + // other objects from internal layer only (detective) + else if( pObject->GetLayer() == SC_LAYER_INTERN ) + { + ScDetectiveFunc aDetFunc( pDoc, static_cast<SCTAB>(nCurrentTable) ); + ScAddress aPosition; + ScRange aSourceRange; + sal_Bool bRedLine; + ScDetectiveObjType eObjType = aDetFunc.GetDetectiveObjectType( + pObject, nCurrentTable, aPosition, aSourceRange, bRedLine ); + pSharedData->GetDetectiveObjContainer()->AddObject( eObjType, static_cast<SCTAB>(nCurrentTable), aPosition, aSourceRange, bRedLine ); + } + } + } +} + +//UNUSED2008-05 sal_Bool ScXMLExport::GetMerge (const uno::Reference <sheet::XSpreadsheet>& xTable, +//UNUSED2008-05 const sal_Int32 nCol, const sal_Int32 nRow, +//UNUSED2008-05 table::CellRangeAddress& aCellAddress) +//UNUSED2008-05 { +//UNUSED2008-05 uno::Reference<sheet::XSheetCellRange> xSheetCellRange(xTable->getCellRangeByPosition(nCol, nRow, nCol, nRow), uno::UNO_QUERY); +//UNUSED2008-05 if (xSheetCellRange.is()) +//UNUSED2008-05 { +//UNUSED2008-05 uno::Reference<sheet::XSheetCellCursor> xCursor(xTable->createCursorByRange(xSheetCellRange)); +//UNUSED2008-05 if (xCursor.is()) +//UNUSED2008-05 { +//UNUSED2008-05 uno::Reference<sheet::XCellRangeAddressable> xCellAddress (xCursor, uno::UNO_QUERY); +//UNUSED2008-05 xCursor->collapseToMergedArea(); +//UNUSED2008-05 aCellAddress = xCellAddress->getRangeAddress(); +//UNUSED2008-05 return sal_True; +//UNUSED2008-05 } +//UNUSED2008-05 } +//UNUSED2008-05 return sal_False; +//UNUSED2008-05 } + +sal_Bool ScXMLExport::GetMerged (const table::CellRangeAddress* pCellAddress, + const uno::Reference <sheet::XSpreadsheet>& xTable) +{ + sal_Bool bReady(sal_False); + sal_Int32 nRow(pCellAddress->StartRow); + sal_Int32 nCol(pCellAddress->StartColumn); + sal_Int32 nEndRow(pCellAddress->EndRow); + sal_Int32 nEndCol(pCellAddress->EndColumn); + sal_Bool bRowInc(nEndRow > nRow); + while(!bReady && nRow <= nEndRow && nCol <= nEndCol) + { + uno::Reference<sheet::XSheetCellRange> xSheetCellRange(xTable->getCellRangeByPosition(nCol, nRow, nCol, nRow), uno::UNO_QUERY); + if (xSheetCellRange.is()) + { + uno::Reference<sheet::XSheetCellCursor> xCursor(xTable->createCursorByRange(xSheetCellRange)); + if(xCursor.is()) + { + uno::Reference<sheet::XCellRangeAddressable> xCellAddress (xCursor, uno::UNO_QUERY); + xCursor->collapseToMergedArea(); + table::CellRangeAddress aCellAddress2(xCellAddress->getRangeAddress()); + if ((aCellAddress2.EndRow > nRow || + aCellAddress2.EndColumn > nCol) && + aCellAddress2.StartRow == nRow && + aCellAddress2.StartColumn == nCol) + { + pMergedRangesContainer->AddRange(aCellAddress2); + pSharedData->SetLastColumn(aCellAddress2.Sheet, aCellAddress2.EndColumn); + pSharedData->SetLastRow(aCellAddress2.Sheet, aCellAddress2.EndRow); + } + else + bReady = sal_True; + } + } + if (!bReady) + { + if (bRowInc) + ++nRow; + else + ++nCol; + } + } + DBG_ASSERT(!(!bReady && nEndRow > nRow && nEndCol > nCol), "should not be possible"); + return !bReady; +} + +//UNUSED2008-05 sal_Bool ScXMLExport::IsMatrix (const uno::Reference <table::XCellRange>& xCellRange, +//UNUSED2008-05 const uno::Reference <sheet::XSpreadsheet>& xTable, +//UNUSED2008-05 const sal_Int32 nCol, const sal_Int32 nRow, +//UNUSED2008-05 table::CellRangeAddress& aCellAddress, sal_Bool& bIsFirst) const +//UNUSED2008-05 { +//UNUSED2008-05 bIsFirst = sal_False; +//UNUSED2008-05 uno::Reference <sheet::XArrayFormulaRange> xArrayFormulaRange (xCellRange->getCellRangeByPosition(nCol,nRow,nCol,nRow), uno::UNO_QUERY); +//UNUSED2008-05 if (xArrayFormulaRange.is()) +//UNUSED2008-05 { +//UNUSED2008-05 rtl::OUString sArrayFormula(xArrayFormulaRange->getArrayFormula()); +//UNUSED2008-05 if (sArrayFormula.getLength()) +//UNUSED2008-05 { +//UNUSED2008-05 uno::Reference<sheet::XSheetCellRange> xMatrixSheetCellRange (xArrayFormulaRange, uno::UNO_QUERY); +//UNUSED2008-05 if (xMatrixSheetCellRange.is()) +//UNUSED2008-05 { +//UNUSED2008-05 uno::Reference<sheet::XSheetCellCursor> xMatrixSheetCursor(xTable->createCursorByRange(xMatrixSheetCellRange)); +//UNUSED2008-05 if (xMatrixSheetCursor.is()) +//UNUSED2008-05 { +//UNUSED2008-05 xMatrixSheetCursor->collapseToCurrentArray(); +//UNUSED2008-05 uno::Reference<sheet::XCellRangeAddressable> xMatrixCellAddress (xMatrixSheetCursor, uno::UNO_QUERY); +//UNUSED2008-05 if (xMatrixCellAddress.is()) +//UNUSED2008-05 { +//UNUSED2008-05 aCellAddress = xMatrixCellAddress->getRangeAddress(); +//UNUSED2008-05 if ((aCellAddress.StartColumn == nCol && aCellAddress.StartRow == nRow) && +//UNUSED2008-05 (aCellAddress.EndColumn > nCol || aCellAddress.EndRow > nRow)) +//UNUSED2008-05 { +//UNUSED2008-05 bIsFirst = sal_True; +//UNUSED2008-05 return sal_True; +//UNUSED2008-05 } +//UNUSED2008-05 else if (aCellAddress.StartColumn != nCol || aCellAddress.StartRow != nRow || +//UNUSED2008-05 aCellAddress.EndColumn != nCol || aCellAddress.EndRow != nRow) +//UNUSED2008-05 return sal_True; +//UNUSED2008-05 else +//UNUSED2008-05 { +//UNUSED2008-05 bIsFirst = sal_True; +//UNUSED2008-05 return sal_True; +//UNUSED2008-05 } +//UNUSED2008-05 } +//UNUSED2008-05 } +//UNUSED2008-05 } +//UNUSED2008-05 } +//UNUSED2008-05 } +//UNUSED2008-05 return sal_False; +//UNUSED2008-05 } + +sal_Bool ScXMLExport::IsMatrix (const ScAddress& aCell, + table::CellRangeAddress& aCellAddress, sal_Bool& bIsFirst) const +{ + bIsFirst = sal_False; + + ScRange aMatrixRange; + + if (pDoc && pDoc->GetMatrixFormulaRange(aCell, aMatrixRange)) + { + ScUnoConversion::FillApiRange( aCellAddress, aMatrixRange ); + if ((aCellAddress.StartColumn == aCell.Col() && aCellAddress.StartRow == aCell.Row()) && + (aCellAddress.EndColumn > aCell.Col() || aCellAddress.EndRow > aCell.Row())) + { + bIsFirst = sal_True; + return sal_True; + } + else if (aCellAddress.StartColumn != aCell.Col() || aCellAddress.StartRow != aCell.Row() || + aCellAddress.EndColumn != aCell.Col() || aCellAddress.EndRow != aCell.Row()) + return sal_True; + else + { + bIsFirst = sal_True; + return sal_True; + } + } + + return sal_False; + +/* uno::Reference <sheet::XArrayFormulaRange> xArrayFormulaRange (xCell, uno::UNO_QUERY); + if (xArrayFormulaRange.is()) + { + rtl::OUString sArrayFormula(xArrayFormulaRange->getArrayFormula()); + if (sArrayFormula.getLength()) + { + uno::Reference<sheet::XSheetCellRange> xMatrixSheetCellRange (xCell, uno::UNO_QUERY); + if (xMatrixSheetCellRange.is()) + { + uno::Reference<sheet::XSheetCellCursor> xMatrixSheetCursor(xTable->createCursorByRange(xMatrixSheetCellRange)); + if (xMatrixSheetCursor.is()) + { + xMatrixSheetCursor->collapseToCurrentArray(); + uno::Reference<sheet::XCellRangeAddressable> xMatrixCellAddress (xMatrixSheetCursor, uno::UNO_QUERY); + if (xMatrixCellAddress.is()) + { + aCellAddress = xMatrixCellAddress->getRangeAddress(); + if ((aCellAddress.StartColumn == nCol && aCellAddress.StartRow == nRow) && + (aCellAddress.EndColumn > nCol || aCellAddress.EndRow > nRow)) + { + bIsFirst = sal_True; + return sal_True; + } + else if (aCellAddress.StartColumn != nCol || aCellAddress.StartRow != nRow || + aCellAddress.EndColumn != nCol || aCellAddress.EndRow != nRow) + return sal_True; + else + { + bIsFirst = sal_True; + return sal_True; + } + } + } + } + } + } + return sal_False;*/ +} + +sal_Bool ScXMLExport::GetCellText (ScMyCell& rMyCell, const ScAddress& aPos) const +{ + if (rMyCell.bHasStringValue) + return sal_True; + else + { +/* if (!rMyCell.bHasXText) + { + rMyCell.xText.set(xCurrentTableCellRange->getCellByPosition(rMyCell.aCellAddress.Column, rMyCell.aCellAddress.Row), uno::UNO_QUERY); + rMyCell.bHasXText = sal_True; + }*/ +// if (rMyCell.xText.is()) +// { + rMyCell.sStringValue = ScCellObj::GetOutputString_Impl(pDoc, aPos); + rMyCell.bHasStringValue = sal_True; + return sal_True; +// } + } +} + +void ScXMLExport::WriteCell (ScMyCell& aCell) +{ + ScAddress aCellPos; + ScUnoConversion::FillScAddress( aCellPos, aCell.aCellAddress ); + if (aCell.nStyleIndex != -1) + AddAttribute(sAttrStyleName, *pCellStyles->GetStyleNameByIndex(aCell.nStyleIndex, aCell.bIsAutoStyle)); + if (aCell.nValidationIndex > -1) + AddAttribute(XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, pValidationsContainer->GetValidationName(aCell.nValidationIndex)); + sal_Bool bIsMatrix(aCell.bIsMatrixBase || aCell.bIsMatrixCovered); + sal_Bool bIsFirstMatrixCell(aCell.bIsMatrixBase); + if (bIsFirstMatrixCell) + { + sal_Int32 nColumns(aCell.aMatrixRange.EndColumn - aCell.aMatrixRange.StartColumn + 1); + sal_Int32 nRows(aCell.aMatrixRange.EndRow - aCell.aMatrixRange.StartRow + 1); + rtl::OUStringBuffer sColumns; + rtl::OUStringBuffer sRows; + SvXMLUnitConverter::convertNumber(sColumns, nColumns); + SvXMLUnitConverter::convertNumber(sRows, nRows); + AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_COLUMNS_SPANNED, sColumns.makeStringAndClear()); + AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_ROWS_SPANNED, sRows.makeStringAndClear()); + } + sal_Bool bIsEmpty(sal_False); + switch (aCell.nType) + { + case table::CellContentType_EMPTY : + { + bIsEmpty = sal_True; + } + break; + case table::CellContentType_VALUE : + { + if (!aCell.bHasDoubleValue) + { + aCell.fValue = pDoc->GetValue( aCellPos ); + aCell.bHasDoubleValue = sal_True; + } + GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes( + aCell.nNumberFormat, aCell.fValue); + } + break; + case table::CellContentType_TEXT : + { + if (GetCellText(aCell, aCellPos)) + { + rtl::OUString sFormula(lcl_GetRawString(pDoc, aCellPos)); + GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes( + sFormula, aCell.sStringValue, sal_True, sal_True); + } + } + break; + case table::CellContentType_FORMULA : + { + ScBaseCell* pBaseCell = pDoc ? pDoc->GetCell(aCellPos) : NULL; + if (pBaseCell && pBaseCell->GetCellType() == CELLTYPE_FORMULA) + { + rtl::OUStringBuffer sFormula; + ScFormulaCell* pFormulaCell((ScFormulaCell*) pBaseCell); + if (!bIsMatrix || (bIsMatrix && bIsFirstMatrixCell)) + { + const formula::FormulaGrammar::Grammar eGrammar = pDoc->GetStorageGrammar(); + sal_uInt16 nNamespacePrefix = (eGrammar == formula::FormulaGrammar::GRAM_ODFF ? XML_NAMESPACE_OF : XML_NAMESPACE_OOOC); + pFormulaCell->GetFormula(sFormula, eGrammar); + rtl::OUString sOUFormula(sFormula.makeStringAndClear()); + if (!bIsMatrix) + { + AddAttribute(sAttrFormula, GetNamespaceMap().GetQNameByKey( nNamespacePrefix, sOUFormula, sal_False )); + } + else + { + AddAttribute(sAttrFormula, GetNamespaceMap().GetQNameByKey( nNamespacePrefix, sOUFormula.copy(1, sOUFormula.getLength() - 2), sal_False )); + } + } + if (pFormulaCell->IsValue()) + { + sal_Bool bIsStandard; + rtl::OUString sCurrency; + GetNumberFormatAttributesExportHelper()->GetCellType(aCell.nNumberFormat, sCurrency, bIsStandard); + if (bIsStandard) + { + if (pDoc) + GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes( + pFormulaCell->GetStandardFormat(*pDoc->GetFormatTable(), 0), + pDoc->GetValue( aCellPos )); + } + else + GetNumberFormatAttributesExportHelper()->SetNumberFormatAttributes( + aCell.nNumberFormat, pDoc->GetValue( aCellPos )); + } + else + { + if (GetCellText(aCell, aCellPos)) + if (aCell.sStringValue.getLength()) + { + AddAttribute(sAttrValueType, XML_STRING); + AddAttribute(sAttrStringValue, aCell.sStringValue); + } + } + } + } + break; + default: + { + // added to avoid warnings + } + } + rtl::OUString* pCellString(&sElemCell); + if (aCell.bIsCovered) + { + pCellString = &sElemCoveredCell; + } + else + { + if (aCell.bIsMergedBase) + { + sal_Int32 nColumns(aCell.aMergeRange.EndColumn - aCell.aMergeRange.StartColumn + 1); + sal_Int32 nRows(aCell.aMergeRange.EndRow - aCell.aMergeRange.StartRow + 1); + rtl::OUStringBuffer sColumns; + rtl::OUStringBuffer sRows; + SvXMLUnitConverter::convertNumber(sColumns, nColumns); + SvXMLUnitConverter::convertNumber(sRows, nRows); + AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_SPANNED, sColumns.makeStringAndClear()); + AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_SPANNED, sRows.makeStringAndClear()); + } + } + SvXMLElementExport aElemC(*this, *pCellString, sal_True, sal_True); + CheckAttrList(); + WriteAreaLink(aCell); + WriteAnnotation(aCell); + WriteDetective(aCell); + + sal_Bool bEditCell = sal_False; + + if (!bIsEmpty) + { + if ((aCell.nType == table::CellContentType_TEXT && IsEditCell(aCell)) || + (aCell.nType == table::CellContentType_FORMULA && IsMultiLineFormulaCell(aCell))) + { + bEditCell = sal_True; + uno::Reference<text::XText> xText(xCurrentTableCellRange->getCellByPosition(aCell.aCellAddress.Column, aCell.aCellAddress.Row), uno::UNO_QUERY); + if ( xText.is()) + GetTextParagraphExport()->exportText(xText, sal_False, sal_False); + } + else + { + SvXMLElementExport aElemP(*this, sElemP, sal_True, sal_False); + sal_Bool bPrevCharWasSpace(sal_True); + if (GetCellText(aCell, aCellPos)) + GetTextParagraphExport()->exportText(aCell.sStringValue, bPrevCharWasSpace); + } + } + WriteShapes(aCell); + if (!bIsEmpty) + IncrementProgressBar(bEditCell); +} + +void ScXMLExport::ExportShape(const uno::Reference < drawing::XShape >& xShape, awt::Point* pPoint) +{ + uno::Reference < beans::XPropertySet > xShapeProps ( xShape, uno::UNO_QUERY ); +//BM sal_Bool bMemChart(sal_False); // das muss man jetzt umbenennen :-) + bool bIsChart( false ); + rtl::OUString sPropCLSID (RTL_CONSTASCII_USTRINGPARAM("CLSID")); + rtl::OUString sPropModel (RTL_CONSTASCII_USTRINGPARAM("Model")); + rtl::OUString sPersistName (RTL_CONSTASCII_USTRINGPARAM("PersistName")); + if (xShapeProps.is()) + { + sal_Int32 nZOrder = 0; + if (xShapeProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ZOrder"))) >>= nZOrder) + { + rtl::OUStringBuffer sBuffer; + GetMM100UnitConverter().convertNumber(sBuffer, nZOrder); + AddAttribute(XML_NAMESPACE_DRAW, XML_ZINDEX, sBuffer.makeStringAndClear()); + } + uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xShapeProps->getPropertySetInfo(); + if( xPropSetInfo->hasPropertyByName( sPropCLSID ) ) + { + rtl::OUString sCLSID; + if (xShapeProps->getPropertyValue( sPropCLSID ) >>= sCLSID) + { + if ( sCLSID.equalsIgnoreAsciiCase(GetChartExport()->getChartCLSID()) ) + { + // we have a chart + ::rtl::OUString sRanges; + if ( pDoc ) + { + ::rtl::OUString aChartName; + xShapeProps->getPropertyValue( sPersistName ) >>= aChartName; + ScRange aEmptyRange; + ScChartListener aSearcher( aChartName, pDoc, aEmptyRange ); + sal_uInt16 nIndex = 0; + ScChartListenerCollection* pCollection = pDoc->GetChartListenerCollection(); + if ( pCollection && pCollection->Search( &aSearcher, nIndex ) ) + { + ScChartListener* pListener = static_cast< ScChartListener* >( pCollection->At( nIndex ) ); + if ( pListener ) + { + const ScRangeListRef& rRangeList = pListener->GetRangeList(); + if ( rRangeList.Is() ) + { + ScRangeStringConverter::GetStringFromRangeList( sRanges, rRangeList, pDoc, FormulaGrammar::CONV_OOO ); + if ( sRanges.getLength() > 0 ) + { + bIsChart = true; + SvXMLAttributeList* pAttrList = new SvXMLAttributeList(); + if ( pAttrList ) + { + pAttrList->AddAttribute( + GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken( XML_NOTIFY_ON_UPDATE_OF_RANGES ) ), sRanges ); + } + GetShapeExport()->exportShape( xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList ); + } + } + } + } + } + + if ( sRanges.getLength() == 0 ) + { + uno::Reference< frame::XModel > xChartModel; + if( ( xShapeProps->getPropertyValue( sPropModel ) >>= xChartModel ) && + xChartModel.is()) + { + uno::Reference< chart2::XChartDocument > xChartDoc( xChartModel, uno::UNO_QUERY ); + uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartModel, uno::UNO_QUERY ); + if( xChartDoc.is() && xReceiver.is() && + ! xChartDoc->hasInternalDataProvider()) + { + // we have a chart that gets its data from Calc + bIsChart = true; + uno::Sequence< ::rtl::OUString > aRepresentations( + xReceiver->getUsedRangeRepresentations()); + SvXMLAttributeList* pAttrList = 0; + if(aRepresentations.getLength()) + { + // add the ranges used by the chart to the shape + // element to be able to start listening after + // load (when the chart is not yet loaded) + uno::Reference< chart2::data::XRangeXMLConversion > xRangeConverter( xChartDoc->getDataProvider(), uno::UNO_QUERY ); + sRanges = lcl_RangeSequenceToString( aRepresentations, xRangeConverter ); + pAttrList = new SvXMLAttributeList(); + pAttrList->AddAttribute( + GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES) ), sRanges ); + } + GetShapeExport()->exportShape(xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList); + } + } + } + +//BM rtl::OUString sOUName; +//BM xShapeProps->getPropertyValue(sPersistName) >>= sOUName; +//BM String sName(sOUName); +//BM if (!pChartListener) +//BM { +//BM String aEmptyString; +//BM ScRange aRange; +//BM pChartListener = new ScChartListener ( aEmptyString, GetDocument(), aRange ); +//BM } +//BM if(pChartListener) +//BM { +//BM sal_uInt16 nIndex(0); +//BM pChartListener->SetString( sName ); +//BM if ( GetDocument() && GetDocument()->GetChartListenerCollection()->Search( pChartListener, nIndex ) ) +//BM { +//BM const ScRangeListRef& rRangeListRef(((ScChartListener*) +//BM (GetDocument()->GetChartListenerCollection()-> +//BM At( nIndex )))->GetRangeList()); +//BM if (rRangeListRef.Is()) +//BM { +//BM bMemChart = sal_True; +//BM rtl::OUString sRanges; +//BM ScRangeStringConverter::GetStringFromRangeList(sRanges, rRangeListRef, GetDocument()); +//BM SvXMLAttributeList* pAttrList = NULL; +//BM if (sRanges.getLength()) +//BM { +//BM pAttrList = new SvXMLAttributeList(); +//BM pAttrList->AddAttribute( +//BM GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES) ), sRanges ); +//BM } +//BM GetShapeExport()->exportShape(xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList); +//BM } +//BM } +//BM else +//BM { +//BM bMemChart = sal_True; +//BM SvXMLAttributeList* pAttrList = new SvXMLAttributeList(); +//BM pAttrList->AddAttribute( +//BM GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES) ), rtl::OUString() ); +//BM GetShapeExport()->exportShape(xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList); +//BM } +//BM } + +/* SchMemChart* pMemChart = pDoc->FindChartData(sName); + if (pMemChart && pMemChart->GetSeriesAddresses().getLength()) + { + bMemChart = sal_True; + rtl::OUString sRanges(pMemChart->getXMLStringForChartRange()); + if (sRanges.getLength()) + AddAttribute(XML_NAMESPACE_DRAW, XML_NOTIFY_ON_UPDATE_OF_RANGES, sRanges); + GetShapeExport()->exportShape(xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint); + }*/ + } + } + } + } + if (!bIsChart) + GetShapeExport()->exportShape(xShape, SEF_DEFAULT, pPoint); + IncrementProgressBar(sal_False); +} + +void ScXMLExport::WriteShapes(const ScMyCell& rMyCell) +{ + if( rMyCell.bHasShape && !rMyCell.aShapeList.empty() && pDoc ) + { + awt::Point aPoint; + Rectangle aRec = pDoc->GetMMRect(static_cast<SCCOL>(rMyCell.aCellAddress.Column), static_cast<SCROW>(rMyCell.aCellAddress.Row), + static_cast<SCCOL>(rMyCell.aCellAddress.Column), static_cast<SCROW>(rMyCell.aCellAddress.Row), static_cast<SCTAB>(rMyCell.aCellAddress.Sheet)); + sal_Bool bNegativePage(pDoc->IsNegativePage(rMyCell.aCellAddress.Sheet)); + if (bNegativePage) + aPoint.X = aRec.Right(); + else + aPoint.X = aRec.Left(); + aPoint.Y = aRec.Top(); + ScMyShapeList::const_iterator aItr = rMyCell.aShapeList.begin(); + ScMyShapeList::const_iterator aEndItr(rMyCell.aShapeList.end()); + while (aItr != aEndItr) + { + if (aItr->xShape.is()) + { + if (bNegativePage) + aPoint.X = 2 * aItr->xShape->getPosition().X + aItr->xShape->getSize().Width - aPoint.X; + if ( !aItr->xShape->getShapeType().equals(sCaptionShape) ) + { + awt::Point aEndPoint; + Rectangle aEndRec(pDoc->GetMMRect(aItr->aEndAddress.Col(), aItr->aEndAddress.Row(), + aItr->aEndAddress.Col(), aItr->aEndAddress.Row(), aItr->aEndAddress.Tab())); + rtl::OUString sEndAddress; + ScRangeStringConverter::GetStringFromAddress(sEndAddress, aItr->aEndAddress, pDoc, FormulaGrammar::CONV_OOO); + AddAttribute(XML_NAMESPACE_TABLE, XML_END_CELL_ADDRESS, sEndAddress); + if (bNegativePage) + aEndPoint.X = -aEndRec.Right(); + else + aEndPoint.X = aEndRec.Left(); + aEndPoint.Y = aEndRec.Top(); + awt::Point aStartPoint(aItr->xShape->getPosition()); + awt::Size aSize(aItr->xShape->getSize()); + sal_Int32 nEndX; + if (bNegativePage) + nEndX = -aStartPoint.X - aEndPoint.X; + else + nEndX = aStartPoint.X + aSize.Width - aEndPoint.X; + sal_Int32 nEndY(aStartPoint.Y + aSize.Height - aEndPoint.Y); + rtl::OUStringBuffer sBuffer; + GetMM100UnitConverter().convertMeasure(sBuffer, nEndX); + AddAttribute(XML_NAMESPACE_TABLE, XML_END_X, sBuffer.makeStringAndClear()); + GetMM100UnitConverter().convertMeasure(sBuffer, nEndY); + AddAttribute(XML_NAMESPACE_TABLE, XML_END_Y, sBuffer.makeStringAndClear()); + } + ExportShape(aItr->xShape, &aPoint); + } + ++aItr; + } + } +} + +void ScXMLExport::WriteTableShapes() +{ + ScMyTableShapes* pTableShapes(pSharedData->GetTableShapes()); + if (pTableShapes && !(*pTableShapes)[nCurrentTable].empty()) + { + DBG_ASSERT(pTableShapes->size() > static_cast<size_t>(nCurrentTable), "wrong Table"); + SvXMLElementExport aShapesElem(*this, XML_NAMESPACE_TABLE, XML_SHAPES, sal_True, sal_False); + ScMyTableXShapes::iterator aItr((*pTableShapes)[nCurrentTable].begin()); + ScMyTableXShapes::iterator aEndItr((*pTableShapes)[nCurrentTable].end()); + while (aItr != aEndItr) + { + if (aItr->is()) + { + if (pDoc->IsNegativePage(static_cast<SCTAB>(nCurrentTable))) + { + awt::Point aPoint((*aItr)->getPosition()); + awt::Size aSize((*aItr)->getSize()); + aPoint.X += aPoint.X + aSize.Width; + aPoint.Y = 0; + ExportShape(*aItr, &aPoint); + } + else + ExportShape(*aItr, NULL); + } + aItr = (*pTableShapes)[nCurrentTable].erase(aItr); + } + } +} + +void ScXMLExport::WriteAreaLink( const ScMyCell& rMyCell ) +{ + if( rMyCell.bHasAreaLink ) + { + const ScMyAreaLink& rAreaLink = rMyCell.aAreaLink; + AddAttribute( XML_NAMESPACE_TABLE, XML_NAME, rAreaLink.sSourceStr ); + AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE ); + AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, GetRelativeReference(rAreaLink.sURL) ); + AddAttribute( XML_NAMESPACE_TABLE, XML_FILTER_NAME, rAreaLink.sFilter ); + if( rAreaLink.sFilterOptions.getLength() ) + AddAttribute( XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, rAreaLink.sFilterOptions ); + OUStringBuffer sValue; + SvXMLUnitConverter::convertNumber( sValue, rAreaLink.GetColCount() ); + AddAttribute( XML_NAMESPACE_TABLE, XML_LAST_COLUMN_SPANNED, sValue.makeStringAndClear() ); + SvXMLUnitConverter::convertNumber( sValue, rAreaLink.GetRowCount() ); + AddAttribute( XML_NAMESPACE_TABLE, XML_LAST_ROW_SPANNED, sValue.makeStringAndClear() ); + if( rAreaLink.nRefresh ) + { + SvXMLUnitConverter::convertTime( sValue, (double)rAreaLink.nRefresh / 86400 ); + AddAttribute( XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, sValue.makeStringAndClear() ); + } + SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_CELL_RANGE_SOURCE, sal_True, sal_True ); + } +} + +void ScXMLExport::exportAnnotationMeta( const uno::Reference < drawing::XShape >& xShape) +{ + if (pCurrentCell && pCurrentCell->xNoteShape.is() && pCurrentCell->xNoteShape.get() == xShape.get() && pCurrentCell->xAnnotation.is()) + { + rtl::OUString sAuthor(pCurrentCell->xAnnotation->getAuthor()); + if (sAuthor.getLength()) + { + SvXMLElementExport aCreatorElem( *this, XML_NAMESPACE_DC, + XML_CREATOR, sal_True, + sal_False ); + Characters(sAuthor); + } + + String aDate(pCurrentCell->xAnnotation->getDate()); + if (pDoc) + { + SvNumberFormatter* pNumForm = pDoc->GetFormatTable(); + double fDate; + sal_uInt32 nfIndex = pNumForm->GetFormatIndex(NF_DATE_SYS_DDMMYYYY, LANGUAGE_SYSTEM); + if (pNumForm->IsNumberFormat(aDate, nfIndex, fDate)) + { + rtl::OUStringBuffer sBuf; + GetMM100UnitConverter().convertDateTime(sBuf, fDate,sal_True); + SvXMLElementExport aDateElem( *this, XML_NAMESPACE_DC, + XML_DATE, sal_True, + sal_False ); + Characters(sBuf.makeStringAndClear()); + } + else + { + SvXMLElementExport aDateElem( *this, XML_NAMESPACE_META, + XML_DATE_STRING, sal_True, + sal_False ); + Characters(rtl::OUString(aDate)); + } + } + else + { + SvXMLElementExport aDateElem( *this, XML_NAMESPACE_META, + XML_DATE_STRING, sal_True, + sal_False ); + Characters(rtl::OUString(aDate)); + } + } +} + +void ScXMLExport::WriteAnnotation(ScMyCell& rMyCell) +{ + if( rMyCell.bHasAnnotation && rMyCell.xAnnotation.is()) + { +/* rtl::OUString sAuthor(rMyCell.xAnnotation->getAuthor()); + if (sAuthor.getLength()) + { + SvXMLElementExport aCreatorElem( *this, XML_NAMESPACE_DC, + XML_CREATOR, sal_True, + sal_False ); + rtl::OUString sAuthor(sAuthor); + Characters(sAuthor); + } + + String aDate(rMyCell.xAnnotation->getDate()); + if (pDoc) + { + SvNumberFormatter* pNumForm(pDoc->GetFormatTable()); + double fDate; + sal_uInt32 nfIndex = pNumForm->GetFormatIndex(NF_DATE_SYS_DDMMYYYY, LANGUAGE_SYSTEM); + if (pNumForm->IsNumberFormat(aDate, nfIndex, fDate)) + { + rtl::OUStringBuffer sBuf; + GetMM100UnitConverter().convertDateTime(sBuf, fDate); + SvXMLElementExport aDateElem( *this, XML_NAMESPACE_DC, + XML_DATE, sal_True, + sal_False ); + Characters(sBuf.makeStringAndClear()); + } + else + { + SvXMLElementExport aDateElem( *this, XML_NAMESPACE_META, + XML_DATE_STRING, sal_True, + sal_False ); + Characters(rtl::OUString(aDate)); + } + } + else + { + SvXMLElementExport aDateElem( *this, XML_NAMESPACE_META, + XML_DATE_STRING, sal_True, + sal_False ); + Characters(rtl::OUString(aDate)); + }*/ + + if (rMyCell.xAnnotation->getIsVisible()) + AddAttribute(XML_NAMESPACE_OFFICE, XML_DISPLAY, XML_TRUE); + + pCurrentCell = &rMyCell; + + if(rMyCell.xNoteShape.is()) + GetShapeExport()->exportShape(rMyCell.xNoteShape, SEF_DEFAULT|SEF_EXPORT_ANNOTATION, NULL); + + pCurrentCell = NULL; + + rMyCell.xNoteShape.clear(); + } +} + +void ScXMLExport::WriteDetective( const ScMyCell& rMyCell ) +{ + if( rMyCell.bHasDetectiveObj || rMyCell.bHasDetectiveOp ) + { + const ScMyDetectiveObjVec& rObjVec = rMyCell.aDetectiveObjVec; + const ScMyDetectiveOpVec& rOpVec = rMyCell.aDetectiveOpVec; + sal_Int32 nObjCount(rObjVec.size()); + sal_Int32 nOpCount(rOpVec.size()); + if( nObjCount || nOpCount ) + { + SvXMLElementExport aDetElem( *this, XML_NAMESPACE_TABLE, XML_DETECTIVE, sal_True, sal_True ); + OUString sString; + ScMyDetectiveObjVec::const_iterator aObjItr(rObjVec.begin()); + ScMyDetectiveObjVec::const_iterator aEndObjItr(rObjVec.end()); + while(aObjItr != aEndObjItr) + { + if (aObjItr->eObjType != SC_DETOBJ_CIRCLE) + { + if( (aObjItr->eObjType == SC_DETOBJ_ARROW) || (aObjItr->eObjType == SC_DETOBJ_TOOTHERTAB)) + { + ScRangeStringConverter::GetStringFromRange( sString, aObjItr->aSourceRange, pDoc, FormulaGrammar::CONV_OOO ); + AddAttribute( XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, sString ); + } + ScXMLConverter::GetStringFromDetObjType( sString, aObjItr->eObjType ); + AddAttribute( XML_NAMESPACE_TABLE, XML_DIRECTION, sString ); + if( aObjItr->bHasError ) + AddAttribute( XML_NAMESPACE_TABLE, XML_CONTAINS_ERROR, XML_TRUE ); + } + else + AddAttribute( XML_NAMESPACE_TABLE, XML_MARKED_INVALID, XML_TRUE ); + SvXMLElementExport aRangeElem( *this, XML_NAMESPACE_TABLE, XML_HIGHLIGHTED_RANGE, sal_True, sal_True ); + ++aObjItr; + } + OUStringBuffer aBuffer; + ScMyDetectiveOpVec::const_iterator aOpItr(rOpVec.begin()); + ScMyDetectiveOpVec::const_iterator aEndOpItr(rOpVec.end()); + while(aOpItr != aEndOpItr) + { + OUString sOpString; + ScXMLConverter::GetStringFromDetOpType( sOpString, aOpItr->eOpType ); + AddAttribute( XML_NAMESPACE_TABLE, XML_NAME, sOpString ); + SvXMLUnitConverter::convertNumber( aBuffer, aOpItr->nIndex ); + AddAttribute( XML_NAMESPACE_TABLE, XML_INDEX, aBuffer.makeStringAndClear() ); + SvXMLElementExport aRangeElem( *this, XML_NAMESPACE_TABLE, XML_OPERATION, sal_True, sal_True ); + ++aOpItr; + } + } + } +} + +void ScXMLExport::SetRepeatAttribute (const sal_Int32 nEqualCellCount) +{ + if (nEqualCellCount > 0) + { + sal_Int32 nTemp(nEqualCellCount + 1); + OUString sOUEqualCellCount(OUString::valueOf(nTemp)); + AddAttribute(sAttrColumnsRepeated, sOUEqualCellCount); + IncrementProgressBar(sal_False, nEqualCellCount); + } +} + +sal_Bool ScXMLExport::IsCellTypeEqual (const ScMyCell& aCell1, const ScMyCell& aCell2) const +{ + return (aCell1.nType == aCell2.nType); +} + +sal_Bool ScXMLExport::IsEditCell(const com::sun::star::table::CellAddress& aAddress, ScMyCell* pMyCell) const +{ + ScAddress aCoreAddress(static_cast<SCCOL>(aAddress.Column), + static_cast<SCROW>(aAddress.Row), + static_cast<SCTAB>(aAddress.Sheet)); + ScBaseCell* pBaseCell = GetDocument() ? GetDocument()->GetCell(aCoreAddress) : NULL; + if (pMyCell) + pMyCell->pBaseCell = pBaseCell; + + if (pBaseCell) + return (pBaseCell->GetCellType() == CELLTYPE_EDIT); + return sal_False; +} + +//UNUSED2008-05 sal_Bool ScXMLExport::IsEditCell(const com::sun::star::uno::Reference <com::sun::star::table::XCell>& xCell) const +//UNUSED2008-05 { +//UNUSED2008-05 uno::Reference<sheet::XCellAddressable> xAddressable (xCell, uno::UNO_QUERY); +//UNUSED2008-05 if ( xAddressable.is() ) +//UNUSED2008-05 return IsEditCell(xAddressable->getCellAddress()); +//UNUSED2008-05 return sal_False; +//UNUSED2008-05 } + +sal_Bool ScXMLExport::IsEditCell(ScMyCell& rCell) const +{ + if (rCell.bKnowWhetherIsEditCell) + return rCell.bIsEditCell; + else + { + rCell.bIsEditCell = IsEditCell(rCell.aCellAddress, &rCell); + rCell.bKnowWhetherIsEditCell = sal_True; + return rCell.bIsEditCell; + } +} + +sal_Bool ScXMLExport::IsMultiLineFormulaCell(ScMyCell& rCell) const +{ + if (rCell.pBaseCell) + { + if (rCell.pBaseCell->GetCellType() != CELLTYPE_FORMULA) + return false; + + return static_cast<ScFormulaCell*>(rCell.pBaseCell)->IsMultilineResult(); + } + + ScAddress aAddr(static_cast<SCCOL>(rCell.aCellAddress.Column), + static_cast<SCROW>(rCell.aCellAddress.Row), + static_cast<SCTAB>(rCell.aCellAddress.Sheet)); + ScBaseCell* pBaseCell = pDoc ? pDoc->GetCell(aAddr) : NULL; + if (!pBaseCell) + return false; + + rCell.pBaseCell = pBaseCell; + if (rCell.pBaseCell->GetCellType() != CELLTYPE_FORMULA) + return false; + + return static_cast<ScFormulaCell*>(rCell.pBaseCell)->IsMultilineResult(); +} + +//UNUSED2008-05 sal_Bool ScXMLExport::IsAnnotationEqual(const uno::Reference<table::XCell>& /* xCell1 */, +//UNUSED2008-05 const uno::Reference<table::XCell>& /* xCell2 */) +//UNUSED2008-05 { +//UNUSED2008-05 // no longer compareable, because the position and size and other attributes can also differ +//UNUSED2008-05 +//UNUSED2008-05 /* uno::Reference<sheet::XSheetAnnotationAnchor> xSheetAnnotationAnchor1(xCell1, uno::UNO_QUERY); +//UNUSED2008-05 uno::Reference<sheet::XSheetAnnotationAnchor> xSheetAnnotationAnchor2(xCell2, uno::UNO_QUERY); +//UNUSED2008-05 if (xSheetAnnotationAnchor1.is() && xSheetAnnotationAnchor2.is()) +//UNUSED2008-05 { +//UNUSED2008-05 uno::Reference <sheet::XSheetAnnotation> xSheetAnnotation1(xSheetAnnotationAnchor1->getAnnotation()); +//UNUSED2008-05 uno::Reference <sheet::XSheetAnnotation> xSheetAnnotation2(xSheetAnnotationAnchor2->getAnnotation()); +//UNUSED2008-05 uno::Reference<text::XSimpleText> xSimpleText1(xSheetAnnotation1, uno::UNO_QUERY); +//UNUSED2008-05 uno::Reference<text::XSimpleText> xSimpleText2(xSheetAnnotation2, uno::UNO_QUERY); +//UNUSED2008-05 if (xSheetAnnotation1.is() && xSimpleText1.is() && +//UNUSED2008-05 xSheetAnnotation2.is() && xSimpleText2.is()) +//UNUSED2008-05 { +//UNUSED2008-05 rtl::OUString sText1(xSimpleText1->getString()); +//UNUSED2008-05 rtl::OUString sText2(xSimpleText2->getString()); +//UNUSED2008-05 sal_Int32 nLength1(sText1.getLength()); +//UNUSED2008-05 sal_Int32 nLength2(sText2.getLength()); +//UNUSED2008-05 if (nLength1 && nLength2) +//UNUSED2008-05 if (sText1 == sText2 && +//UNUSED2008-05 xSheetAnnotation1->getAuthor() == xSheetAnnotation2->getAuthor() && +//UNUSED2008-05 xSheetAnnotation1->getDate() == xSheetAnnotation2->getDate() && +//UNUSED2008-05 xSheetAnnotation1->getIsVisible() == xSheetAnnotation2->getIsVisible()) +//UNUSED2008-05 return sal_True; +//UNUSED2008-05 else +//UNUSED2008-05 return sal_False; +//UNUSED2008-05 else +//UNUSED2008-05 if (nLength1 || nLength2) +//UNUSED2008-05 return sal_False; +//UNUSED2008-05 else +//UNUSED2008-05 return sal_True; +//UNUSED2008-05 } +//UNUSED2008-05 }*/ +//UNUSED2008-05 return sal_False; +//UNUSED2008-05 } + +sal_Bool ScXMLExport::IsCellEqual (ScMyCell& aCell1, ScMyCell& aCell2) +{ + ScAddress aCellPos1; + ScUnoConversion::FillScAddress( aCellPos1, aCell1.aCellAddress ); + ScAddress aCellPos2; + ScUnoConversion::FillScAddress( aCellPos2, aCell2.aCellAddress ); + sal_Bool bIsEqual = sal_False; + if( !aCell1.bIsMergedBase && !aCell2.bIsMergedBase && + aCell1.bIsCovered == aCell2.bIsCovered && + !aCell1.bIsMatrixBase && !aCell2.bIsMatrixBase && + aCell1.bIsMatrixCovered == aCell2.bIsMatrixCovered && + aCell1.bHasAnnotation == aCell2.bHasAnnotation && + !aCell1.bHasShape && !aCell2.bHasShape && + aCell1.bHasAreaLink == aCell2.bHasAreaLink && + !aCell1.bHasDetectiveObj && !aCell2.bHasDetectiveObj) + { + if( (aCell1.bHasAreaLink && + (aCell1.aAreaLink.GetColCount() == 1) && + (aCell2.aAreaLink.GetColCount() == 1) && + aCell1.aAreaLink.Compare( aCell2.aAreaLink ) ) || + !aCell1.bHasAreaLink ) + { + if (!aCell1.bHasAnnotation || (aCell1.bHasAnnotation && sal_False/*IsAnnotationEqual(aCell1.xCell, aCell2.xCell)*/)) // no longer compareable + { + if ((((aCell1.nStyleIndex == aCell2.nStyleIndex) && (aCell1.bIsAutoStyle == aCell2.bIsAutoStyle)) || + ((aCell1.nStyleIndex == aCell2.nStyleIndex) && (aCell1.nStyleIndex == -1))) && + (aCell1.nValidationIndex == aCell2.nValidationIndex) && + IsCellTypeEqual(aCell1, aCell2)) + { + switch ( aCell1.nType ) + { + case table::CellContentType_EMPTY : + { + bIsEqual = sal_True; + } + break; + case table::CellContentType_VALUE : + { + if(!aCell1.bHasDoubleValue) + { + aCell1.fValue = pDoc->GetValue( aCellPos1 ); + aCell1.bHasDoubleValue = sal_True; + } + if (!aCell2.bHasDoubleValue) + { + aCell2.fValue = pDoc->GetValue( aCellPos2 ); + aCell2.bHasDoubleValue = sal_True; + } + // #i29101# number format may be different from column default styles, + // but can lead to different value types, so it must also be compared + bIsEqual = (aCell1.nNumberFormat == aCell2.nNumberFormat) && + (aCell1.fValue == aCell2.fValue); + } + break; + case table::CellContentType_TEXT : + { + if (IsEditCell(aCell1) || IsEditCell(aCell2)) + bIsEqual = sal_False; + else + { + if (GetCellText(aCell1, aCellPos1) && GetCellText(aCell2, aCellPos2)) + { + bIsEqual = (aCell1.sStringValue == aCell2.sStringValue) && + (lcl_GetRawString(pDoc, aCellPos1) == lcl_GetRawString(pDoc, aCellPos2)); + } + else + bIsEqual = sal_False; + } + } + break; + case table::CellContentType_FORMULA : + { + bIsEqual = sal_False; + } + break; + default : + { + bIsEqual = sal_False; + } + break; + } + } + } + } + } + return bIsEqual; +} + +void ScXMLExport::WriteCalculationSettings(const uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc) +{ + uno::Reference<beans::XPropertySet> xPropertySet(xSpreadDoc, uno::UNO_QUERY); + if (xPropertySet.is()) + { + sal_Bool bCalcAsShown (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_CALCASSHOWN))) )); + sal_Bool bIgnoreCase (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_IGNORECASE))) )); + sal_Bool bLookUpLabels (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_LOOKUPLABELS))) )); + sal_Bool bMatchWholeCell (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_MATCHWHOLE))) )); + sal_Bool bUseRegularExpressions (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_REGEXENABLED))) )); + sal_Bool bIsIterationEnabled (::cppu::any2bool( xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITERENABLED))) )); + sal_uInt16 nYear2000 (pDoc ? pDoc->GetDocOptions().GetYear2000() : 0); + sal_Int32 nIterationCount(100); + xPropertySet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITERCOUNT))) >>= nIterationCount; + double fIterationEpsilon = 0; + xPropertySet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ITEREPSILON))) >>= fIterationEpsilon; + util::Date aNullDate; + xPropertySet->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_NULLDATE))) >>= aNullDate; + if (bCalcAsShown || bIgnoreCase || !bLookUpLabels || !bMatchWholeCell || !bUseRegularExpressions || + bIsIterationEnabled || nIterationCount != 100 || !::rtl::math::approxEqual(fIterationEpsilon, 0.001) || + aNullDate.Day != 30 || aNullDate.Month != 12 || aNullDate.Year != 1899 || nYear2000 != 1930) + { + if (bIgnoreCase) + AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_FALSE); + if (bCalcAsShown) + AddAttribute(XML_NAMESPACE_TABLE, XML_PRECISION_AS_SHOWN, XML_TRUE); + if (!bMatchWholeCell) + AddAttribute(XML_NAMESPACE_TABLE, XML_SEARCH_CRITERIA_MUST_APPLY_TO_WHOLE_CELL, XML_FALSE); + if (!bLookUpLabels) + AddAttribute(XML_NAMESPACE_TABLE, XML_AUTOMATIC_FIND_LABELS, XML_FALSE); + if (!bUseRegularExpressions) + AddAttribute(XML_NAMESPACE_TABLE, XML_USE_REGULAR_EXPRESSIONS, XML_FALSE); + if (nYear2000 != 1930) + { + rtl::OUStringBuffer sBuffer; + GetMM100UnitConverter().convertNumber(sBuffer, nYear2000); + AddAttribute(XML_NAMESPACE_TABLE, XML_NULL_YEAR, sBuffer.makeStringAndClear()); + } + SvXMLElementExport aCalcSettings(*this, XML_NAMESPACE_TABLE, XML_CALCULATION_SETTINGS, sal_True, sal_True); + { + if (aNullDate.Day != 30 || aNullDate.Month != 12 || aNullDate.Year != 1899) + { + rtl::OUStringBuffer sDate; + GetMM100UnitConverter().convertDateTime(sDate, 0.0, aNullDate); + AddAttribute(XML_NAMESPACE_TABLE, XML_DATE_VALUE, sDate.makeStringAndClear()); + SvXMLElementExport aElemNullDate(*this, XML_NAMESPACE_TABLE, XML_NULL_DATE, sal_True, sal_True); + } + if (bIsIterationEnabled || nIterationCount != 100 || !::rtl::math::approxEqual(fIterationEpsilon, 0.001)) + { + rtl::OUStringBuffer sBuffer; + if (bIsIterationEnabled) + AddAttribute(XML_NAMESPACE_TABLE, XML_STATUS, XML_ENABLE); + if (nIterationCount != 100) + { + GetMM100UnitConverter().convertNumber(sBuffer, nIterationCount); + AddAttribute(XML_NAMESPACE_TABLE, XML_STEPS, sBuffer.makeStringAndClear()); + } + if (!::rtl::math::approxEqual(fIterationEpsilon, 0.001)) + { + GetMM100UnitConverter().convertDouble(sBuffer, fIterationEpsilon); + AddAttribute(XML_NAMESPACE_TABLE, XML_MAXIMUM_DIFFERENCE, sBuffer.makeStringAndClear()); + } + SvXMLElementExport aElemIteration(*this, XML_NAMESPACE_TABLE, XML_ITERATION, sal_True, sal_True); + } + } + } + } +} + +void ScXMLExport::WriteTableSource() +{ + uno::Reference <sheet::XSheetLinkable> xLinkable (xCurrentTable, uno::UNO_QUERY); + if (xLinkable.is() && GetModel().is()) + { + sheet::SheetLinkMode nMode (xLinkable->getLinkMode()); + if (nMode != sheet::SheetLinkMode_NONE) + { + rtl::OUString sLink (xLinkable->getLinkUrl()); + uno::Reference <beans::XPropertySet> xProps (GetModel(), uno::UNO_QUERY); + if (xProps.is()) + { + uno::Reference <container::XIndexAccess> xIndex(xProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_SHEETLINKS))), uno::UNO_QUERY); + if (xIndex.is()) + { + sal_Int32 nCount(xIndex->getCount()); + if (nCount) + { + sal_Bool bFound(sal_False); + uno::Reference <beans::XPropertySet> xLinkProps; + for (sal_Int32 i = 0; (i < nCount) && !bFound; ++i) + { + xLinkProps.set(xIndex->getByIndex(i), uno::UNO_QUERY); + if (xLinkProps.is()) + { + rtl::OUString sNewLink; + if (xLinkProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_LINKURL))) >>= sNewLink) + bFound = sLink.equals(sNewLink); + } + } + if (bFound && xLinkProps.is()) + { + rtl::OUString sFilter; + rtl::OUString sFilterOptions; + rtl::OUString sTableName (xLinkable->getLinkSheetName()); + sal_Int32 nRefresh(0); + xLinkProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_FILTER))) >>= sFilter; + xLinkProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_FILTOPT))) >>= sFilterOptions; + xLinkProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_REFDELAY))) >>= nRefresh; + if (sLink.getLength()) + { + AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE); + AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, GetRelativeReference(sLink)); + if (sTableName.getLength()) + AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, sTableName); + if (sFilter.getLength()) + AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_NAME, sFilter); + if (sFilterOptions.getLength()) + AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, sFilterOptions); + if (nMode != sheet::SheetLinkMode_NORMAL) + AddAttribute(XML_NAMESPACE_TABLE, XML_MODE, XML_COPY_RESULTS_ONLY); + if( nRefresh ) + { + rtl::OUStringBuffer sBuffer; + SvXMLUnitConverter::convertTime( sBuffer, (double)nRefresh / 86400 ); + AddAttribute( XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, sBuffer.makeStringAndClear() ); + } + SvXMLElementExport aSourceElem(*this, XML_NAMESPACE_TABLE, XML_TABLE_SOURCE, sal_True, sal_True); + } + } + } + } + } + } + } +} + +// core implementation +void ScXMLExport::WriteScenario() +{ + if (pDoc && pDoc->IsScenario(static_cast<SCTAB>(nCurrentTable))) + { + String sComment; + Color aColor; + sal_uInt16 nFlags; + pDoc->GetScenarioData(static_cast<SCTAB>(nCurrentTable), sComment, aColor, nFlags); + if (!(nFlags & SC_SCENARIO_SHOWFRAME)) + AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY_BORDER, XML_FALSE); + rtl::OUStringBuffer aBuffer; + SvXMLUnitConverter::convertColor(aBuffer, aColor); + AddAttribute(XML_NAMESPACE_TABLE, XML_BORDER_COLOR, aBuffer.makeStringAndClear()); + if (!(nFlags & SC_SCENARIO_TWOWAY)) + AddAttribute(XML_NAMESPACE_TABLE, XML_COPY_BACK, XML_FALSE); + if (!(nFlags & SC_SCENARIO_ATTRIB)) + AddAttribute(XML_NAMESPACE_TABLE, XML_COPY_STYLES, XML_FALSE); + if (nFlags & SC_SCENARIO_VALUE) + AddAttribute(XML_NAMESPACE_TABLE, XML_COPY_FORMULAS, XML_FALSE); + if (nFlags & SC_SCENARIO_PROTECT) + AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TRUE); + SvXMLUnitConverter::convertBool(aBuffer, pDoc->IsActiveScenario(static_cast<SCTAB>(nCurrentTable))); + AddAttribute(XML_NAMESPACE_TABLE, XML_IS_ACTIVE, aBuffer.makeStringAndClear()); + const ScRangeList* pRangeList = pDoc->GetScenarioRanges(static_cast<SCTAB>(nCurrentTable)); + rtl::OUString sRangeListStr; + ScRangeStringConverter::GetStringFromRangeList( sRangeListStr, pRangeList, pDoc, FormulaGrammar::CONV_OOO ); + AddAttribute(XML_NAMESPACE_TABLE, XML_SCENARIO_RANGES, sRangeListStr); + if (sComment.Len()) + AddAttribute(XML_NAMESPACE_TABLE, XML_COMMENT, rtl::OUString(sComment)); + SvXMLElementExport aElem(*this, XML_NAMESPACE_TABLE, XML_SCENARIO, sal_True, sal_True); + } +} + +void ScXMLExport::WriteTheLabelRanges( const uno::Reference< sheet::XSpreadsheetDocument >& xSpreadDoc ) +{ + uno::Reference< beans::XPropertySet > xDocProp( xSpreadDoc, uno::UNO_QUERY ); + if( !xDocProp.is() ) return; + + sal_Int32 nCount(0); + uno::Reference< container::XIndexAccess > xColRangesIAccess(xDocProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_COLLABELRNG ) ) ), uno::UNO_QUERY); + if( xColRangesIAccess.is() ) + nCount += xColRangesIAccess->getCount(); + + uno::Reference< container::XIndexAccess > xRowRangesIAccess(xDocProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_ROWLABELRNG ) ) ), uno::UNO_QUERY); + if( xRowRangesIAccess.is() ) + nCount += xRowRangesIAccess->getCount(); + + if( nCount ) + { + SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_LABEL_RANGES, sal_True, sal_True ); + WriteLabelRanges( xColRangesIAccess, sal_True ); + WriteLabelRanges( xRowRangesIAccess, sal_False ); + } +} + +void ScXMLExport::WriteLabelRanges( const uno::Reference< container::XIndexAccess >& xRangesIAccess, sal_Bool bColumn ) +{ + if( !xRangesIAccess.is() ) return; + + sal_Int32 nCount(xRangesIAccess->getCount()); + for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex ) + { + uno::Reference< sheet::XLabelRange > xRange(xRangesIAccess->getByIndex( nIndex ), uno::UNO_QUERY); + if( xRange.is() ) + { + OUString sRangeStr; + table::CellRangeAddress aCellRange( xRange->getLabelArea() ); + ScRangeStringConverter::GetStringFromRange( sRangeStr, aCellRange, pDoc, FormulaGrammar::CONV_OOO ); + AddAttribute( XML_NAMESPACE_TABLE, XML_LABEL_CELL_RANGE_ADDRESS, sRangeStr ); + aCellRange = xRange->getDataArea(); + ScRangeStringConverter::GetStringFromRange( sRangeStr, aCellRange, pDoc, FormulaGrammar::CONV_OOO ); + AddAttribute( XML_NAMESPACE_TABLE, XML_DATA_CELL_RANGE_ADDRESS, sRangeStr ); + AddAttribute( XML_NAMESPACE_TABLE, XML_ORIENTATION, bColumn ? XML_COLUMN : XML_ROW ); + SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_LABEL_RANGE, sal_True, sal_True ); + } + } +} + +void ScXMLExport::WriteNamedExpressions(const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xSpreadDoc) +{ + uno::Reference <beans::XPropertySet> xPropertySet (xSpreadDoc, uno::UNO_QUERY); + if (xPropertySet.is()) + { + uno::Reference <sheet::XNamedRanges> xNamedRanges(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_NAMEDRANGES))), uno::UNO_QUERY); + CheckAttrList(); + if (xNamedRanges.is()) + { + uno::Sequence <rtl::OUString> aRangesNames(xNamedRanges->getElementNames()); + sal_Int32 nNamedRangesCount(aRangesNames.getLength()); + if (nNamedRangesCount > 0) + { + if (pDoc) + { + ScRangeName* pNamedRanges(pDoc->GetRangeName()); + SvXMLElementExport aElemNEs(*this, XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSIONS, sal_True, sal_True); + for (sal_Int32 i = 0; i < nNamedRangesCount; ++i) + { + CheckAttrList(); + rtl::OUString sNamedRange(aRangesNames[i]); + uno::Reference <sheet::XNamedRange> xNamedRange(xNamedRanges->getByName(sNamedRange), uno::UNO_QUERY); + if (xNamedRange.is()) + { + uno::Reference <container::XNamed> xNamed (xNamedRange, uno::UNO_QUERY); + uno::Reference <sheet::XCellRangeReferrer> xCellRangeReferrer (xNamedRange, uno::UNO_QUERY); + if (xNamed.is() && xCellRangeReferrer.is()) + { + rtl::OUString sOUName(xNamed->getName()); + AddAttribute(sAttrName, sOUName); + + OUString sOUBaseCellAddress; + ScRangeStringConverter::GetStringFromAddress( sOUBaseCellAddress, + xNamedRange->getReferencePosition(), pDoc, FormulaGrammar::CONV_OOO, ' ', sal_False, SCA_ABS_3D ); + AddAttribute(XML_NAMESPACE_TABLE, XML_BASE_CELL_ADDRESS, sOUBaseCellAddress); + + sal_uInt16 nRangeIndex; + String sName(sOUName); + pNamedRanges->SearchName(sName, nRangeIndex); + ScRangeData* pNamedRange((*pNamedRanges)[nRangeIndex]); //should get directly and not with ScDocument + String sContent; + pNamedRange->GetSymbol(sContent, pDoc->GetStorageGrammar()); + rtl::OUString sOUTempContent(sContent); + uno::Reference <table::XCellRange> xCellRange(xCellRangeReferrer->getReferredCells()); + if(xCellRange.is()) + { + rtl::OUString sOUContent(sOUTempContent.copy(1, sOUTempContent.getLength() - 2)); + AddAttribute(XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, sOUContent); + sal_Int32 nRangeType(xNamedRange->getType()); + rtl::OUStringBuffer sBufferRangeType; + if ((nRangeType & sheet::NamedRangeFlag::COLUMN_HEADER) == sheet::NamedRangeFlag::COLUMN_HEADER) + sBufferRangeType.append(GetXMLToken(XML_REPEAT_COLUMN)); + if ((nRangeType & sheet::NamedRangeFlag::ROW_HEADER) == sheet::NamedRangeFlag::ROW_HEADER) + { + if (sBufferRangeType.getLength() > 0) + sBufferRangeType.appendAscii(" "); + sBufferRangeType.append(GetXMLToken(XML_REPEAT_ROW)); + } + if ((nRangeType & sheet::NamedRangeFlag::FILTER_CRITERIA) == sheet::NamedRangeFlag::FILTER_CRITERIA) + { + if (sBufferRangeType.getLength() > 0) + sBufferRangeType.appendAscii(" "); + sBufferRangeType.append(GetXMLToken(XML_FILTER)); + } + if ((nRangeType & sheet::NamedRangeFlag::PRINT_AREA) == sheet::NamedRangeFlag::PRINT_AREA) + { + if (sBufferRangeType.getLength() > 0) + sBufferRangeType.appendAscii(" "); + sBufferRangeType.append(GetXMLToken(XML_PRINT_RANGE)); + } + rtl::OUString sRangeType = sBufferRangeType.makeStringAndClear(); + if (sRangeType.getLength()) + AddAttribute(XML_NAMESPACE_TABLE, XML_RANGE_USABLE_AS, sRangeType); + SvXMLElementExport aElemNR(*this, XML_NAMESPACE_TABLE, XML_NAMED_RANGE, sal_True, sal_True); + } + else + { + AddAttribute(XML_NAMESPACE_TABLE, XML_EXPRESSION, sOUTempContent); + SvXMLElementExport aElemNE(*this, XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSION, sal_True, sal_True); + } + } + } + } + } + } + } + } +} + +void ScXMLExport::WriteExternalRefCaches() +{ + if (!pDoc) + return; + + ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager(); + pRefMgr->resetSrcFileData(GetOrigFileName()); + sal_uInt16 nCount = pRefMgr->getExternalFileCount(); + for (sal_uInt16 nFileId = 0; nFileId < nCount; ++nFileId) + { + const String* pUrl = pRefMgr->getExternalFileName(nFileId); + if (!pUrl) + continue; + + vector<String> aTabNames; + pRefMgr->getAllCachedTableNames(nFileId, aTabNames); + if (aTabNames.empty()) + continue; + + for (vector<String>::const_iterator itr = aTabNames.begin(), itrEnd = aTabNames.end(); + itr != itrEnd; ++itr) + { + ScExternalRefCache::TableTypeRef pTable = pRefMgr->getCacheTable(nFileId, *itr, false); + if (!pTable.get() || !pTable->isReferenced()) + continue; + + OUStringBuffer aBuf; + aBuf.append(sal_Unicode('\'')); + aBuf.append(*pUrl); + aBuf.append(sal_Unicode('\'')); + aBuf.append(sal_Unicode('#')); + aBuf.append(*itr); + AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, aBuf.makeStringAndClear()); + AddAttribute(XML_NAMESPACE_TABLE, XML_PRINT, GetXMLToken(XML_FALSE)); + AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, sExternalRefTabStyleName); + SvXMLElementExport aElemTable(*this, XML_NAMESPACE_TABLE, XML_TABLE, sal_True, sal_True); + { + const ScExternalRefManager::SrcFileData* pExtFileData = pRefMgr->getExternalFileData(nFileId); + if (pExtFileData) + { + String aRelUrl; + if (pExtFileData->maRelativeName.Len()) + aRelUrl = pExtFileData->maRelativeName; + else + aRelUrl = GetRelativeReference(pExtFileData->maRelativeName); + AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE); + AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, aRelUrl); + AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, *itr); + if (pExtFileData->maFilterName.Len()) + AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_NAME, pExtFileData->maFilterName); + if (pExtFileData->maFilterOptions.Len()) + AddAttribute(XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, pExtFileData->maFilterOptions); + AddAttribute(XML_NAMESPACE_TABLE, XML_MODE, XML_COPY_RESULTS_ONLY); + } + SvXMLElementExport aElemTableSource(*this, XML_NAMESPACE_TABLE, XML_TABLE_SOURCE, sal_True, sal_True); + } + + // Determine maximum column count of used area, for repeated cells. + SCCOL nMaxColsUsed = 1; // assume that there is at least one cell somewhere.. + vector<SCROW> aRows; + pTable->getAllRows(aRows); + for (vector<SCROW>::const_iterator itrRow = aRows.begin(), itrRowEnd = aRows.end(); + itrRow != itrRowEnd; ++itrRow) + { + SCROW nRow = *itrRow; + vector<SCCOL> aCols; + pTable->getAllCols(nRow, aCols); + if (!aCols.empty()) + { + SCCOL nCol = aCols.back(); + if (nMaxColsUsed <= nCol) + nMaxColsUsed = nCol + 1; + } + } + + // Column definitions have to be present to make a valid file + { + if (nMaxColsUsed > 1) + AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, + OUString::valueOf(static_cast<sal_Int32>(nMaxColsUsed))); + SvXMLElementExport aElemColumn(*this, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, sal_True, sal_True); + } + + // Write cache content for this table. + SCROW nLastRow = 0; + bool bFirstRow = true; + for (vector<SCROW>::const_iterator itrRow = aRows.begin(), itrRowEnd = aRows.end(); + itrRow != itrRowEnd; ++itrRow) + { + SCROW nRow = *itrRow; + if (bFirstRow) + { + if (nRow > 0) + { + if (nRow > 1) + { + OUStringBuffer aVal; + aVal.append(nRow); + AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, aVal.makeStringAndClear()); + } + SvXMLElementExport aElemRow(*this, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True); + OUStringBuffer aVal; + aVal.append(static_cast<sal_Int32>(nMaxColsUsed)); + AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear()); + SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True); + } + } + else + { + SCROW nRowGap = nRow - nLastRow; + if (nRowGap > 1) + { + if (nRowGap > 2) + { + OUStringBuffer aVal; + aVal.append(static_cast<sal_Int32>(nRowGap-1)); + AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, aVal.makeStringAndClear()); + } + SvXMLElementExport aElemRow(*this, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True); + OUStringBuffer aVal; + aVal.append(static_cast<sal_Int32>(nMaxColsUsed)); + AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear()); + SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True); + } + } + SvXMLElementExport aElemRow(*this, XML_NAMESPACE_TABLE, XML_TABLE_ROW, sal_True, sal_True); + + vector<SCCOL> aCols; + pTable->getAllCols(nRow, aCols); + SCCOL nLastCol = 0; + bool bFirstCol = true; + for (vector<SCCOL>::const_iterator itrCol = aCols.begin(), itrColEnd = aCols.end(); + itrCol != itrColEnd; ++itrCol) + { + SCCOL nCol = *itrCol; + if (bFirstCol) + { + if (nCol > 0) + { + if (nCol > 1) + { + OUStringBuffer aVal; + aVal.append(static_cast<sal_Int32>(nCol)); + AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear()); + } + SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True); + } + } + else + { + SCCOL nColGap = nCol - nLastCol; + if (nColGap > 1) + { + if (nColGap > 2) + { + OUStringBuffer aVal; + aVal.append(static_cast<sal_Int32>(nColGap-1)); + AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, aVal.makeStringAndClear()); + } + SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True); + } + } + + // Write out this cell. + sal_uInt32 nNumFmt = 0; + ScExternalRefCache::TokenRef pToken = pTable->getCell(nCol, nRow, &nNumFmt); + OUString aStrVal; + if (pToken.get()) + { + sal_Int32 nIndex = GetNumberFormatStyleIndex(nNumFmt); + if (nIndex >= 0) + { + const OUString aStyleName = *pCellStyles->GetStyleNameByIndex(nIndex, true); + AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, aStyleName); + } + + switch(pToken->GetType()) + { + case svDouble: + { + AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT); + OUStringBuffer aVal; + aVal.append(pToken->GetDouble()); + aStrVal = aVal.makeStringAndClear(); + AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE, aStrVal); + } + break; + case svString: + { + AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING); + aStrVal = pToken->GetString(); + } + break; + default: + ; + } + } + SvXMLElementExport aElemCell(*this, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True); + SvXMLElementExport aElemText(*this, XML_NAMESPACE_TEXT, XML_P, sal_True, sal_False); + Characters(aStrVal); + + nLastCol = nCol; + bFirstCol = false; + } + nLastRow = nRow; + bFirstRow = false; + } + } + } +} + +// core implementation +void ScXMLExport::WriteConsolidation() +{ + if (pDoc) + { + const ScConsolidateParam* pCons(pDoc->GetConsolidateDlgData()); + if( pCons ) + { + OUString sStrData; + + ScXMLConverter::GetStringFromFunction( sStrData, pCons->eFunction ); + AddAttribute( XML_NAMESPACE_TABLE, XML_FUNCTION, sStrData ); + + sStrData = OUString(); + for( sal_Int32 nIndex = 0; nIndex < pCons->nDataAreaCount; ++nIndex ) + ScRangeStringConverter::GetStringFromArea( sStrData, *pCons->ppDataAreas[ nIndex ], pDoc, FormulaGrammar::CONV_OOO, sal_True ); + AddAttribute( XML_NAMESPACE_TABLE, XML_SOURCE_CELL_RANGE_ADDRESSES, sStrData ); + + ScRangeStringConverter::GetStringFromAddress( sStrData, ScAddress( pCons->nCol, pCons->nRow, pCons->nTab ), pDoc, FormulaGrammar::CONV_OOO ); + AddAttribute( XML_NAMESPACE_TABLE, XML_TARGET_CELL_ADDRESS, sStrData ); + + if( pCons->bByCol && !pCons->bByRow ) + AddAttribute( XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_COLUMN ); + else if( !pCons->bByCol && pCons->bByRow ) + AddAttribute( XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_ROW ); + else if( pCons->bByCol && pCons->bByRow ) + AddAttribute( XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_BOTH ); + + if( pCons->bReferenceData ) + AddAttribute( XML_NAMESPACE_TABLE, XML_LINK_TO_SOURCE_DATA, XML_TRUE ); + + SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_CONSOLIDATION, sal_True, sal_True ); + } + } +} + +SvXMLAutoStylePoolP* ScXMLExport::CreateAutoStylePool() +{ + return new ScXMLAutoStylePoolP(*this); +} + +XMLPageExport* ScXMLExport::CreatePageExport() +{ + return new XMLTableMasterPageExport( *this ); +} + +void ScXMLExport::GetChangeTrackViewSettings(uno::Sequence<beans::PropertyValue>& rProps) +{ + ScChangeViewSettings* pViewSettings(GetDocument() ? GetDocument()->GetChangeViewSettings() : NULL); + if (pViewSettings) + { + sal_Int32 nChangePos(rProps.getLength()); + rProps.realloc(nChangePos + 1); + beans::PropertyValue* pProps(rProps.getArray()); + if (pProps) + { + uno::Sequence<beans::PropertyValue> aChangeProps(SC_VIEWCHANGES_COUNT); + beans::PropertyValue* pChangeProps(aChangeProps.getArray()); + if (pChangeProps) + { + pChangeProps[SC_SHOW_CHANGES].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChanges")); + pChangeProps[SC_SHOW_CHANGES].Value <<= pViewSettings->ShowChanges(); + pChangeProps[SC_SHOW_ACCEPTED_CHANGES].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowAcceptedChanges")); + pChangeProps[SC_SHOW_ACCEPTED_CHANGES].Value <<= pViewSettings->IsShowAccepted(); + pChangeProps[SC_SHOW_REJECTED_CHANGES].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowRejectedChanges")); + pChangeProps[SC_SHOW_REJECTED_CHANGES].Value <<= pViewSettings->IsShowRejected(); + pChangeProps[SC_SHOW_CHANGES_BY_DATETIME].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByDatetime")); + pChangeProps[SC_SHOW_CHANGES_BY_DATETIME].Value <<= pViewSettings->HasDate(); + pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_MODE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByDatetimeMode")); + pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_MODE].Value <<= static_cast<sal_Int16>(pViewSettings->GetTheDateMode()); + util::DateTime aDateTime; + ScXMLConverter::ConvertCoreToAPIDateTime(pViewSettings->GetTheFirstDateTime(), aDateTime); + pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByDatetimeFirstDatetime")); + pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME].Value <<= aDateTime; + ScXMLConverter::ConvertCoreToAPIDateTime(pViewSettings->GetTheLastDateTime(), aDateTime); + pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByDatetimeSecondDatetime")); + pChangeProps[SC_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME].Value <<= aDateTime; + pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByAuthor")); + pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR].Value <<= pViewSettings->HasAuthor(); + pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR_NAME].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByAuthorName")); + pChangeProps[SC_SHOW_CHANGES_BY_AUTHOR_NAME].Value <<= rtl::OUString (pViewSettings->GetTheAuthorToShow()); + pChangeProps[SC_SHOW_CHANGES_BY_COMMENT].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByComment")); + pChangeProps[SC_SHOW_CHANGES_BY_COMMENT].Value <<= pViewSettings->HasComment(); + pChangeProps[SC_SHOW_CHANGES_BY_COMMENT_TEXT].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByCommentText")); + pChangeProps[SC_SHOW_CHANGES_BY_COMMENT_TEXT].Value <<= rtl::OUString (pViewSettings->GetTheComment()); + pChangeProps[SC_SHOW_CHANGES_BY_RANGES].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByRanges")); + pChangeProps[SC_SHOW_CHANGES_BY_RANGES].Value <<= pViewSettings->HasRange(); + rtl::OUString sRangeList; + ScRangeStringConverter::GetStringFromRangeList(sRangeList, &(pViewSettings->GetTheRangeList()), GetDocument(), FormulaGrammar::CONV_OOO); + pChangeProps[SC_SHOW_CHANGES_BY_RANGES_LIST].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowChangesByRangesList")); + pChangeProps[SC_SHOW_CHANGES_BY_RANGES_LIST].Value <<= sRangeList; + + pProps[nChangePos].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TrackedChangesViewSettings")); + pProps[nChangePos].Value <<= aChangeProps; + } + } + } +} + +void ScXMLExport::GetViewSettings(uno::Sequence<beans::PropertyValue>& rProps) +{ + rProps.realloc(4); + beans::PropertyValue* pProps(rProps.getArray()); + if(pProps) + { + if (GetModel().is()) + { + ScModelObj* pDocObj(ScModelObj::getImplementation( GetModel() )); + if (pDocObj) + { + SfxObjectShell* pEmbeddedObj = pDocObj->GetEmbeddedObject(); + if (pEmbeddedObj) + { + Rectangle aRect(pEmbeddedObj->GetVisArea()); + sal_uInt16 i(0); + pProps[i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VisibleAreaTop")); + pProps[i].Value <<= static_cast<sal_Int32>(aRect.getY()); + pProps[++i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VisibleAreaLeft")); + pProps[i].Value <<= static_cast<sal_Int32>(aRect.getX()); + pProps[++i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VisibleAreaWidth")); + pProps[i].Value <<= static_cast<sal_Int32>(aRect.getWidth()); + pProps[++i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VisibleAreaHeight")); + pProps[i].Value <<= static_cast<sal_Int32>(aRect.getHeight()); + } + } + } + } + GetChangeTrackViewSettings(rProps); +} + + + + +void ScXMLExport::GetConfigurationSettings(uno::Sequence<beans::PropertyValue>& rProps) +{ + if (GetModel().is()) + { + uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY); + if (xMultiServiceFactory.is()) + { + uno::Reference <beans::XPropertySet> xProperties(xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.SpreadsheetSettings"))), uno::UNO_QUERY); + if (xProperties.is()) + SvXMLUnitConverter::convertPropertySet(rProps, xProperties); + + sal_Int32 nPropsToAdd = 0; + rtl::OUStringBuffer aTrackedChangesKey; + if (GetDocument() && GetDocument()->GetChangeTrack() && GetDocument()->GetChangeTrack()->IsProtected()) + { + SvXMLUnitConverter::encodeBase64(aTrackedChangesKey, GetDocument()->GetChangeTrack()->GetProtection()); + if (aTrackedChangesKey.getLength()) + ++nPropsToAdd; + } + + bool bVBACompat = false; + uno::Reference <container::XNameAccess> xCodeNameAccess; + DBG_ASSERT( pDoc, "ScXMLExport::GetConfigurationSettings - no ScDocument!" ); + if( pDoc && pDoc->IsInVBAMode() ) + { + // VBA compatibility mode + bVBACompat = true; + ++nPropsToAdd; + // code names + xCodeNameAccess = new XMLCodeNameProvider( pDoc ); + if( xCodeNameAccess->hasElements() ) + ++nPropsToAdd; + else + xCodeNameAccess.clear(); + } + + if( nPropsToAdd > 0 ) + { + sal_Int32 nCount(rProps.getLength()); + rProps.realloc(nCount + nPropsToAdd); + if (aTrackedChangesKey.getLength()) + { + rProps[nCount].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TrackedChangesProtectionKey")); + rProps[nCount].Value <<= aTrackedChangesKey.makeStringAndClear(); + ++nCount; + } + if( bVBACompat ) + { + rProps[nCount].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VBACompatibilityMode")); + rProps[nCount].Value <<= bVBACompat; + ++nCount; + } + if( xCodeNameAccess.is() ) + { + rProps[nCount].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScriptConfiguration")); + rProps[nCount].Value <<= xCodeNameAccess; + ++nCount; + } + } + } + } +} + +XMLShapeExport* ScXMLExport::CreateShapeExport() +{ + return new ScXMLShapeExport(*this); +} + +void ScXMLExport::CreateSharedData(const sal_Int32 nTableCount) +{ + pSharedData = new ScMySharedData(nTableCount); +} + +XMLNumberFormatAttributesExportHelper* ScXMLExport::GetNumberFormatAttributesExportHelper() +{ + if (!pNumberFormatAttributesExportHelper) + pNumberFormatAttributesExportHelper = new XMLNumberFormatAttributesExportHelper(GetNumberFormatsSupplier(), *this ); + return pNumberFormatAttributesExportHelper; +} + +void ScXMLExport::CollectUserDefinedNamespaces(const SfxItemPool* pPool, sal_uInt16 nAttrib) +{ + const SfxPoolItem* pItem; + sal_uInt32 nItems(pPool->GetItemCount2( nAttrib )); + for( sal_uInt32 i = 0; i < nItems; ++i ) + { + if( 0 != (pItem = pPool->GetItem2( nAttrib, i ) ) ) + { + const SvXMLAttrContainerItem *pUnknown((const SvXMLAttrContainerItem *)pItem); + if( (pUnknown->GetAttrCount() > 0) ) + { + sal_uInt16 nIdx(pUnknown->GetFirstNamespaceIndex()); + while( USHRT_MAX != nIdx ) + { + if( (XML_NAMESPACE_UNKNOWN_FLAG & nIdx) != 0 ) + { + const OUString& rPrefix = pUnknown->GetPrefix( nIdx ); + // Add namespace declaration for unknown attributes if + // there aren't existing ones for the prefix used by the + // attibutes + _GetNamespaceMap().Add( rPrefix, + pUnknown->GetNamespace( nIdx ), + XML_NAMESPACE_UNKNOWN ); + } + nIdx = pUnknown->GetNextNamespaceIndex( nIdx ); + } + } + } + } + + // #i66550# needed for 'presentation:event-listener' element for URLs in shapes + _GetNamespaceMap().Add( + GetXMLToken( XML_NP_PRESENTATION ), + GetXMLToken( XML_N_PRESENTATION ), + XML_NAMESPACE_PRESENTATION ); +} + +void ScXMLExport::IncrementProgressBar(sal_Bool bEditCell, sal_Int32 nInc) +{ + nProgressCount += nInc; + if (bEditCell || nProgressCount > 100) + { + GetProgressBarHelper()->Increment(nProgressCount); + nProgressCount = 0; + } +} + +sal_uInt32 ScXMLExport::exportDoc( enum XMLTokenEnum eClass ) +{ + if( (getExportFlags() & (EXPORT_FONTDECLS|EXPORT_STYLES| + EXPORT_MASTERSTYLES|EXPORT_CONTENT)) != 0 ) + { + if (GetDocument()) + { + CollectUserDefinedNamespaces(GetDocument()->GetPool(), ATTR_USERDEF); + CollectUserDefinedNamespaces(GetDocument()->GetEditPool(), EE_PARA_XMLATTRIBS); + CollectUserDefinedNamespaces(GetDocument()->GetEditPool(), EE_CHAR_XMLATTRIBS); + ScDrawLayer* pDrawLayer = GetDocument()->GetDrawLayer(); + if (pDrawLayer) + { + CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), EE_PARA_XMLATTRIBS); + CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), EE_CHAR_XMLATTRIBS); + CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), SDRATTR_XMLATTRIBUTES); + } + + // sheet events use officeooo namespace + if( (getExportFlags() & EXPORT_CONTENT) != 0 && + getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST ) + { + bool bAnySheetEvents = false; + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab=0; nTab<nTabCount; ++nTab) + if (pDoc->GetSheetEvents(nTab)) + bAnySheetEvents = true; + if (bAnySheetEvents) + _GetNamespaceMap().Add( + GetXMLToken( XML_NP_OFFICE_EXT ), + GetXMLToken( XML_N_OFFICE_EXT ), + XML_NAMESPACE_OFFICE_EXT ); + } + } + } + return SvXMLExport::exportDoc( eClass ); +} + +// XExporter +void SAL_CALL ScXMLExport::setSourceDocument( const uno::Reference<lang::XComponent>& xComponent ) + throw(lang::IllegalArgumentException, uno::RuntimeException) +{ + ScUnoGuard aGuard; + SvXMLExport::setSourceDocument( xComponent ); + + pDoc = ScXMLConverter::GetScDocument( GetModel() ); + DBG_ASSERT( pDoc, "ScXMLExport::setSourceDocument - no ScDocument!" ); + if (!pDoc) + throw lang::IllegalArgumentException(); + + // create ScChangeTrackingExportHelper after document is known + pChangeTrackingExportHelper = new ScChangeTrackingExportHelper(*this); + + // Set the document's storage grammar corresponding to the ODF version that + // is to be written. + SvtSaveOptions::ODFDefaultVersion meODFDefaultVersion = getDefaultVersion(); + switch (meODFDefaultVersion) + { + // ODF 1.0 and 1.1 use GRAM_PODF, everything later or unspecified GRAM_ODFF + case SvtSaveOptions::ODFVER_010: + case SvtSaveOptions::ODFVER_011: + pDoc->SetStorageGrammar( formula::FormulaGrammar::GRAM_PODF); + break; + default: + pDoc->SetStorageGrammar( formula::FormulaGrammar::GRAM_ODFF); + } +} + +// XFilter +sal_Bool SAL_CALL ScXMLExport::filter( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor ) + throw(::com::sun::star::uno::RuntimeException) +{ + ScUnoGuard aGuard; + if (pDoc) + pDoc->DisableIdle(sal_True); + sal_Bool bReturn(SvXMLExport::filter(aDescriptor)); + if (pDoc) + pDoc->DisableIdle(sal_False); + return bReturn; +} + +void SAL_CALL ScXMLExport::cancel() + throw(::com::sun::star::uno::RuntimeException) +{ + ScUnoGuard aGuard; + if (pDoc) + pDoc->DisableIdle(sal_False); + SvXMLExport::cancel(); +} + +// XInitialization +void SAL_CALL ScXMLExport::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + ScUnoGuard aGuard; + SvXMLExport::initialize(aArguments); +} + +// XServiceInfo +::rtl::OUString SAL_CALL ScXMLExport::getImplementationName( ) + throw(::com::sun::star::uno::RuntimeException) +{ + ScUnoGuard aGuard; + + sal_uInt16 nFlags = getExportFlags(); + if (nFlags & EXPORT_OASIS) + { + nFlags |= EXPORT_OASIS; + switch( nFlags ) + { + case EXPORT_ALL: + return ScXMLOasisExport_getImplementationName(); + case (EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS): + return ScXMLOasisExport_Styles_getImplementationName(); + case (EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS): + return ScXMLOasisExport_Content_getImplementationName(); + case EXPORT_META: + return ScXMLOasisExport_Meta_getImplementationName(); + case EXPORT_SETTINGS: + return ScXMLOasisExport_Settings_getImplementationName(); + default: + // generic name for 'unknown' cases + return ScXMLOasisExport_getImplementationName(); + } + } + else + { + switch( nFlags ) + { + case EXPORT_ALL: + return ScXMLOOoExport_getImplementationName(); + case (EXPORT_STYLES|EXPORT_MASTERSTYLES|EXPORT_AUTOSTYLES|EXPORT_FONTDECLS): + return ScXMLOOoExport_Styles_getImplementationName(); + case (EXPORT_AUTOSTYLES|EXPORT_CONTENT|EXPORT_SCRIPTS|EXPORT_FONTDECLS): + return ScXMLOOoExport_Content_getImplementationName(); + case EXPORT_META: + return ScXMLOOoExport_Meta_getImplementationName(); + case EXPORT_SETTINGS: + return ScXMLOOoExport_Settings_getImplementationName(); + default: + // generic name for 'unknown' cases + return ScXMLOOoExport_getImplementationName(); + } + } + return SvXMLExport::getImplementationName(); +} + +sal_Bool SAL_CALL ScXMLExport::supportsService( const ::rtl::OUString& ServiceName ) + throw(::com::sun::star::uno::RuntimeException) +{ + ScUnoGuard aGuard; + return SvXMLExport::supportsService( ServiceName ); +} + +::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL ScXMLExport::getSupportedServiceNames( ) + throw(::com::sun::star::uno::RuntimeException) +{ + ScUnoGuard aGuard; + return SvXMLExport::getSupportedServiceNames(); +} + +// XUnoTunnel +sal_Int64 SAL_CALL ScXMLExport::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) + throw(::com::sun::star::uno::RuntimeException) +{ + ScUnoGuard aGuard; + return SvXMLExport::getSomething(aIdentifier); +} + +void ScXMLExport::DisposingModel() +{ + SvXMLExport::DisposingModel(); + pDoc = NULL; + xCurrentTable = 0; +} + diff --git a/sc/source/filter/xml/xmlexprt.hxx b/sc/source/filter/xml/xmlexprt.hxx new file mode 100644 index 000000000000..e024fc6a0de0 --- /dev/null +++ b/sc/source/filter/xml/xmlexprt.hxx @@ -0,0 +1,293 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef SC_XMLEXPRT_HXX +#define SC_XMLEXPRT_HXX + +#include <xmloff/xmlexp.hxx> +#include <com/sun/star/sheet/XSpreadsheet.hpp> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include <com/sun/star/table/CellRangeAddress.hpp> +#include <com/sun/star/table/CellAddress.hpp> +#include <com/sun/star/drawing/XShapes.hpp> +#include <com/sun/star/table/XCellRange.hpp> + +namespace com { namespace sun { namespace star { + namespace beans { class XPropertySet; } +} } } + +#include <hash_map> + +class ScOutlineArray; +class SvXMLExportPropertyMapper; +class ScMyShapesContainer; +class ScMyMergedRangesContainer; +class ScMyValidationsContainer; +class ScMyNotEmptyCellsIterator; +class ScChangeTrackingExportHelper; +class ScColumnStyles; +class ScRowStyles; +class ScFormatRangeStyles; +class ScRowFormatRanges; +class ScMyOpenCloseColumnRowGroup; +class ScMyAreaLinksContainer; +class ScMyDetectiveOpContainer; +struct ScMyCell; +class ScDocument; +class ScMySharedData; +class ScMyDefaultStyles; +class XMLNumberFormatAttributesExportHelper; +class ScChartListener; +class SfxItemPool; +class ScAddress; +class ScBaseCell; + +typedef std::vector< com::sun::star::uno::Reference < com::sun::star::drawing::XShapes > > ScMyXShapesVec; + +class ScXMLExport : public SvXMLExport +{ + ScDocument* pDoc; + com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheet> xCurrentTable; + com::sun::star::uno::Reference <com::sun::star::table::XCellRange> xCurrentTableCellRange; + + com::sun::star::uno::Reference<com::sun::star::io::XInputStream> xSourceStream; + sal_Int32 nSourceStreamPos; + + UniReference < XMLPropertyHandlerFactory > xScPropHdlFactory; + UniReference < XMLPropertySetMapper > xCellStylesPropertySetMapper; + UniReference < XMLPropertySetMapper > xColumnStylesPropertySetMapper; + UniReference < XMLPropertySetMapper > xRowStylesPropertySetMapper; + UniReference < XMLPropertySetMapper > xTableStylesPropertySetMapper; + UniReference < SvXMLExportPropertyMapper > xCellStylesExportPropertySetMapper; + UniReference < SvXMLExportPropertyMapper > xColumnStylesExportPropertySetMapper; + UniReference < SvXMLExportPropertyMapper > xRowStylesExportPropertySetMapper; + UniReference < SvXMLExportPropertyMapper > xTableStylesExportPropertySetMapper; + XMLNumberFormatAttributesExportHelper* pNumberFormatAttributesExportHelper; + typedef ::std::hash_map<sal_Int32, sal_Int32> NumberFormatIndexMap; + NumberFormatIndexMap aNumFmtIndexMap; + ScMySharedData* pSharedData; + ScColumnStyles* pColumnStyles; + ScRowStyles* pRowStyles; + ScFormatRangeStyles* pCellStyles; + ScRowFormatRanges* pRowFormatRanges; + std::vector<rtl::OUString> aTableStyles; + com::sun::star::table::CellRangeAddress aRowHeaderRange; + ScMyOpenCloseColumnRowGroup* pGroupColumns; + ScMyOpenCloseColumnRowGroup* pGroupRows; + ScMyDefaultStyles* pDefaults; + ScChartListener* pChartListener; + const ScMyCell* pCurrentCell; + + ScMyMergedRangesContainer* pMergedRangesContainer; + ScMyValidationsContainer* pValidationsContainer; + ScMyNotEmptyCellsIterator* pCellsItr; + ScChangeTrackingExportHelper* pChangeTrackingExportHelper; + const rtl::OUString sLayerID; + const rtl::OUString sCaptionShape; + rtl::OUString sExternalRefTabStyleName; + rtl::OUString sAttrName; + rtl::OUString sAttrStyleName; + rtl::OUString sAttrColumnsRepeated; + rtl::OUString sAttrFormula; + rtl::OUString sAttrValueType; + rtl::OUString sAttrStringValue; + rtl::OUString sElemCell; + rtl::OUString sElemCoveredCell; + rtl::OUString sElemCol; + rtl::OUString sElemRow; + rtl::OUString sElemTab; + rtl::OUString sElemP; + sal_Int32 nOpenRow; + sal_Int32 nProgressCount; + sal_uInt16 nCurrentTable; + sal_Bool bHasRowHeader; + sal_Bool bRowHeaderOpen; + sal_Bool mbShowProgress; + + sal_Int32 GetNumberFormatStyleIndex(sal_Int32 nNumFmt) const; + sal_Bool HasDrawPages(com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xDoc); + void CollectSharedData(sal_Int32& nTableCount, sal_Int32& nShapesCount, const sal_Int32 nCellCount); + void CollectShapesAutoStyles(const sal_Int32 nTableCount); + void WriteTablesView(const com::sun::star::uno::Any& aTableView); + void WriteView(const com::sun::star::uno::Any& aView); + virtual void _ExportFontDecls(); + virtual void _ExportStyles( sal_Bool bUsed ); + virtual void _ExportAutoStyles(); + virtual void _ExportMasterStyles(); + virtual void SetBodyAttributes(); + virtual void _ExportContent(); + virtual void _ExportMeta(); + + void CollectInternalShape( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape ); + + com::sun::star::table::CellRangeAddress GetEndAddress(const com::sun::star::uno::Reference<com::sun::star::sheet::XSpreadsheet>& xTable, + const sal_Int32 nTable); +// ScMyEmptyDatabaseRangesContainer GetEmptyDatabaseRanges(); + void GetAreaLinks( com::sun::star::uno::Reference< com::sun::star::sheet::XSpreadsheetDocument>& xSpreadDoc, ScMyAreaLinksContainer& rAreaLinks ); + void GetDetectiveOpList( ScMyDetectiveOpContainer& rDetOp ); + void WriteSingleColumn(const sal_Int32 nRepeatColumns, const sal_Int32 nStyleIndex, + const sal_Int32 nIndex, const sal_Bool bIsAutoStyle, const sal_Bool bIsVisible); + void WriteColumn(const sal_Int32 nColumn, const sal_Int32 nRepeatColumns, + const sal_Int32 nStyleIndex, const sal_Bool bIsVisible); + void OpenHeaderColumn(); + void CloseHeaderColumn(); + void ExportColumns(const sal_Int32 nTable, const com::sun::star::table::CellRangeAddress& aColumnHeaderRange, const sal_Bool bHasColumnHeader); + void ExportExternalRefCacheStyles(); + void ExportFormatRanges(const sal_Int32 nStartCol, const sal_Int32 nStartRow, + const sal_Int32 nEndCol, const sal_Int32 nEndRow, const sal_Int32 nSheet); + void WriteRowContent(); + void WriteRowStartTag(sal_Int32 nRow, const sal_Int32 nIndex, const sal_Int8 nFlag, const sal_Int32 nEmptyRows); + void OpenHeaderRows(); + void CloseHeaderRows(); + void OpenNewRow(const sal_Int32 nIndex, const sal_Int8 nFlag, const sal_Int32 nStartRow, const sal_Int32 nEmptyRows); + void OpenAndCloseRow(const sal_Int32 nIndex, const sal_Int8 nFlag, + const sal_Int32 nStartRow, const sal_Int32 nEmptyRows); + void OpenRow(const sal_Int32 nTable, const sal_Int32 nStartRow, const sal_Int32 nRepeatRow); + void CloseRow(const sal_Int32 nRow); + void GetColumnRowHeader(sal_Bool& bHasColumnHeader, com::sun::star::table::CellRangeAddress& aColumnHeaderRange, + sal_Bool& bHasRowHeader, com::sun::star::table::CellRangeAddress& aRowHeaderRange, + rtl::OUString& rPrintRanges) const; + void FillFieldGroup(ScOutlineArray* pFields, ScMyOpenCloseColumnRowGroup* pGroups); + void FillColumnRowGroups(); + +//UNUSED2008-05 sal_Bool GetMerge (const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheet>& xTable, +//UNUSED2008-05 sal_Int32 nCol, sal_Int32 nRow, +//UNUSED2008-05 com::sun::star::table::CellRangeAddress& aCellAddress); + + sal_Bool GetMerged (const com::sun::star::table::CellRangeAddress* pCellRange, + const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheet>& xTable); + + sal_Bool GetCellText (ScMyCell& rMyCell, const ScAddress& aPos) const; + + void WriteCell (ScMyCell& aCell); + void WriteAreaLink(const ScMyCell& rMyCell); + void WriteAnnotation(ScMyCell& rMyCell); + void WriteDetective(const ScMyCell& rMyCell); + void ExportShape(const com::sun::star::uno::Reference < com::sun::star::drawing::XShape >& xShape, com::sun::star::awt::Point* pPoint); + void WriteShapes(const ScMyCell& rMyCell); + void WriteTableShapes(); + void SetRepeatAttribute (const sal_Int32 nEqualCellCount); + + sal_Bool IsCellTypeEqual (const ScMyCell& aCell1, const ScMyCell& aCell2) const; + sal_Bool IsEditCell(const com::sun::star::table::CellAddress& aAddress, ScMyCell* pMyCell = NULL) const; +//UNUSED2008-05 sal_Bool IsEditCell(const com::sun::star::uno::Reference <com::sun::star::table::XCell>& xCell) const; + sal_Bool IsEditCell(ScMyCell& rCell) const; + sal_Bool IsMultiLineFormulaCell(ScMyCell& rCell) const; +//UNUSED2008-05 sal_Bool IsAnnotationEqual(const com::sun::star::uno::Reference<com::sun::star::table::XCell>& xCell1, +//UNUSED2008-05 const com::sun::star::uno::Reference<com::sun::star::table::XCell>& xCell2); + sal_Bool IsCellEqual (ScMyCell& aCell1, ScMyCell& aCell2); + + void WriteCalculationSettings(const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xSpreadDoc); + void WriteTableSource(); + void WriteScenario(); // core implementation + void WriteTheLabelRanges(const com::sun::star::uno::Reference< com::sun::star::sheet::XSpreadsheetDocument >& xSpreadDoc); + void WriteLabelRanges( const com::sun::star::uno::Reference< com::sun::star::container::XIndexAccess >& xRangesIAccess, sal_Bool bColumn ); + void WriteNamedExpressions(const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheetDocument>& xSpreadDoc); + void WriteExternalRefCaches(); + void WriteConsolidation(); // core implementation + + void CollectUserDefinedNamespaces(const SfxItemPool* pPool, sal_uInt16 nAttrib); + + void AddStyleFromCells( + const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xProperties, + const com::sun::star::uno::Reference< com::sun::star::sheet::XSpreadsheet >& xTable, + sal_Int32 nTable, const rtl::OUString* pOldName ); + void AddStyleFromColumn( + const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xColumnProperties, + const rtl::OUString* pOldName, sal_Int32& rIndex, sal_Bool& rIsVisible ); + void AddStyleFromRow( + const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xRowProperties, + const rtl::OUString* pOldName, sal_Int32& rIndex ); + + void IncrementProgressBar(sal_Bool bEditCell, sal_Int32 nInc = 1); + + void CopySourceStream( sal_Int32 nStartOffset, sal_Int32 nEndOffset, sal_Int32& rNewStart, sal_Int32& rNewEnd ); + +protected: + virtual SvXMLAutoStylePoolP* CreateAutoStylePool(); + virtual XMLPageExport* CreatePageExport(); + virtual XMLShapeExport* CreateShapeExport(); + virtual XMLFontAutoStylePool* CreateFontAutoStylePool(); +public: + // #110680# + ScXMLExport( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory, + const sal_uInt16 nExportFlag); + + virtual ~ScXMLExport(); + + static sal_Int16 GetFieldUnit(); + inline ScDocument* GetDocument() { return pDoc; } + inline const ScDocument* GetDocument() const { return pDoc; } +//UNUSED2008-05 sal_Bool IsMatrix (const com::sun::star::uno::Reference <com::sun::star::table::XCellRange>& xCellRange, +//UNUSED2008-05 const com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheet>& xTable, +//UNUSED2008-05 const sal_Int32 nCol, const sal_Int32 nRow, +//UNUSED2008-05 com::sun::star::table::CellRangeAddress& aCellAddress, sal_Bool& bIsFirst) const; + sal_Bool IsMatrix (const ScAddress& aCell, + com::sun::star::table::CellRangeAddress& aCellAddress, sal_Bool& bIsFirst) const; + + UniReference < XMLPropertySetMapper > GetCellStylesPropertySetMapper() { return xCellStylesPropertySetMapper; } + UniReference < XMLPropertySetMapper > GetTableStylesPropertySetMapper() { return xTableStylesPropertySetMapper; } + + void SetSourceStream( const com::sun::star::uno::Reference<com::sun::star::io::XInputStream>& xNewStream ); + + void GetChangeTrackViewSettings(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& rProps); + virtual void GetViewSettings(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& rProps); + virtual void GetConfigurationSettings(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& rProps); + + virtual void exportAnnotationMeta( const com::sun::star::uno::Reference < com::sun::star::drawing::XShape >& xShape); + + void CreateSharedData(const sal_Int32 nTableCount); + void SetSharedData(ScMySharedData* pTemp) { pSharedData = pTemp; } + ScMySharedData* GetSharedData() { return pSharedData; } + XMLNumberFormatAttributesExportHelper* GetNumberFormatAttributesExportHelper(); + + // Export the document. + virtual sal_uInt32 exportDoc( enum ::xmloff::token::XMLTokenEnum eClass = ::xmloff::token::XML_TOKEN_INVALID ); + + // XExporter + virtual void SAL_CALL setSourceDocument( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& xDoc ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + + // XFilter + virtual sal_Bool SAL_CALL filter( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL cancel() throw(::com::sun::star::uno::RuntimeException); + + // XInitialization + virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException); + + // XUnoTunnel + virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException); + + virtual void DisposingModel(); +}; + +#endif + diff --git a/sc/source/filter/xml/xmlexternaltabi.cxx b/sc/source/filter/xml/xmlexternaltabi.cxx new file mode 100644 index 000000000000..fb33b5e9a450 --- /dev/null +++ b/sc/source/filter/xml/xmlexternaltabi.cxx @@ -0,0 +1,437 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- + +#include "xmlexternaltabi.hxx" +#include "xmlimprt.hxx" +#include "xmltabi.hxx" +#include "xmlstyli.hxx" + +#include "token.hxx" +#include "document.hxx" + +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmluconv.hxx> +#include <com/sun/star/util/NumberFormat.hpp> + +using namespace ::com::sun::star; + +using ::rtl::OUString; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::xml::sax::XAttributeList; + +// ============================================================================ + +ScXMLExternalRefTabSourceContext::ScXMLExternalRefTabSourceContext( + ScXMLImport& rImport, sal_uInt16 nPrefix, const OUString& rLName, + const Reference<XAttributeList>& xAttrList, ScXMLExternalTabData& rRefInfo ) : + SvXMLImportContext( rImport, nPrefix, rLName ), + mrScImport(rImport), + mrExternalRefInfo(rRefInfo) +{ + using namespace ::xmloff::token; + + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + for (sal_Int16 i = 0; i < nAttrCount; ++i) + { + const rtl::OUString& sAttrName = xAttrList->getNameByIndex(i); + rtl::OUString aLocalName; + sal_uInt16 nAttrPrefix = mrScImport.GetNamespaceMap().GetKeyByAttrName(sAttrName, &aLocalName); + const rtl::OUString& sValue = xAttrList->getValueByIndex(i); + if (nAttrPrefix == XML_NAMESPACE_XLINK) + { + if (IsXMLToken(aLocalName, XML_HREF)) + maRelativeUrl = sValue; + } + else if (nAttrPrefix == XML_NAMESPACE_TABLE) + { + if (IsXMLToken(aLocalName, XML_TABLE_NAME)) + maTableName = sValue; + else if (IsXMLToken(aLocalName, XML_FILTER_NAME)) + maFilterName = sValue; + else if (IsXMLToken(aLocalName, XML_FILTER_OPTIONS)) + maFilterOptions = sValue; + } + } +} + +ScXMLExternalRefTabSourceContext::~ScXMLExternalRefTabSourceContext() +{ +} + +SvXMLImportContext* ScXMLExternalRefTabSourceContext::CreateChildContext( + sal_uInt16 nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& /*xAttrList*/ ) +{ + return new SvXMLImportContext(GetImport(), nPrefix, rLocalName); +} + +/** + * Make sure the URL is a valid relative URL, mainly to avoid storing + * absolute URL as relative URL by accident. For now, we only check the first + * three characters which are assumed to be always '../', because the relative + * URL for an external document is always in reference to the content.xml + * fragment of the original document. + */ +static bool lcl_isValidRelativeURL(const OUString& rUrl) +{ + sal_Int32 n = ::std::min( rUrl.getLength(), static_cast<sal_Int32>(3)); + if (n < 3) + return false; + const sal_Unicode* p = rUrl.getStr(); + for (sal_Int32 i = 0; i < n; ++i) + { + sal_Unicode c = p[i]; + if (i < 2 && c != '.') + // the path must begin with '..' + return false; + else if (i == 2 && c != '/') + // a '/' path separator must follow + return false; + } + return true; +} + +void ScXMLExternalRefTabSourceContext::EndElement() +{ + ScDocument* pDoc = mrScImport.GetDocument(); + if (!pDoc) + return; + + ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager(); + if (lcl_isValidRelativeURL(maRelativeUrl)) + pRefMgr->setRelativeFileName(mrExternalRefInfo.mnFileId, maRelativeUrl); + pRefMgr->setFilterData(mrExternalRefInfo.mnFileId, maFilterName, maFilterOptions); +} + +// ============================================================================ + +ScXMLExternalRefRowsContext::ScXMLExternalRefRowsContext( + ScXMLImport& rImport, sal_uInt16 nPrefix, const OUString& rLName, + const Reference<XAttributeList>& /* xAttrList */, ScXMLExternalTabData& rRefInfo ) : + SvXMLImportContext( rImport, nPrefix, rLName ), + mrScImport(rImport), + mrExternalRefInfo(rRefInfo) +{ +} + +ScXMLExternalRefRowsContext::~ScXMLExternalRefRowsContext() +{ +} + +SvXMLImportContext* ScXMLExternalRefRowsContext::CreateChildContext( + sal_uInt16 nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& xAttrList ) +{ + // #i101319# row elements inside group, rows or header-rows + // are treated like row elements directly in the table element + + const SvXMLTokenMap& rTokenMap = mrScImport.GetTableRowsElemTokenMap(); + sal_uInt16 nToken = rTokenMap.Get(nPrefix, rLocalName); + switch (nToken) + { + case XML_TOK_TABLE_ROWS_ROW_GROUP: + case XML_TOK_TABLE_ROWS_HEADER_ROWS: + case XML_TOK_TABLE_ROWS_ROWS: + return new ScXMLExternalRefRowsContext( + mrScImport, nPrefix, rLocalName, xAttrList, mrExternalRefInfo); + case XML_TOK_TABLE_ROWS_ROW: + return new ScXMLExternalRefRowContext( + mrScImport, nPrefix, rLocalName, xAttrList, mrExternalRefInfo); + default: + ; + } + return new SvXMLImportContext(GetImport(), nPrefix, rLocalName); +} + +void ScXMLExternalRefRowsContext::EndElement() +{ +} + +// ============================================================================ + +ScXMLExternalRefRowContext::ScXMLExternalRefRowContext( + ScXMLImport& rImport, sal_uInt16 nPrefix, const OUString& rLName, + const Reference<XAttributeList>& xAttrList, ScXMLExternalTabData& rRefInfo ) : + SvXMLImportContext( rImport, nPrefix, rLName ), + mrScImport(rImport), + mrExternalRefInfo(rRefInfo), + mnRepeatRowCount(1) +{ + mrExternalRefInfo.mnCol = 0; + + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + const SvXMLTokenMap& rAttrTokenMap = mrScImport.GetTableRowAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName = xAttrList->getNameByIndex(i); + rtl::OUString aLocalName; + sal_uInt16 nAttrPrefix = mrScImport.GetNamespaceMap().GetKeyByAttrName(sAttrName, &aLocalName); + const rtl::OUString& sValue = xAttrList->getValueByIndex(i); + + switch (rAttrTokenMap.Get(nAttrPrefix, aLocalName)) + { + case XML_TOK_TABLE_ROW_ATTR_REPEATED: + { + mnRepeatRowCount = std::max(sValue.toInt32(), static_cast<sal_Int32>(1)); + } + break; + } + } +} + +ScXMLExternalRefRowContext::~ScXMLExternalRefRowContext() +{ +} + +SvXMLImportContext* ScXMLExternalRefRowContext::CreateChildContext( + sal_uInt16 nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& xAttrList ) +{ + const SvXMLTokenMap& rTokenMap = mrScImport.GetTableRowElemTokenMap(); + sal_uInt16 nToken = rTokenMap.Get(nPrefix, rLocalName); + if (nToken == XML_TOK_TABLE_ROW_CELL || nToken == XML_TOK_TABLE_ROW_COVERED_CELL) + return new ScXMLExternalRefCellContext(mrScImport, nPrefix, rLocalName, xAttrList, mrExternalRefInfo); + + return new SvXMLImportContext(GetImport(), nPrefix, rLocalName); +} + +void ScXMLExternalRefRowContext::EndElement() +{ + ScExternalRefCache::TableTypeRef pTab = mrExternalRefInfo.mpCacheTable; + + for (sal_Int32 i = 1; i < mnRepeatRowCount; ++i) + { + // Performance: duplicates of a non-existent row will still not exist. + // Don't find that out for every cell. + // External references often are a sparse matrix. + if (i == 1 && !pTab->hasRow( mrExternalRefInfo.mnRow)) + { + mrExternalRefInfo.mnRow += mnRepeatRowCount; + return; + } + + for (sal_Int32 j = 0; j < mrExternalRefInfo.mnCol; ++j) + { + ScExternalRefCache::TokenRef pToken = pTab->getCell( + static_cast<SCCOL>(j), static_cast<SCROW>(mrExternalRefInfo.mnRow)); + + if (pToken.get()) + { + pTab->setCell(static_cast<SCCOL>(j), + static_cast<SCROW>(mrExternalRefInfo.mnRow+i), pToken); + } + } + } + mrExternalRefInfo.mnRow += mnRepeatRowCount; +} + +// ============================================================================ + +ScXMLExternalRefCellContext::ScXMLExternalRefCellContext( + ScXMLImport& rImport, sal_uInt16 nPrefix, const OUString& rLName, + const Reference<XAttributeList>& xAttrList, ScXMLExternalTabData& rRefInfo ) : + SvXMLImportContext( rImport, nPrefix, rLName ), + mrScImport(rImport), + mrExternalRefInfo(rRefInfo), + mfCellValue(0.0), + mnRepeatCount(1), + mnNumberFormat(-1), + mnCellType(::com::sun::star::util::NumberFormat::UNDEFINED), + mbIsNumeric(false), + mbIsEmpty(true) +{ + using namespace ::xmloff::token; + + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rTokenMap = rImport.GetTableRowCellAttrTokenMap(); + for (sal_Int16 i = 0; i < nAttrCount; ++i) + { + OUString aLocalName; + sal_uInt16 nAttrPrefix = rImport.GetNamespaceMap().GetKeyByAttrName( + xAttrList->getNameByIndex(i), &aLocalName); + + const rtl::OUString& sValue = xAttrList->getValueByIndex(i); + sal_uInt16 nToken = rTokenMap.Get(nAttrPrefix, aLocalName); + + switch (nToken) + { + case XML_TOK_TABLE_ROW_CELL_ATTR_STYLE_NAME: + { + XMLTableStylesContext* pStyles = static_cast<XMLTableStylesContext*>(mrScImport.GetAutoStyles()); + const XMLTableStyleContext* pStyle = static_cast<const XMLTableStyleContext*>( + pStyles->FindStyleChildContext(XML_STYLE_FAMILY_TABLE_CELL, sValue, true)); + if (pStyle) + mnNumberFormat = const_cast<XMLTableStyleContext*>(pStyle)->GetNumberFormat(); + } + break; + case XML_TOK_TABLE_ROW_CELL_ATTR_REPEATED: + { + mnRepeatCount = ::std::max(sValue.toInt32(), static_cast<sal_Int32>(1)); + } + break; + case XML_TOK_TABLE_ROW_CELL_ATTR_VALUE_TYPE: + { + mnCellType = mrScImport.GetCellType(sValue); + } + break; + case XML_TOK_TABLE_ROW_CELL_ATTR_VALUE: + { + if (sValue.getLength()) + { + mrScImport.GetMM100UnitConverter().convertDouble(mfCellValue, sValue); + mbIsNumeric = true; + mbIsEmpty = false; + } + } + break; + case XML_TOK_TABLE_ROW_CELL_ATTR_DATE_VALUE: + { + if (sValue.getLength() && mrScImport.SetNullDateOnUnitConverter()) + { + mrScImport.GetMM100UnitConverter().convertDateTime(mfCellValue, sValue); + mbIsNumeric = true; + mbIsEmpty = false; + } + } + break; + case XML_TOK_TABLE_ROW_CELL_ATTR_TIME_VALUE: + { + if (sValue.getLength()) + { + mrScImport.GetMM100UnitConverter().convertTime(mfCellValue, sValue); + mbIsNumeric = true; + mbIsEmpty = false; + } + } + break; + case XML_TOK_TABLE_ROW_CELL_ATTR_STRING_VALUE: + { + if (sValue.getLength()) + { + maCellString = sValue; + mbIsNumeric = false; + mbIsEmpty = false; + } + } + break; + case XML_TOK_TABLE_ROW_CELL_ATTR_BOOLEAN_VALUE: + { + if (sValue.getLength()) + { + mfCellValue = IsXMLToken(sValue, XML_TRUE) ? 1.0 : 0.0; + mbIsNumeric = true; + mbIsEmpty = false; + } + } + break; + default: + ; + } + } +} + +ScXMLExternalRefCellContext::~ScXMLExternalRefCellContext() +{ +} + +SvXMLImportContext* ScXMLExternalRefCellContext::CreateChildContext( + sal_uInt16 nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& xAttrList ) +{ + const SvXMLTokenMap& rTokenMap = mrScImport.GetTableRowCellElemTokenMap(); + sal_uInt16 nToken = rTokenMap.Get(nPrefix, rLocalName); + if (nToken == XML_TOK_TABLE_ROW_CELL_P) + return new ScXMLExternalRefCellTextContext(mrScImport, nPrefix, rLocalName, xAttrList, *this); + + return new SvXMLImportContext(GetImport(), nPrefix, rLocalName); +} + +void ScXMLExternalRefCellContext::EndElement() +{ + if (maCellString.getLength()) + mbIsEmpty = false; + + for (sal_Int32 i = 0; i < mnRepeatCount; ++i, ++mrExternalRefInfo.mnCol) + { + if (mbIsEmpty) + continue; + + ScExternalRefCache::TokenRef aToken; + if (mbIsNumeric) + aToken.reset(new formula::FormulaDoubleToken(mfCellValue)); + else + aToken.reset(new formula::FormulaStringToken(maCellString)); + + sal_uInt32 nNumFmt = mnNumberFormat >= 0 ? static_cast<sal_uInt32>(mnNumberFormat) : 0; + mrExternalRefInfo.mpCacheTable->setCell( + static_cast<SCCOL>(mrExternalRefInfo.mnCol), + static_cast<SCROW>(mrExternalRefInfo.mnRow), + aToken, nNumFmt); + } +} + +void ScXMLExternalRefCellContext::SetCellString(const OUString& rStr) +{ + maCellString = rStr; +} + +// ============================================================================ + +ScXMLExternalRefCellTextContext::ScXMLExternalRefCellTextContext( + ScXMLImport& rImport, sal_uInt16 nPrefix, const OUString& rLName, + const Reference<XAttributeList>& /*xAttrList*/, + ScXMLExternalRefCellContext& rParent ) : + SvXMLImportContext( rImport, nPrefix, rLName ), + mrScImport(rImport), + mrParent(rParent) +{ +} + +ScXMLExternalRefCellTextContext::~ScXMLExternalRefCellTextContext() +{ +} + +SvXMLImportContext* ScXMLExternalRefCellTextContext::CreateChildContext( + sal_uInt16 nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& /*xAttrList*/ ) +{ + return new SvXMLImportContext(GetImport(), nPrefix, rLocalName); +} + +void ScXMLExternalRefCellTextContext::Characters(const OUString& rChar) +{ + maCellStrBuf.append(rChar); +} + +void ScXMLExternalRefCellTextContext::EndElement() +{ + mrParent.SetCellString(maCellStrBuf.makeStringAndClear()); +} diff --git a/sc/source/filter/xml/xmlexternaltabi.hxx b/sc/source/filter/xml/xmlexternaltabi.hxx new file mode 100644 index 000000000000..8382e681c439 --- /dev/null +++ b/sc/source/filter/xml/xmlexternaltabi.hxx @@ -0,0 +1,176 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLEXTERNALTABI_HXX +#define SC_XMLEXTERNALTABI_HXX + +#include <xmloff/xmlictxt.hxx> +#include "rtl/ustrbuf.hxx" + +class ScXMLImport; +struct ScXMLExternalTabData; + +class ScXMLExternalRefTabSourceContext : public SvXMLImportContext +{ +public: + ScXMLExternalRefTabSourceContext( ScXMLImport& rImport, sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLExternalTabData& rRefInfo ); + + virtual ~ScXMLExternalRefTabSourceContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +private: + ScXMLImport& mrScImport; + ScXMLExternalTabData& mrExternalRefInfo; + + ::rtl::OUString maRelativeUrl; + ::rtl::OUString maTableName; + ::rtl::OUString maFilterName; + ::rtl::OUString maFilterOptions; +}; + +// ============================================================================ + +class ScXMLExternalRefRowsContext : public SvXMLImportContext +{ +public: + ScXMLExternalRefRowsContext( ScXMLImport& rImport, sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLExternalTabData& rRefInfo ); + + virtual ~ScXMLExternalRefRowsContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +private: + ScXMLImport& mrScImport; + ScXMLExternalTabData& mrExternalRefInfo; +}; + +// ============================================================================ + +class ScXMLExternalRefRowContext : public SvXMLImportContext +{ +public: + ScXMLExternalRefRowContext( ScXMLImport& rImport, sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLExternalTabData& rRefInfo ); + + virtual ~ScXMLExternalRefRowContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +private: + ScXMLImport& mrScImport; + ScXMLExternalTabData& mrExternalRefInfo; + sal_Int32 mnRepeatRowCount; +}; + +// ============================================================================ + +class ScXMLExternalRefCellContext : public SvXMLImportContext +{ +public: + ScXMLExternalRefCellContext( ScXMLImport& rImport, sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLExternalTabData& rRefInfo ); + + virtual ~ScXMLExternalRefCellContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); + + void SetCellString(const ::rtl::OUString& rStr); + +private: + ScXMLImport& mrScImport; + ScXMLExternalTabData& mrExternalRefInfo; + ::rtl::OUString maCellString; + double mfCellValue; + sal_Int32 mnRepeatCount; + sal_Int32 mnNumberFormat; + sal_Int16 mnCellType; + bool mbIsNumeric; + bool mbIsEmpty; +}; + +// ============================================================================ + +class ScXMLExternalRefCellTextContext : public SvXMLImportContext +{ +public: + ScXMLExternalRefCellTextContext( ScXMLImport& rImport, sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLExternalRefCellContext& rParent ); + + virtual ~ScXMLExternalRefCellTextContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void Characters(const ::rtl::OUString& rChar); + + virtual void EndElement(); + +private: + ScXMLImport& mrScImport; + ScXMLExternalRefCellContext& mrParent; + + ::rtl::OUStringBuffer maCellStrBuf; +}; + +#endif diff --git a/sc/source/filter/xml/xmlfilti.cxx b/sc/source/filter/xml/xmlfilti.cxx new file mode 100644 index 000000000000..760a21a8c106 --- /dev/null +++ b/sc/source/filter/xml/xmlfilti.cxx @@ -0,0 +1,785 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + +// INCLUDE --------------------------------------------------------------- + +#include "xmlfilti.hxx" +#include "xmlimprt.hxx" +#include "docuno.hxx" +#include "convuno.hxx" +#include "XMLConverter.hxx" +#include "rangeutl.hxx" + +#include <xmloff/xmltkmap.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmltoken.hxx> + +using namespace com::sun::star; +using namespace xmloff::token; + +//------------------------------------------------------------------ + +ScXMLFilterContext::ScXMLFilterContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDatabaseRangeContext(pTempDatabaseRangeContext), + aFilterFields(), + bSkipDuplicates(sal_False), + bCopyOutputData(sal_False), + bUseRegularExpressions(sal_False), + bConnectionOr(sal_True), + bNextConnectionOr(sal_True), + bConditionSourceRange(sal_False) +{ + ScDocument* pDoc(GetScImport().GetDocument()); + + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetFilterAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_FILTER_ATTR_TARGET_RANGE_ADDRESS : + { + ScRange aScRange; + sal_Int32 nOffset(0); + if (ScRangeStringConverter::GetRangeFromString( aScRange, sValue, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset )) + { + ScUnoConversion::FillApiAddress( aOutputPosition, aScRange.aStart ); + bCopyOutputData = sal_True; + } + } + break; + case XML_TOK_FILTER_ATTR_CONDITION_SOURCE_RANGE_ADDRESS : + { + sal_Int32 nOffset(0); + if (ScRangeStringConverter::GetRangeFromString( aConditionSourceRangeAddress, sValue, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset )) + bConditionSourceRange = sal_True; + } + break; + case XML_TOK_FILTER_ATTR_CONDITION_SOURCE : + { + // not supported by StarOffice + } + break; + case XML_TOK_FILTER_ATTR_DISPLAY_DUPLICATES : + { + bSkipDuplicates = !IsXMLToken(sValue, XML_TRUE); + } + break; + } + } +} + +ScXMLFilterContext::~ScXMLFilterContext() +{ +} + +SvXMLImportContext *ScXMLFilterContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap()); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_FILTER_AND: + { + pContext = new ScXMLAndContext( GetScImport(), nPrefix, + rLName, xAttrList, this); + } + break; + case XML_TOK_FILTER_OR: + { + pContext = new ScXMLOrContext( GetScImport(), nPrefix, + rLName, xAttrList, this); + } + break; + case XML_TOK_FILTER_CONDITION: + { + pContext = new ScXMLConditionContext( GetScImport(), nPrefix, + rLName, xAttrList, this); + } + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLFilterContext::EndElement() +{ + pDatabaseRangeContext->SetFilterUseRegularExpressions(bUseRegularExpressions); + if (bCopyOutputData) + { + pDatabaseRangeContext->SetFilterOutputPosition(aOutputPosition); + pDatabaseRangeContext->SetFilterCopyOutputData(bCopyOutputData); + } + else + pDatabaseRangeContext->SetFilterCopyOutputData(sal_False); + pDatabaseRangeContext->SetFilterIsCaseSensitive(bIsCaseSensitive); + pDatabaseRangeContext->SetFilterSkipDuplicates(bSkipDuplicates); + pDatabaseRangeContext->SetFilterFields(aFilterFields); + if (bConditionSourceRange) + pDatabaseRangeContext->SetFilterConditionSourceRangeAddress(aConditionSourceRangeAddress); +} + +ScXMLAndContext::ScXMLAndContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */, + ScXMLFilterContext* pTempFilterContext) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pFilterContext(pTempFilterContext) +{ + pFilterContext->OpenConnection(sal_False); +} + +ScXMLAndContext::~ScXMLAndContext() +{ +} + +SvXMLImportContext *ScXMLAndContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap()); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_FILTER_OR: + { + // not supported in StarOffice + } + break; + case XML_TOK_FILTER_CONDITION: + { + pContext = new ScXMLConditionContext( GetScImport(), nPrefix, + rLName, xAttrList, pFilterContext); + } + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLAndContext::EndElement() +{ + pFilterContext->CloseConnection(); +} + +ScXMLOrContext::ScXMLOrContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */, + ScXMLFilterContext* pTempFilterContext) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pFilterContext(pTempFilterContext) +{ + pFilterContext->OpenConnection(sal_True); +} + +ScXMLOrContext::~ScXMLOrContext() +{ +} + +SvXMLImportContext *ScXMLOrContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap()); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_FILTER_AND: + { + pContext = new ScXMLAndContext( GetScImport(), nPrefix, + rLName, xAttrList, pFilterContext); + } + break; + case XML_TOK_FILTER_CONDITION: + { + pContext = new ScXMLConditionContext( GetScImport(), nPrefix, + rLName, xAttrList, pFilterContext); + } + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLOrContext::EndElement() +{ + pFilterContext->CloseConnection(); +} + +ScXMLConditionContext::ScXMLConditionContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLFilterContext* pTempFilterContext) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pFilterContext(pTempFilterContext), + bIsCaseSensitive(sal_False) +{ + sDataType = GetXMLToken(XML_TEXT); + + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetFilterConditionAttrTokenMap()); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_CONDITION_ATTR_FIELD_NUMBER : + { + nField = sValue.toInt32(); + } + break; + case XML_TOK_CONDITION_ATTR_CASE_SENSITIVE : + { + bIsCaseSensitive = IsXMLToken(sValue, XML_TRUE); + } + break; + case XML_TOK_CONDITION_ATTR_DATA_TYPE : + { + sDataType = sValue; + } + break; + case XML_TOK_CONDITION_ATTR_VALUE : + { + sConditionValue = sValue; + } + break; + case XML_TOK_CONDITION_ATTR_OPERATOR : + { + sOperator = sValue; + } + break; + } + } +} + +ScXMLConditionContext::~ScXMLConditionContext() +{ +} + +SvXMLImportContext *ScXMLConditionContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + return new SvXMLImportContext( GetImport(), nPrefix, rLName ); +} + +void ScXMLConditionContext::getOperatorXML(const rtl::OUString sTempOperator, sal_Int32& aFilterOperator, sal_Bool& bUseRegularExpressions) const +{ + bUseRegularExpressions = sal_False; + if (IsXMLToken(sTempOperator, XML_MATCH)) + { + bUseRegularExpressions = sal_True; + aFilterOperator = sheet::FilterOperator2::EQUAL; + } + else if (IsXMLToken(sTempOperator, XML_NOMATCH)) + { + bUseRegularExpressions = sal_True; + aFilterOperator = sheet::FilterOperator2::NOT_EQUAL; + } + else if (sTempOperator.compareToAscii("=") == 0) + aFilterOperator = sheet::FilterOperator2::EQUAL; + else if (sTempOperator.compareToAscii("!=") == 0) + aFilterOperator = sheet::FilterOperator2::NOT_EQUAL; + else if (IsXMLToken(sTempOperator, XML_BOTTOM_PERCENT)) + aFilterOperator = sheet::FilterOperator2::BOTTOM_PERCENT; + else if (IsXMLToken(sTempOperator, XML_BOTTOM_VALUES)) + aFilterOperator = sheet::FilterOperator2::BOTTOM_VALUES; + else if (IsXMLToken(sTempOperator, XML_EMPTY)) + aFilterOperator = sheet::FilterOperator2::EMPTY; + else if (sTempOperator.compareToAscii(">") == 0) + aFilterOperator = sheet::FilterOperator2::GREATER; + else if (sTempOperator.compareToAscii(">=") == 0) + aFilterOperator = sheet::FilterOperator2::GREATER_EQUAL; + else if (sTempOperator.compareToAscii("<") == 0) + aFilterOperator = sheet::FilterOperator2::LESS; + else if (sTempOperator.compareToAscii("<=") == 0) + aFilterOperator = sheet::FilterOperator2::LESS_EQUAL; + else if (IsXMLToken(sTempOperator, XML_NOEMPTY)) + aFilterOperator = sheet::FilterOperator2::NOT_EMPTY; + else if (IsXMLToken(sTempOperator, XML_TOP_PERCENT)) + aFilterOperator = sheet::FilterOperator2::TOP_PERCENT; + else if (IsXMLToken(sTempOperator, XML_TOP_VALUES)) + aFilterOperator = sheet::FilterOperator2::TOP_VALUES; + else if (IsXMLToken(sTempOperator, XML_CONTAINS)) + aFilterOperator = sheet::FilterOperator2::CONTAINS; + else if (IsXMLToken(sTempOperator, XML_DOES_NOT_CONTAIN)) + aFilterOperator = sheet::FilterOperator2::DOES_NOT_CONTAIN; + else if (IsXMLToken(sTempOperator, XML_BEGINS_WITH)) + aFilterOperator = sheet::FilterOperator2::BEGINS_WITH; + else if (IsXMLToken(sTempOperator, XML_DOES_NOT_BEGIN_WITH)) + aFilterOperator = sheet::FilterOperator2::DOES_NOT_BEGIN_WITH; + else if (IsXMLToken(sTempOperator, XML_ENDS_WITH)) + aFilterOperator = sheet::FilterOperator2::ENDS_WITH; + else if (IsXMLToken(sTempOperator, XML_DOES_NOT_END_WITH)) + aFilterOperator = sheet::FilterOperator2::DOES_NOT_END_WITH; +} + +void ScXMLConditionContext::EndElement() +{ + sheet::TableFilterField2 aFilterField; + if (pFilterContext->GetConnection()) + aFilterField.Connection = sheet::FilterConnection_OR; + else + aFilterField.Connection = sheet::FilterConnection_AND; + pFilterContext->SetIsCaseSensitive(bIsCaseSensitive); + sal_Bool bUseRegularExpressions; + getOperatorXML(sOperator, aFilterField.Operator, bUseRegularExpressions); + pFilterContext->SetUseRegularExpressions(bUseRegularExpressions); + aFilterField.Field = nField; + if (IsXMLToken(sDataType, XML_NUMBER)) + { + aFilterField.NumericValue = sConditionValue.toDouble(); + aFilterField.IsNumeric = sal_True; + } + else + { + aFilterField.StringValue = sConditionValue; + aFilterField.IsNumeric = sal_False; + } + pFilterContext->AddFilterField(aFilterField); +} + +//========================================================================== + +ScXMLDPFilterContext::ScXMLDPFilterContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotTableContext* pTempDataPilotTableContext) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDataPilotTable(pTempDataPilotTableContext), + aFilterFields(), + nFilterFieldCount(0), + bSkipDuplicates(sal_False), + bCopyOutputData(sal_False), + bUseRegularExpressions(sal_False), + bConnectionOr(sal_True), + bNextConnectionOr(sal_True), + bConditionSourceRange(sal_False) +{ + ScDocument* pDoc(GetScImport().GetDocument()); + + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetFilterAttrTokenMap()); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_FILTER_ATTR_TARGET_RANGE_ADDRESS : + { + ScRange aScRange; + sal_Int32 nOffset(0); + if (ScRangeStringConverter::GetRangeFromString( aScRange, sValue, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset )) + { + aOutputPosition = aScRange.aStart; + bCopyOutputData = sal_True; + } + } + break; + case XML_TOK_FILTER_ATTR_CONDITION_SOURCE_RANGE_ADDRESS : + { + sal_Int32 nOffset(0); + if(ScRangeStringConverter::GetRangeFromString( aConditionSourceRangeAddress, sValue, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset )) + bConditionSourceRange = sal_True; + } + break; + case XML_TOK_FILTER_ATTR_CONDITION_SOURCE : + { + // not supported by StarOffice + } + break; + case XML_TOK_FILTER_ATTR_DISPLAY_DUPLICATES : + { + bSkipDuplicates = !IsXMLToken(sValue, XML_TRUE); + } + break; + } + } +} + +ScXMLDPFilterContext::~ScXMLDPFilterContext() +{ +} + +SvXMLImportContext *ScXMLDPFilterContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap()); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_FILTER_AND: + { + pContext = new ScXMLDPAndContext( GetScImport(), nPrefix, + rLName, xAttrList, this); + } + break; + case XML_TOK_FILTER_OR: + { + pContext = new ScXMLDPOrContext( GetScImport(), nPrefix, + rLName, xAttrList, this); + } + break; + case XML_TOK_FILTER_CONDITION: + { + pContext = new ScXMLDPConditionContext( GetScImport(), nPrefix, + rLName, xAttrList, this); + } + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDPFilterContext::EndElement() +{ + aFilterFields.bRegExp = bUseRegularExpressions; + aFilterFields.bCaseSens = bIsCaseSensitive; + aFilterFields.bDuplicate = !bSkipDuplicates; +// pDataPilotTable->SetFilterUseRegularExpressions(bUseRegularExpressions); + if (bCopyOutputData) + { + pDataPilotTable->SetFilterOutputPosition(aOutputPosition); + pDataPilotTable->SetFilterCopyOutputData(bCopyOutputData); + } + else + pDataPilotTable->SetFilterCopyOutputData(sal_False); +// pDataPilotTable->SetFilterIsCaseSensitive(bIsCaseSensitive); +// pDataPilotTable->SetFilterSkipDuplicates(bSkipDuplicates); + pDataPilotTable->SetSourceQueryParam(aFilterFields); + if (bConditionSourceRange) + pDataPilotTable->SetFilterSourceRange(aConditionSourceRangeAddress); +} + +void ScXMLDPFilterContext::AddFilterField (const ScQueryEntry& aFilterField) +{ + aFilterFields.Resize(nFilterFieldCount + 1); + ScQueryEntry& rEntry(aFilterFields.GetEntry(nFilterFieldCount)); + rEntry = aFilterField; + rEntry.bDoQuery = sal_True; + ++nFilterFieldCount; +} + +ScXMLDPAndContext::ScXMLDPAndContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */, + ScXMLDPFilterContext* pTempFilterContext) : + SvXMLImportContext( rImport, nPrfx, rLName ) +{ + pFilterContext = pTempFilterContext; + pFilterContext->OpenConnection(sal_False); +} + +ScXMLDPAndContext::~ScXMLDPAndContext() +{ +} + +SvXMLImportContext *ScXMLDPAndContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap()); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_FILTER_OR: + { + // not supported in StarOffice + } + break; + case XML_TOK_FILTER_CONDITION: + { + pContext = new ScXMLDPConditionContext( GetScImport(), nPrefix, + rLName, xAttrList, pFilterContext); + } + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDPAndContext::EndElement() +{ + pFilterContext->CloseConnection(); +} + +ScXMLDPOrContext::ScXMLDPOrContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */, + ScXMLDPFilterContext* pTempFilterContext) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pFilterContext(pTempFilterContext) +{ + pFilterContext->OpenConnection(sal_True); +} + +ScXMLDPOrContext::~ScXMLDPOrContext() +{ +} + +SvXMLImportContext *ScXMLDPOrContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + const SvXMLTokenMap& rTokenMap(GetScImport().GetFilterElemTokenMap()); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_FILTER_AND: + { + pContext = new ScXMLDPAndContext( GetScImport(), nPrefix, + rLName, xAttrList, pFilterContext); + } + break; + case XML_TOK_FILTER_CONDITION: + { + pContext = new ScXMLDPConditionContext( GetScImport(), nPrefix, + rLName, xAttrList, pFilterContext); + } + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLDPOrContext::EndElement() +{ + pFilterContext->CloseConnection(); +} + +ScXMLDPConditionContext::ScXMLDPConditionContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDPFilterContext* pTempFilterContext) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pFilterContext(pTempFilterContext), + sDataType(GetXMLToken(XML_TEXT)), + bIsCaseSensitive(sal_False) +{ + + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetFilterConditionAttrTokenMap()); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_CONDITION_ATTR_FIELD_NUMBER : + { + nField = sValue.toInt32(); + } + break; + case XML_TOK_CONDITION_ATTR_CASE_SENSITIVE : + { + bIsCaseSensitive = IsXMLToken(sValue, XML_TRUE); + } + break; + case XML_TOK_CONDITION_ATTR_DATA_TYPE : + { + sDataType = sValue; + } + break; + case XML_TOK_CONDITION_ATTR_VALUE : + { + sConditionValue = sValue; + } + break; + case XML_TOK_CONDITION_ATTR_OPERATOR : + { + sOperator = sValue; + } + break; + } + } +} + +ScXMLDPConditionContext::~ScXMLDPConditionContext() +{ +} + +SvXMLImportContext *ScXMLDPConditionContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + return new SvXMLImportContext( GetImport(), nPrefix, rLName ); +} + +void ScXMLDPConditionContext::getOperatorXML(const rtl::OUString sTempOperator, ScQueryOp& aFilterOperator, sal_Bool& bUseRegularExpressions, + double& dVal) const +{ + bUseRegularExpressions = sal_False; + if (IsXMLToken(sTempOperator, XML_MATCH)) + { + bUseRegularExpressions = sal_True; + aFilterOperator = SC_EQUAL; + } + else if (IsXMLToken(sTempOperator, XML_NOMATCH)) + { + bUseRegularExpressions = sal_True; + aFilterOperator = SC_NOT_EQUAL; + } + else if (sTempOperator.compareToAscii("=") == 0) + aFilterOperator = SC_EQUAL; + else if (sTempOperator.compareToAscii("!=") == 0) + aFilterOperator = SC_NOT_EQUAL; + else if (IsXMLToken(sTempOperator, XML_BOTTOM_PERCENT)) + aFilterOperator = SC_BOTPERC; + else if (IsXMLToken(sTempOperator, XML_BOTTOM_VALUES)) + aFilterOperator = SC_BOTVAL; + else if (IsXMLToken(sTempOperator, XML_EMPTY)) + dVal = SC_EMPTYFIELDS; + else if (sTempOperator.compareToAscii(">") == 0) + aFilterOperator = SC_GREATER; + else if (sTempOperator.compareToAscii(">=") == 0) + aFilterOperator = SC_GREATER_EQUAL; + else if (sTempOperator.compareToAscii("<") == 0) + aFilterOperator = SC_LESS; + else if (sTempOperator.compareToAscii("<=") == 0) + aFilterOperator = SC_LESS_EQUAL; + else if (IsXMLToken(sTempOperator, XML_NOEMPTY)) + dVal = SC_NONEMPTYFIELDS; + else if (IsXMLToken(sTempOperator, XML_TOP_PERCENT)) + aFilterOperator = SC_TOPPERC; + else if (IsXMLToken(sTempOperator, XML_TOP_VALUES)) + aFilterOperator = SC_TOPVAL; +} + +void ScXMLDPConditionContext::EndElement() +{ + ScQueryEntry aFilterField; + if (pFilterContext->GetConnection()) + aFilterField.eConnect = SC_OR; + else + aFilterField.eConnect = SC_AND; + pFilterContext->SetIsCaseSensitive(bIsCaseSensitive); + sal_Bool bUseRegularExpressions; + double dVal(0.0); + getOperatorXML(sOperator, aFilterField.eOp, bUseRegularExpressions, dVal); + pFilterContext->SetUseRegularExpressions(bUseRegularExpressions); + aFilterField.nField = nField; + if (IsXMLToken(sDataType, XML_NUMBER)) + { + aFilterField.nVal = sConditionValue.toDouble(); + *aFilterField.pStr = sConditionValue; + aFilterField.bQueryByString = sal_False; + if (dVal != 0.0) + { + aFilterField.nVal = dVal; + *aFilterField.pStr = EMPTY_STRING; + } + } + else + { + aFilterField.pStr = new String(sConditionValue); + aFilterField.bQueryByString = sal_True; + aFilterField.nVal = 0; + } + pFilterContext->AddFilterField(aFilterField); +} + + + diff --git a/sc/source/filter/xml/xmlfilti.hxx b/sc/source/filter/xml/xmlfilti.hxx new file mode 100644 index 000000000000..f00b7b00cfdf --- /dev/null +++ b/sc/source/filter/xml/xmlfilti.hxx @@ -0,0 +1,310 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLFILTI_HXX +#define SC_XMLFILTI_HXX + +#include <xmloff/xmlictxt.hxx> +#include <xmloff/xmlimp.hxx> +#include <com/sun/star/table/CellAddress.hpp> +#include <com/sun/star/table/CellRangeAddress.hpp> +#include <com/sun/star/sheet/FilterOperator.hpp> +#include <com/sun/star/sheet/FilterOperator2.hpp> +#include <com/sun/star/sheet/TableFilterField2.hpp> +#include <tools/stack.hxx> + +#include "xmldrani.hxx" +#include "xmldpimp.hxx" + +class ScXMLImport; + +class ScXMLFilterContext : public SvXMLImportContext +{ + ScXMLDatabaseRangeContext* pDatabaseRangeContext; + + com::sun::star::uno::Sequence <com::sun::star::sheet::TableFilterField2> aFilterFields; + com::sun::star::table::CellAddress aOutputPosition; + com::sun::star::table::CellRangeAddress aConditionSourceRangeAddress; + sal_Int16 nUserListIndex; + sal_Bool bSkipDuplicates; + sal_Bool bCopyOutputData; + sal_Bool bUseRegularExpressions; + sal_Bool bIsCaseSensitive; + sal_Bool bEnabledUserList; + sal_Bool bConnectionOr; + sal_Bool bNextConnectionOr; + sal_Bool bConditionSourceRange; + Stack aConnectionOrStack; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLFilterContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDatabaseRangeContext* pTempDatabaseRangeContext); + + virtual ~ScXMLFilterContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); + + void SetIsCaseSensitive(const sal_Bool bTemp) { bIsCaseSensitive = bTemp; } + void SetUseRegularExpressions(const sal_Bool bTemp) { if (!bUseRegularExpressions) bUseRegularExpressions = bTemp;} + void OpenConnection(const sal_Bool bTemp) { sal_Bool* pTemp = new sal_Bool; *pTemp = bConnectionOr; + bConnectionOr = bNextConnectionOr; bNextConnectionOr = bTemp; + aConnectionOrStack.Push(pTemp);} + void CloseConnection() { sal_Bool* pTemp = static_cast <sal_Bool*> (aConnectionOrStack.Pop()); bConnectionOr = *pTemp; bNextConnectionOr = *pTemp; delete pTemp;} + sal_Bool GetConnection() { sal_Bool bTemp = bConnectionOr; bConnectionOr = bNextConnectionOr; return bTemp; } + void AddFilterField(const com::sun::star::sheet::TableFilterField2 aFilterField) { aFilterFields.realloc(aFilterFields.getLength() + 1); + aFilterFields[aFilterFields.getLength() - 1] = aFilterField; } +}; + +class ScXMLAndContext : public SvXMLImportContext +{ + ScXMLFilterContext* pFilterContext; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLAndContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLFilterContext* pTempFilterContext); + + virtual ~ScXMLAndContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLOrContext : public SvXMLImportContext +{ + ScXMLFilterContext* pFilterContext; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLOrContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLFilterContext* pTempFilterContext); + + virtual ~ScXMLOrContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLConditionContext : public SvXMLImportContext +{ + ScXMLFilterContext* pFilterContext; + + rtl::OUString sDataType; + rtl::OUString sConditionValue; + rtl::OUString sOperator; + sal_Int32 nField; + sal_Bool bIsCaseSensitive; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLConditionContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLFilterContext* pTempFilterContext); + + virtual ~ScXMLConditionContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + void getOperatorXML(const rtl::OUString sTempOperator, sal_Int32& aFilterOperator, sal_Bool& bUseRegularExpressions) const; + virtual void EndElement(); +}; + +// Datapilot (Core) + +class ScXMLDPFilterContext : public SvXMLImportContext +{ + ScXMLDataPilotTableContext* pDataPilotTable; + + ScQueryParam aFilterFields; + ScAddress aOutputPosition; + ScRange aConditionSourceRangeAddress; + sal_uInt8 nFilterFieldCount; + sal_Int16 nUserListIndex; + sal_Bool bSkipDuplicates; + sal_Bool bCopyOutputData; + sal_Bool bUseRegularExpressions; + sal_Bool bIsCaseSensitive; + sal_Bool bEnabledUserList; + sal_Bool bConnectionOr; + sal_Bool bNextConnectionOr; + sal_Bool bConditionSourceRange; + Stack aConnectionOrStack; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDPFilterContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDataPilotTableContext* pTempDataPilotTableContext); + + virtual ~ScXMLDPFilterContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); + + void SetIsCaseSensitive(const sal_Bool bTemp) { bIsCaseSensitive = bTemp; } + void SetUseRegularExpressions(const sal_Bool bTemp) { if (!bUseRegularExpressions) bUseRegularExpressions = bTemp;} + void OpenConnection(const sal_Bool bTemp) { sal_Bool* pTemp = new sal_Bool; *pTemp = bConnectionOr; + bConnectionOr = bNextConnectionOr; bNextConnectionOr = bTemp; + aConnectionOrStack.Push(pTemp);} + void CloseConnection() { sal_Bool* pTemp = static_cast <sal_Bool*> (aConnectionOrStack.Pop()); bConnectionOr = *pTemp; bNextConnectionOr = *pTemp; delete pTemp;} + sal_Bool GetConnection() { sal_Bool bTemp = bConnectionOr; bConnectionOr = bNextConnectionOr; return bTemp; } + void AddFilterField (const ScQueryEntry& aFilterField); +}; + +class ScXMLDPAndContext : public SvXMLImportContext +{ + ScXMLDPFilterContext* pFilterContext; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDPAndContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDPFilterContext* pTempFilterContext); + + virtual ~ScXMLDPAndContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLDPOrContext : public SvXMLImportContext +{ + ScXMLDPFilterContext* pFilterContext; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDPOrContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDPFilterContext* pTempFilterContext); + + virtual ~ScXMLDPOrContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLDPConditionContext : public SvXMLImportContext +{ + ScXMLDPFilterContext* pFilterContext; + + rtl::OUString sDataType; + rtl::OUString sConditionValue; + rtl::OUString sOperator; + sal_Int32 nField; + sal_Bool bIsCaseSensitive; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDPConditionContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDPFilterContext* pTempFilterContext); + + virtual ~ScXMLDPConditionContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + void getOperatorXML(const rtl::OUString sTempOperator, ScQueryOp& aFilterOperator, sal_Bool& bUseRegularExpressions, + double& dVal) const; + virtual void EndElement(); +}; + +#endif diff --git a/sc/source/filter/xml/xmlfonte.cxx b/sc/source/filter/xml/xmlfonte.cxx new file mode 100644 index 000000000000..50fe06e9629c --- /dev/null +++ b/sc/source/filter/xml/xmlfonte.cxx @@ -0,0 +1,152 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" +#ifdef PRECOMPILED +#include "filt_pch.hxx" +#endif + + +#include "scitems.hxx" + +#include <editeng/eeitem.hxx> + + +#include <xmloff/XMLFontAutoStylePool.hxx> +#include <editeng/fontitem.hxx> +#include <editeng/eeitem.hxx> +#include <editeng/editeng.hxx> +#include "document.hxx" +#include "docpool.hxx" +#include "xmlexprt.hxx" +#include "stlpool.hxx" +#include "attrib.hxx" + +class ScXMLFontAutoStylePool_Impl: public XMLFontAutoStylePool +{ + void AddFontItems(sal_uInt16* pWhichIds, sal_uInt8 nIdCount, const SfxItemPool* pItemPool, const sal_Bool bExportDefaults); + public: + + ScXMLFontAutoStylePool_Impl( ScXMLExport& rExport ); + +}; + +void ScXMLFontAutoStylePool_Impl::AddFontItems(sal_uInt16* pWhichIds, sal_uInt8 nIdCount, const SfxItemPool* pItemPool, const sal_Bool bExportDefaults) +{ + const SfxPoolItem* pItem; + for( sal_uInt16 i=0; i < nIdCount; ++i ) + { + sal_uInt16 nWhichId(pWhichIds[i]); + if (bExportDefaults && (0 != (pItem = &pItemPool->GetDefaultItem(nWhichId)))) + { + const SvxFontItem *pFont((const SvxFontItem *)pItem); + Add( pFont->GetFamilyName(), pFont->GetStyleName(), + sal::static_int_cast<sal_Int16>(pFont->GetFamily()), + sal::static_int_cast<sal_Int16>(pFont->GetPitch()), + pFont->GetCharSet() ); + } + sal_uInt32 nItems(pItemPool->GetItemCount2( nWhichId )); + for( sal_uInt32 j = 0; j < nItems; ++j ) + { + if( 0 != (pItem = pItemPool->GetItem2( nWhichId, j ) ) ) + { + const SvxFontItem *pFont((const SvxFontItem *)pItem); + Add( pFont->GetFamilyName(), pFont->GetStyleName(), + sal::static_int_cast<sal_Int16>(pFont->GetFamily()), + sal::static_int_cast<sal_Int16>(pFont->GetPitch()), + pFont->GetCharSet() ); + } + } + } +} + +ScXMLFontAutoStylePool_Impl::ScXMLFontAutoStylePool_Impl( + ScXMLExport& rExportP ) : + XMLFontAutoStylePool( rExportP ) +{ + sal_uInt16 aWhichIds[3] = { ATTR_FONT, ATTR_CJK_FONT, + ATTR_CTL_FONT }; + sal_uInt16 aEditWhichIds[3] = { EE_CHAR_FONTINFO, EE_CHAR_FONTINFO_CJK, + EE_CHAR_FONTINFO_CTL }; + sal_uInt16 aPageWhichIds[4] = { ATTR_PAGE_HEADERLEFT, ATTR_PAGE_FOOTERLEFT, + ATTR_PAGE_HEADERRIGHT, ATTR_PAGE_FOOTERRIGHT }; + + const SfxItemPool* pItemPool(rExportP.GetDocument() ? rExportP.GetDocument()->GetPool() : NULL); + AddFontItems(aWhichIds, 3, pItemPool, sal_True); + const SfxItemPool* pEditPool(rExportP.GetDocument()->GetEditPool()); + AddFontItems(aEditWhichIds, 3, pEditPool, sal_False); + + SfxStyleSheetIterator* pItr(rExportP.GetDocument() ? rExportP.GetDocument()->GetStyleSheetPool()->CreateIterator(SFX_STYLE_FAMILY_PAGE, 0xFFFF) : NULL); + if(pItr) + { + SfxStyleSheetBase* pStyle(pItr->First()); + SfxItemPool* pPageEditPool(EditEngine::CreatePool()); + EditEngine aEditEngine(pPageEditPool); + while (pStyle) + { + const SfxItemPool& rPagePool(pStyle->GetPool().GetPool()); + for (sal_uInt8 j = 0; j < 4; ++j) + { + sal_uInt16 nPageWhichId(aPageWhichIds[j]); + sal_uInt32 nPageHFItems(rPagePool.GetItemCount2(nPageWhichId)); + const ScPageHFItem* pPageItem; + for (sal_uInt32 k = 0; k < nPageHFItems; ++k) + { + if (0 != (pPageItem = static_cast<const ScPageHFItem*>(rPagePool.GetItem2(nPageWhichId, k)))) + { + const EditTextObject* pLeftArea(pPageItem->GetLeftArea()); + if (pLeftArea) + { + aEditEngine.SetText(*pLeftArea); + AddFontItems(aEditWhichIds, 3, pPageEditPool, sal_False); + } + const EditTextObject* pCenterArea(pPageItem->GetCenterArea()); + if (pCenterArea) + { + aEditEngine.SetText(*pCenterArea); + AddFontItems(aEditWhichIds, 3, pPageEditPool, sal_False); + } + const EditTextObject* pRightArea(pPageItem->GetRightArea()); + if (pRightArea) + { + aEditEngine.SetText(*pRightArea); + AddFontItems(aEditWhichIds, 3, pPageEditPool, sal_False); + } + } + } + } + pStyle = pItr->Next(); + } + } +} + + +XMLFontAutoStylePool* ScXMLExport::CreateFontAutoStylePool() +{ + return new ScXMLFontAutoStylePool_Impl( *this ); +} diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx new file mode 100644 index 000000000000..d840c39f5939 --- /dev/null +++ b/sc/source/filter/xml/xmlimprt.cxx @@ -0,0 +1,3038 @@ +/************************************************************************* +* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +// INCLUDE --------------------------------------------------------------- + +#include <svl/zforlist.hxx> + +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/i18nmap.hxx> +#include <xmloff/xmltkmap.hxx> +#include <xmloff/xmlictxt.hxx> +#include <xmloff/xmlmetai.hxx> +#include <sfx2/objsh.hxx> +#include <xmloff/xmlnumfi.hxx> +#include <xmloff/xmlscripti.hxx> +#include <xmloff/XMLFontStylesContext.hxx> +#include <xmloff/DocumentSettingsContext.hxx> +#include <xmloff/xmluconv.hxx> +#include <xmloff/numehelp.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlerror.hxx> + +#include <svl/zforlist.hxx> +#include <svl/zformat.hxx> +#include <svl/languageoptions.hxx> + +#include "xmlimprt.hxx" +#include "document.hxx" +#include "docuno.hxx" +#include "nameuno.hxx" +#include "xmlbodyi.hxx" +#include "xmlstyli.hxx" +#include "unoguard.hxx" +#include "ViewSettingsSequenceDefines.hxx" + +#include "patattr.hxx" + +#include "XMLConverter.hxx" +#include "XMLTableShapeImportHelper.hxx" +#include "XMLChangeTrackingImportHelper.hxx" +#include "chgviset.hxx" +#include "XMLStylesImportHelper.hxx" +#include "sheetdata.hxx" +#include "unonames.hxx" +#include "rangeutl.hxx" +#include "postit.hxx" +#include "formulaparserpool.hxx" +#include <comphelper/extract.hxx> + +#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/sheet/XSheetCellRange.hpp> +#include <com/sun/star/sheet/XCellRangeAddressable.hpp> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include <com/sun/star/util/XMergeable.hpp> +#include <com/sun/star/sheet/CellInsertMode.hpp> +#include <com/sun/star/sheet/XCellRangeMovement.hpp> +#include <com/sun/star/document/XActionLockable.hpp> +#include <com/sun/star/util/NumberFormat.hpp> +#include <com/sun/star/util/XNumberFormatTypes.hpp> +#include <tools/urlobj.hxx> +#include <com/sun/star/sheet/XNamedRanges.hpp> +#include <com/sun/star/sheet/NamedRangeFlag.hpp> +#include <com/sun/star/sheet/XNamedRange.hpp> +#include <com/sun/star/sheet/XLabelRanges.hpp> +#include <com/sun/star/io/XSeekable.hpp> + +#define SC_LOCALE "Locale" +#define SC_STANDARDFORMAT "StandardFormat" +#define SC_CURRENCYSYMBOL "CurrencySymbol" +#define SC_NAMEDRANGES "NamedRanges" +#define SC_REPEAT_COLUMN "repeat-column" +#define SC_REPEAT_ROW "repeat-row" +#define SC_FILTER "filter" +#define SC_PRINT_RANGE "print-range" + +using namespace com::sun::star; +using namespace ::xmloff::token; +using namespace ::formula; +using ::rtl::OUString; + +OUString SAL_CALL ScXMLImport_getImplementationName() throw() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisImporter" ) ); +} + +uno::Sequence< rtl::OUString > SAL_CALL ScXMLImport_getSupportedServiceNames() throw() +{ + const rtl::OUString aServiceName( ScXMLImport_getImplementationName() ); + return uno::Sequence< rtl::OUString > ( &aServiceName, 1 ); +} + +uno::Reference< uno::XInterface > SAL_CALL ScXMLImport_createInstance( + const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception ) +{ + // #110680# + // return (cppu::OWeakObject*)new ScXMLImport(IMPORT_ALL); + return (cppu::OWeakObject*)new ScXMLImport( rSMgr, IMPORT_ALL ); +} + +OUString SAL_CALL ScXMLImport_Meta_getImplementationName() throw() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisMetaImporter" ) ); +} + +uno::Sequence< rtl::OUString > SAL_CALL ScXMLImport_Meta_getSupportedServiceNames() throw() +{ + const rtl::OUString aServiceName( ScXMLImport_Meta_getImplementationName() ); + return uno::Sequence< rtl::OUString > ( &aServiceName, 1 ); +} + +uno::Reference< uno::XInterface > SAL_CALL ScXMLImport_Meta_createInstance( + const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception ) +{ + // #110680# + // return (cppu::OWeakObject*)new ScXMLImport(IMPORT_META); + return (cppu::OWeakObject*)new ScXMLImport( rSMgr, IMPORT_META ); +} + +OUString SAL_CALL ScXMLImport_Styles_getImplementationName() throw() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisStylesImporter" ) ); +} + +uno::Sequence< rtl::OUString > SAL_CALL ScXMLImport_Styles_getSupportedServiceNames() throw() +{ + const rtl::OUString aServiceName( ScXMLImport_Styles_getImplementationName() ); + return uno::Sequence< rtl::OUString > ( &aServiceName, 1 ); +} + +uno::Reference< uno::XInterface > SAL_CALL ScXMLImport_Styles_createInstance( + const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception ) +{ + // #110680# + // return (cppu::OWeakObject*)new ScXMLImport(IMPORT_STYLES|IMPORT_AUTOSTYLES|IMPORT_MASTERSTYLES|IMPORT_FONTDECLS); + return (cppu::OWeakObject*)new ScXMLImport( rSMgr, IMPORT_STYLES|IMPORT_AUTOSTYLES|IMPORT_MASTERSTYLES|IMPORT_FONTDECLS); +} + +OUString SAL_CALL ScXMLImport_Content_getImplementationName() throw() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisContentImporter" ) ); +} + +uno::Sequence< rtl::OUString > SAL_CALL ScXMLImport_Content_getSupportedServiceNames() throw() +{ + const rtl::OUString aServiceName( ScXMLImport_Content_getImplementationName() ); + return uno::Sequence< rtl::OUString > ( &aServiceName, 1 ); +} + +uno::Reference< uno::XInterface > SAL_CALL ScXMLImport_Content_createInstance( + const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception ) +{ + // #110680# + // return (cppu::OWeakObject*)new ScXMLImport(IMPORT_META|IMPORT_STYLES|IMPORT_MASTERSTYLES|IMPORT_AUTOSTYLES|IMPORT_CONTENT|IMPORT_SCRIPTS|IMPORT_SETTINGS|IMPORT_FONTDECLS); + return (cppu::OWeakObject*)new ScXMLImport( rSMgr, IMPORT_AUTOSTYLES|IMPORT_CONTENT|IMPORT_SCRIPTS|IMPORT_FONTDECLS); +} + +OUString SAL_CALL ScXMLImport_Settings_getImplementationName() throw() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.XMLOasisSettingsImporter" ) ); +} + +uno::Sequence< rtl::OUString > SAL_CALL ScXMLImport_Settings_getSupportedServiceNames() throw() +{ + const rtl::OUString aServiceName( ScXMLImport_Settings_getImplementationName() ); + return uno::Sequence< rtl::OUString > ( &aServiceName, 1 ); +} + +uno::Reference< uno::XInterface > SAL_CALL ScXMLImport_Settings_createInstance( + const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception ) +{ + // #110680# + // return (cppu::OWeakObject*)new ScXMLImport(IMPORT_SETTINGS); + return (cppu::OWeakObject*)new ScXMLImport( rSMgr, IMPORT_SETTINGS ); +} + +const SvXMLTokenMap& ScXMLImport::GetTableRowCellAttrTokenMap() +{ + static __FAR_DATA SvXMLTokenMapEntry aTableRowCellAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_STYLE_NAME, XML_TOK_TABLE_ROW_CELL_ATTR_STYLE_NAME }, + { XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION_NAME, XML_TOK_TABLE_ROW_CELL_ATTR_CONTENT_VALIDATION_NAME }, + { XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_SPANNED, XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_ROWS }, + { XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_SPANNED, XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_COLS }, + { XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_COLUMNS_SPANNED, XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_COLS }, + { XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_ROWS_SPANNED, XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_ROWS }, + { XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, XML_TOK_TABLE_ROW_CELL_ATTR_REPEATED }, + { XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_TOK_TABLE_ROW_CELL_ATTR_VALUE_TYPE }, + { XML_NAMESPACE_OFFICE, XML_VALUE, XML_TOK_TABLE_ROW_CELL_ATTR_VALUE }, + { XML_NAMESPACE_OFFICE, XML_DATE_VALUE, XML_TOK_TABLE_ROW_CELL_ATTR_DATE_VALUE }, + { XML_NAMESPACE_OFFICE, XML_TIME_VALUE, XML_TOK_TABLE_ROW_CELL_ATTR_TIME_VALUE }, + { XML_NAMESPACE_OFFICE, XML_STRING_VALUE, XML_TOK_TABLE_ROW_CELL_ATTR_STRING_VALUE }, + { XML_NAMESPACE_OFFICE, XML_BOOLEAN_VALUE, XML_TOK_TABLE_ROW_CELL_ATTR_BOOLEAN_VALUE }, + { XML_NAMESPACE_TABLE, XML_FORMULA, XML_TOK_TABLE_ROW_CELL_ATTR_FORMULA }, + { XML_NAMESPACE_OFFICE, XML_CURRENCY, XML_TOK_TABLE_ROW_CELL_ATTR_CURRENCY }, + XML_TOKEN_MAP_END + }; + + if ( !pTableRowCellAttrTokenMap ) + pTableRowCellAttrTokenMap = new SvXMLTokenMap( aTableRowCellAttrTokenMap ); + return *pTableRowCellAttrTokenMap; +} + +//---------------------------------------------------------------------------- + + + + + + + + + + + + + + + + + + + + + +// NB: virtually inherit so we can multiply inherit properly +// in ScXMLFlatDocContext_Impl +class ScXMLDocContext_Impl : public virtual SvXMLImportContext +{ +protected: + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLDocContext_Impl( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const OUString& rLName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList ); + virtual ~ScXMLDocContext_Impl(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const rtl::OUString& rLocalName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList ); +}; + +ScXMLDocContext_Impl::ScXMLDocContext_Impl( ScXMLImport& rImport, sal_uInt16 nPrfx, + const OUString& rLName, + const uno::Reference<xml::sax::XAttributeList>& /* xAttrList */ ) : +SvXMLImportContext( rImport, nPrfx, rLName ) +{ + +} + +ScXMLDocContext_Impl::~ScXMLDocContext_Impl() +{ +} + +// context for flat file xml format +class ScXMLFlatDocContext_Impl + : public ScXMLDocContext_Impl, public SvXMLMetaDocumentContext +{ +public: + ScXMLFlatDocContext_Impl( ScXMLImport& i_rImport, + sal_uInt16 i_nPrefix, const OUString & i_rLName, + const uno::Reference<xml::sax::XAttributeList>& i_xAttrList, + const uno::Reference<document::XDocumentProperties>& i_xDocProps, + const uno::Reference<xml::sax::XDocumentHandler>& i_xDocBuilder); + + virtual ~ScXMLFlatDocContext_Impl(); + + virtual SvXMLImportContext *CreateChildContext( + sal_uInt16 i_nPrefix, const OUString& i_rLocalName, + const uno::Reference<xml::sax::XAttributeList>& i_xAttrList); +}; + +ScXMLFlatDocContext_Impl::ScXMLFlatDocContext_Impl( ScXMLImport& i_rImport, + sal_uInt16 i_nPrefix, const OUString & i_rLName, + const uno::Reference<xml::sax::XAttributeList>& i_xAttrList, + const uno::Reference<document::XDocumentProperties>& i_xDocProps, + const uno::Reference<xml::sax::XDocumentHandler>& i_xDocBuilder) : +SvXMLImportContext(i_rImport, i_nPrefix, i_rLName), +ScXMLDocContext_Impl(i_rImport, i_nPrefix, i_rLName, i_xAttrList), +SvXMLMetaDocumentContext(i_rImport, i_nPrefix, i_rLName, + i_xDocProps, i_xDocBuilder) +{ +} + +ScXMLFlatDocContext_Impl::~ScXMLFlatDocContext_Impl() { } + + +SvXMLImportContext *ScXMLFlatDocContext_Impl::CreateChildContext( + sal_uInt16 i_nPrefix, const OUString& i_rLocalName, + const uno::Reference<xml::sax::XAttributeList>& i_xAttrList) +{ + // behave like meta base class iff we encounter office:meta + const SvXMLTokenMap& rTokenMap = GetScImport().GetDocElemTokenMap(); + if ( XML_TOK_DOC_META == rTokenMap.Get( i_nPrefix, i_rLocalName ) ) { + return SvXMLMetaDocumentContext::CreateChildContext( + i_nPrefix, i_rLocalName, i_xAttrList ); + } else { + return ScXMLDocContext_Impl::CreateChildContext( + i_nPrefix, i_rLocalName, i_xAttrList ); + } +} + +class ScXMLBodyContext_Impl : public SvXMLImportContext +{ + const ScXMLImport& GetScImport() const + { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLBodyContext_Impl( ScXMLImport& rImport, sal_uInt16 nPrfx, + const OUString& rLName, + const uno::Reference< xml::sax::XAttributeList > & xAttrList ); + virtual ~ScXMLBodyContext_Impl(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const OUString& rLocalName, + const uno::Reference< xml::sax::XAttributeList > & xAttrList ); +}; + +ScXMLBodyContext_Impl::ScXMLBodyContext_Impl( ScXMLImport& rImport, + sal_uInt16 nPrfx, const OUString& rLName, + const uno::Reference< xml::sax::XAttributeList > & /* xAttrList */ ) : +SvXMLImportContext( rImport, nPrfx, rLName ) +{ +} + +ScXMLBodyContext_Impl::~ScXMLBodyContext_Impl() +{ +} + +SvXMLImportContext *ScXMLBodyContext_Impl::CreateChildContext( + sal_uInt16 /* nPrefix */, + const OUString& rLocalName, + const uno::Reference< xml::sax::XAttributeList > & xAttrList ) +{ + return GetScImport().CreateBodyContext( rLocalName, xAttrList ); +} + +SvXMLImportContext *ScXMLDocContext_Impl::CreateChildContext( sal_uInt16 nPrefix, + const rtl::OUString& rLocalName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + const SvXMLTokenMap& rTokenMap(GetScImport().GetDocElemTokenMap()); + switch( rTokenMap.Get( nPrefix, rLocalName ) ) + { + case XML_TOK_DOC_FONTDECLS: + if (GetScImport().getImportFlags() & IMPORT_FONTDECLS) + pContext = GetScImport().CreateFontDeclsContext(nPrefix, rLocalName, xAttrList); + break; + case XML_TOK_DOC_STYLES: + if (GetScImport().getImportFlags() & IMPORT_STYLES) + pContext = GetScImport().CreateStylesContext( rLocalName, xAttrList, sal_False); + break; + case XML_TOK_DOC_AUTOSTYLES: + if (GetScImport().getImportFlags() & IMPORT_AUTOSTYLES) + pContext = GetScImport().CreateStylesContext( rLocalName, xAttrList, sal_True); + break; + case XML_TOK_DOC_MASTERSTYLES: + if (GetScImport().getImportFlags() & IMPORT_MASTERSTYLES) + pContext = new ScXMLMasterStylesContext( GetImport(), nPrefix, rLocalName, + xAttrList ); + break; + case XML_TOK_DOC_META: + DBG_WARNING("XML_TOK_DOC_META: should not have come here, maybe document is invalid?"); + break; + case XML_TOK_DOC_SCRIPTS: + if (GetScImport().getImportFlags() & IMPORT_SCRIPTS) + pContext = GetScImport().CreateScriptContext( rLocalName ); + break; + case XML_TOK_DOC_BODY: + if (GetScImport().getImportFlags() & IMPORT_CONTENT) + pContext = new ScXMLBodyContext_Impl( GetScImport(), nPrefix, + rLocalName, xAttrList ); + break; + case XML_TOK_DOC_SETTINGS: + if (GetScImport().getImportFlags() & IMPORT_SETTINGS) + pContext = new XMLDocumentSettingsContext(GetScImport(), nPrefix, rLocalName, xAttrList ); + break; + } + + if(!pContext) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); + + return pContext; +} + +const SvXMLTokenMap& ScXMLImport::GetDocElemTokenMap() +{ + if( !pDocElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aDocTokenMap[] = + { + { XML_NAMESPACE_OFFICE, XML_FONT_FACE_DECLS, XML_TOK_DOC_FONTDECLS }, + { XML_NAMESPACE_OFFICE, XML_STYLES, XML_TOK_DOC_STYLES }, + { XML_NAMESPACE_OFFICE, XML_AUTOMATIC_STYLES, XML_TOK_DOC_AUTOSTYLES }, + { XML_NAMESPACE_OFFICE, XML_MASTER_STYLES, XML_TOK_DOC_MASTERSTYLES }, + { XML_NAMESPACE_OFFICE, XML_META, XML_TOK_DOC_META }, + { XML_NAMESPACE_OFFICE, XML_SCRIPTS, XML_TOK_DOC_SCRIPTS }, + { XML_NAMESPACE_OFFICE, XML_BODY, XML_TOK_DOC_BODY }, + { XML_NAMESPACE_OFFICE, XML_SETTINGS, XML_TOK_DOC_SETTINGS }, + XML_TOKEN_MAP_END + }; + + pDocElemTokenMap = new SvXMLTokenMap( aDocTokenMap ); + + } // if( !pDocElemTokenMap ) + + return *pDocElemTokenMap; +} + + +const SvXMLTokenMap& ScXMLImport::GetBodyElemTokenMap() +{ + if( !pBodyElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aBodyTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_TRACKED_CHANGES, XML_TOK_BODY_TRACKED_CHANGES }, + { XML_NAMESPACE_TABLE, XML_CALCULATION_SETTINGS, XML_TOK_BODY_CALCULATION_SETTINGS }, + { XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATIONS, XML_TOK_BODY_CONTENT_VALIDATIONS }, + { XML_NAMESPACE_TABLE, XML_LABEL_RANGES, XML_TOK_BODY_LABEL_RANGES }, + { XML_NAMESPACE_TABLE, XML_TABLE, XML_TOK_BODY_TABLE }, + { XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSIONS, XML_TOK_BODY_NAMED_EXPRESSIONS }, + { XML_NAMESPACE_TABLE, XML_DATABASE_RANGES, XML_TOK_BODY_DATABASE_RANGES }, + { XML_NAMESPACE_TABLE, XML_DATABASE_RANGE, XML_TOK_BODY_DATABASE_RANGE }, + { XML_NAMESPACE_TABLE, XML_DATA_PILOT_TABLES, XML_TOK_BODY_DATA_PILOT_TABLES }, + { XML_NAMESPACE_TABLE, XML_CONSOLIDATION, XML_TOK_BODY_CONSOLIDATION }, + { XML_NAMESPACE_TABLE, XML_DDE_LINKS, XML_TOK_BODY_DDE_LINKS }, + XML_TOKEN_MAP_END + }; + + pBodyElemTokenMap = new SvXMLTokenMap( aBodyTokenMap ); + } // if( !pBodyElemTokenMap ) + + return *pBodyElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetContentValidationsElemTokenMap() +{ + if( !pContentValidationsElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aContentValidationsElemTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION, XML_TOK_CONTENT_VALIDATION }, + XML_TOKEN_MAP_END + }; + + pContentValidationsElemTokenMap = new SvXMLTokenMap( aContentValidationsElemTokenMap ); + } // if( !pContentValidationsElemTokenMap ) + + return *pContentValidationsElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetContentValidationElemTokenMap() +{ + if( !pContentValidationElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aContentValidationElemTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_HELP_MESSAGE, XML_TOK_CONTENT_VALIDATION_ELEM_HELP_MESSAGE }, + { XML_NAMESPACE_TABLE, XML_ERROR_MESSAGE, XML_TOK_CONTENT_VALIDATION_ELEM_ERROR_MESSAGE }, + { XML_NAMESPACE_TABLE, XML_ERROR_MACRO, XML_TOK_CONTENT_VALIDATION_ELEM_ERROR_MACRO }, + { XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, XML_TOK_CONTENT_VALIDATION_ELEM_EVENT_LISTENERS }, + XML_TOKEN_MAP_END + }; + + pContentValidationElemTokenMap = new SvXMLTokenMap( aContentValidationElemTokenMap ); + } // if( !pContentValidationElemTokenMap ) + + return *pContentValidationElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetContentValidationAttrTokenMap() +{ + if( !pContentValidationAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aContentValidationAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_CONTENT_VALIDATION_NAME }, + { XML_NAMESPACE_TABLE, XML_CONDITION, XML_TOK_CONTENT_VALIDATION_CONDITION }, + { XML_NAMESPACE_TABLE, XML_BASE_CELL_ADDRESS, XML_TOK_CONTENT_VALIDATION_BASE_CELL_ADDRESS }, + { XML_NAMESPACE_TABLE, XML_ALLOW_EMPTY_CELL, XML_TOK_CONTENT_VALIDATION_ALLOW_EMPTY_CELL }, + { XML_NAMESPACE_TABLE, XML_DISPLAY_LIST, XML_TOK_CONTENT_VALIDATION_DISPLAY_LIST }, + XML_TOKEN_MAP_END + }; + + pContentValidationAttrTokenMap = new SvXMLTokenMap( aContentValidationAttrTokenMap ); + } // if( !pContentValidationAttrTokenMap ) + + return *pContentValidationAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetContentValidationMessageElemTokenMap() +{ + if( !pContentValidationMessageElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aContentValidationMessageElemTokenMap[] = + { + { XML_NAMESPACE_TEXT, XML_P, XML_TOK_P }, + XML_TOKEN_MAP_END + }; + + pContentValidationMessageElemTokenMap = new SvXMLTokenMap( aContentValidationMessageElemTokenMap ); + } // if( !pContentValidationMessageElemTokenMap ) + + return *pContentValidationMessageElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetContentValidationHelpMessageAttrTokenMap() +{ + if( !pContentValidationHelpMessageAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aContentValidationHelpMessageAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_TITLE, XML_TOK_HELP_MESSAGE_ATTR_TITLE }, + { XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TOK_HELP_MESSAGE_ATTR_DISPLAY }, + XML_TOKEN_MAP_END + }; + + pContentValidationHelpMessageAttrTokenMap = new SvXMLTokenMap( aContentValidationHelpMessageAttrTokenMap ); + } // if( !pContentValidationHelpMessageAttrTokenMap ) + + return *pContentValidationHelpMessageAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetContentValidationErrorMessageAttrTokenMap() +{ + if( !pContentValidationErrorMessageAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aContentValidationErrorMessageAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_TITLE, XML_TOK_ERROR_MESSAGE_ATTR_TITLE }, + { XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TOK_ERROR_MESSAGE_ATTR_DISPLAY }, + { XML_NAMESPACE_TABLE, XML_MESSAGE_TYPE, XML_TOK_ERROR_MESSAGE_ATTR_MESSAGE_TYPE }, + XML_TOKEN_MAP_END + }; + + pContentValidationErrorMessageAttrTokenMap = new SvXMLTokenMap( aContentValidationErrorMessageAttrTokenMap ); + } // if( !pContentValidationErrorMessageAttrTokenMap ) + + return *pContentValidationErrorMessageAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetContentValidationErrorMacroAttrTokenMap() +{ + if( !pContentValidationErrorMacroAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aContentValidationErrorMacroAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_ERROR_MACRO_ATTR_NAME }, + { XML_NAMESPACE_TABLE, XML_EXECUTE, XML_TOK_ERROR_MACRO_ATTR_EXECUTE }, + XML_TOKEN_MAP_END + }; + + pContentValidationErrorMacroAttrTokenMap = new SvXMLTokenMap( aContentValidationErrorMacroAttrTokenMap ); + } // if( !pContentValidationErrorMacroAttrTokenMap ) + + return *pContentValidationErrorMacroAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetLabelRangesElemTokenMap() +{ + if( !pLabelRangesElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aLabelRangesElemTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_LABEL_RANGE, XML_TOK_LABEL_RANGE_ELEM }, + XML_TOKEN_MAP_END + }; + + pLabelRangesElemTokenMap = new SvXMLTokenMap( aLabelRangesElemTokenMap ); + } // if( !pLabelRangesElemTokenMap ) + + return *pLabelRangesElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetLabelRangeAttrTokenMap() +{ + if( !pLabelRangeAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aLabelRangeAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_LABEL_CELL_RANGE_ADDRESS, XML_TOK_LABEL_RANGE_ATTR_LABEL_RANGE }, + { XML_NAMESPACE_TABLE, XML_DATA_CELL_RANGE_ADDRESS, XML_TOK_LABEL_RANGE_ATTR_DATA_RANGE }, + { XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_TOK_LABEL_RANGE_ATTR_ORIENTATION }, + XML_TOKEN_MAP_END + }; + + pLabelRangeAttrTokenMap = new SvXMLTokenMap( aLabelRangeAttrTokenMap ); + } // if( !pLabelRangeAttrTokenMap ) + + return *pLabelRangeAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetTableElemTokenMap() +{ + if( !pTableElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aTableTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_TABLE_COLUMN_GROUP, XML_TOK_TABLE_COL_GROUP }, + { XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, XML_TOK_TABLE_HEADER_COLS }, + { XML_NAMESPACE_TABLE, XML_TABLE_COLUMNS, XML_TOK_TABLE_COLS }, + { XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, XML_TOK_TABLE_COL }, + { XML_NAMESPACE_TABLE, XML_TABLE_ROW_GROUP, XML_TOK_TABLE_ROW_GROUP }, + { XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, XML_TOK_TABLE_HEADER_ROWS }, + { XML_NAMESPACE_TABLE, XML_TABLE_ROWS, XML_TOK_TABLE_ROWS }, + { XML_NAMESPACE_TABLE, XML_TABLE_ROW, XML_TOK_TABLE_ROW }, + { XML_NAMESPACE_TABLE, XML_TABLE_SOURCE, XML_TOK_TABLE_SOURCE }, + { XML_NAMESPACE_TABLE, XML_SCENARIO, XML_TOK_TABLE_SCENARIO }, + { XML_NAMESPACE_TABLE, XML_SHAPES, XML_TOK_TABLE_SHAPES }, + { XML_NAMESPACE_OFFICE, XML_FORMS, XML_TOK_TABLE_FORMS }, + { XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, XML_TOK_TABLE_EVENT_LISTENERS }, + { XML_NAMESPACE_OFFICE_EXT, XML_EVENT_LISTENERS, XML_TOK_TABLE_EVENT_LISTENERS_EXT }, + XML_TOKEN_MAP_END + }; + + pTableElemTokenMap = new SvXMLTokenMap( aTableTokenMap ); + } // if( !pTableElemTokenMap ) + + return *pTableElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetTableRowsElemTokenMap() +{ + if( !pTableRowsElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aTableRowsElemTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_TABLE_ROW_GROUP, XML_TOK_TABLE_ROWS_ROW_GROUP }, + { XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS, XML_TOK_TABLE_ROWS_HEADER_ROWS }, + { XML_NAMESPACE_TABLE, XML_TABLE_ROWS, XML_TOK_TABLE_ROWS_ROWS }, + { XML_NAMESPACE_TABLE, XML_TABLE_ROW, XML_TOK_TABLE_ROWS_ROW }, + XML_TOKEN_MAP_END + }; + + pTableRowsElemTokenMap = new SvXMLTokenMap( aTableRowsElemTokenMap ); + } // if( !pTableRowsElemTokenMap ) + + return *pTableRowsElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetTableColsElemTokenMap() +{ + if( !pTableColsElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aTableColsElemTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_TABLE_COLUMN_GROUP, XML_TOK_TABLE_COLS_COL_GROUP }, + { XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS, XML_TOK_TABLE_COLS_HEADER_COLS }, + { XML_NAMESPACE_TABLE, XML_TABLE_COLUMNS, XML_TOK_TABLE_COLS_COLS }, + { XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, XML_TOK_TABLE_COLS_COL }, + XML_TOKEN_MAP_END + }; + + pTableColsElemTokenMap = new SvXMLTokenMap( aTableColsElemTokenMap ); + } // if( !pTableColsElemTokenMap ) + + return *pTableColsElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetTableAttrTokenMap() +{ + if( !pTableAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aTableAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_TABLE_NAME }, + { XML_NAMESPACE_TABLE, XML_STYLE_NAME, XML_TOK_TABLE_STYLE_NAME }, + { XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TOK_TABLE_PROTECTION }, + { XML_NAMESPACE_TABLE, XML_PRINT_RANGES, XML_TOK_TABLE_PRINT_RANGES }, + { XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, XML_TOK_TABLE_PASSWORD }, + { XML_NAMESPACE_TABLE, XML_PRINT, XML_TOK_TABLE_PRINT }, + XML_TOKEN_MAP_END + }; + + pTableAttrTokenMap = new SvXMLTokenMap( aTableAttrTokenMap ); + } // if( !pTableAttrTokenMap ) + + return *pTableAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetTableScenarioAttrTokenMap() +{ + if( !pTableScenarioAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aTableScenarioAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_DISPLAY_BORDER, XML_TOK_TABLE_SCENARIO_ATTR_DISPLAY_BORDER }, + { XML_NAMESPACE_TABLE, XML_BORDER_COLOR, XML_TOK_TABLE_SCENARIO_ATTR_BORDER_COLOR }, + { XML_NAMESPACE_TABLE, XML_COPY_BACK, XML_TOK_TABLE_SCENARIO_ATTR_COPY_BACK }, + { XML_NAMESPACE_TABLE, XML_COPY_STYLES, XML_TOK_TABLE_SCENARIO_ATTR_COPY_STYLES }, + { XML_NAMESPACE_TABLE, XML_COPY_FORMULAS, XML_TOK_TABLE_SCENARIO_ATTR_COPY_FORMULAS }, + { XML_NAMESPACE_TABLE, XML_IS_ACTIVE, XML_TOK_TABLE_SCENARIO_ATTR_IS_ACTIVE }, + { XML_NAMESPACE_TABLE, XML_SCENARIO_RANGES, XML_TOK_TABLE_SCENARIO_ATTR_SCENARIO_RANGES }, + { XML_NAMESPACE_TABLE, XML_COMMENT, XML_TOK_TABLE_SCENARIO_ATTR_COMMENT }, + { XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TOK_TABLE_SCENARIO_ATTR_PROTECTED }, + XML_TOKEN_MAP_END + }; + + pTableScenarioAttrTokenMap = new SvXMLTokenMap( aTableScenarioAttrTokenMap ); + } // if( !pTableScenarioAttrTokenMap ) + + return *pTableScenarioAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetTableColAttrTokenMap() +{ + if( !pTableColAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aTableColAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_STYLE_NAME, XML_TOK_TABLE_COL_ATTR_STYLE_NAME }, + { XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, XML_TOK_TABLE_COL_ATTR_REPEATED }, + { XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_TOK_TABLE_COL_ATTR_VISIBILITY }, + { XML_NAMESPACE_TABLE, XML_DEFAULT_CELL_STYLE_NAME, XML_TOK_TABLE_COL_ATTR_DEFAULT_CELL_STYLE_NAME }, + XML_TOKEN_MAP_END + }; + + pTableColAttrTokenMap = new SvXMLTokenMap( aTableColAttrTokenMap ); + } // if( !pTableColAttrTokenMap ) + + return *pTableColAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetTableRowElemTokenMap() +{ + if( !pTableRowElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aTableRowTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_TABLE_CELL, XML_TOK_TABLE_ROW_CELL }, + { XML_NAMESPACE_TABLE, XML_COVERED_TABLE_CELL, XML_TOK_TABLE_ROW_COVERED_CELL }, + XML_TOKEN_MAP_END + }; + + pTableRowElemTokenMap = new SvXMLTokenMap( aTableRowTokenMap ); + } // if( !pTableRowElemTokenMap ) + + return *pTableRowElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetTableRowAttrTokenMap() +{ + if( !pTableRowAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aTableRowAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_STYLE_NAME, XML_TOK_TABLE_ROW_ATTR_STYLE_NAME }, + { XML_NAMESPACE_TABLE, XML_VISIBILITY, XML_TOK_TABLE_ROW_ATTR_VISIBILITY }, + { XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED, XML_TOK_TABLE_ROW_ATTR_REPEATED }, + { XML_NAMESPACE_TABLE, XML_DEFAULT_CELL_STYLE_NAME, XML_TOK_TABLE_ROW_ATTR_DEFAULT_CELL_STYLE_NAME }, + // { XML_NAMESPACE_TABLE, XML_USE_OPTIMAL_HEIGHT, XML_TOK_TABLE_ROW_ATTR_USE_OPTIMAL_HEIGHT }, + XML_TOKEN_MAP_END + }; + + pTableRowAttrTokenMap = new SvXMLTokenMap( aTableRowAttrTokenMap ); + } // if( !pTableRowAttrTokenMap ) + + return *pTableRowAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetTableRowCellElemTokenMap() +{ + if( !pTableRowCellElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aTableRowCellTokenMap[] = + { + { XML_NAMESPACE_TEXT, XML_P, XML_TOK_TABLE_ROW_CELL_P }, + { XML_NAMESPACE_TABLE, XML_SUB_TABLE, XML_TOK_TABLE_ROW_CELL_TABLE }, + { XML_NAMESPACE_OFFICE, XML_ANNOTATION, XML_TOK_TABLE_ROW_CELL_ANNOTATION }, + { XML_NAMESPACE_TABLE, XML_DETECTIVE, XML_TOK_TABLE_ROW_CELL_DETECTIVE }, + { XML_NAMESPACE_TABLE, XML_CELL_RANGE_SOURCE, XML_TOK_TABLE_ROW_CELL_CELL_RANGE_SOURCE }, + XML_TOKEN_MAP_END + }; + + pTableRowCellElemTokenMap = new SvXMLTokenMap( aTableRowCellTokenMap ); + } // if( !pTableRowCellElemTokenMap ) + + return *pTableRowCellElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetTableAnnotationAttrTokenMap() +{ + if( !pTableAnnotationAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aTableAnnotationAttrTokenMap[] = + { + { XML_NAMESPACE_OFFICE, XML_AUTHOR, XML_TOK_TABLE_ANNOTATION_ATTR_AUTHOR }, + { XML_NAMESPACE_OFFICE, XML_CREATE_DATE, XML_TOK_TABLE_ANNOTATION_ATTR_CREATE_DATE }, + { XML_NAMESPACE_OFFICE, XML_CREATE_DATE_STRING, XML_TOK_TABLE_ANNOTATION_ATTR_CREATE_DATE_STRING }, + { XML_NAMESPACE_OFFICE, XML_DISPLAY, XML_TOK_TABLE_ANNOTATION_ATTR_DISPLAY }, + { XML_NAMESPACE_SVG, XML_X, XML_TOK_TABLE_ANNOTATION_ATTR_X }, + { XML_NAMESPACE_SVG, XML_Y, XML_TOK_TABLE_ANNOTATION_ATTR_Y }, + XML_TOKEN_MAP_END + }; + + pTableAnnotationAttrTokenMap = new SvXMLTokenMap( aTableAnnotationAttrTokenMap ); + } // if( !pTableAnnotationAttrTokenMap ) + + return *pTableAnnotationAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDetectiveElemTokenMap() +{ + if( !pDetectiveElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aDetectiveElemTokenMap[]= + { + { XML_NAMESPACE_TABLE, XML_HIGHLIGHTED_RANGE, XML_TOK_DETECTIVE_ELEM_HIGHLIGHTED }, + { XML_NAMESPACE_TABLE, XML_OPERATION, XML_TOK_DETECTIVE_ELEM_OPERATION }, + XML_TOKEN_MAP_END + }; + + pDetectiveElemTokenMap = new SvXMLTokenMap( aDetectiveElemTokenMap ); + } // if( !pDetectiveElemTokenMap ) + + return *pDetectiveElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDetectiveHighlightedAttrTokenMap() +{ + if( !pDetectiveHighlightedAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aDetectiveHighlightedAttrTokenMap[]= + { + { XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_CELL_RANGE }, + { XML_NAMESPACE_TABLE, XML_DIRECTION, XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_DIRECTION }, + { XML_NAMESPACE_TABLE, XML_CONTAINS_ERROR, XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_CONTAINS_ERROR }, + { XML_NAMESPACE_TABLE, XML_MARKED_INVALID, XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_MARKED_INVALID }, + XML_TOKEN_MAP_END + }; + + pDetectiveHighlightedAttrTokenMap = new SvXMLTokenMap( aDetectiveHighlightedAttrTokenMap ); + } // if( !pDetectiveHighlightedAttrTokenMap ) + + return *pDetectiveHighlightedAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDetectiveOperationAttrTokenMap() +{ + if( !pDetectiveOperationAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aDetectiveOperationAttrTokenMap[]= + { + { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_DETECTIVE_OPERATION_ATTR_NAME }, + { XML_NAMESPACE_TABLE, XML_INDEX, XML_TOK_DETECTIVE_OPERATION_ATTR_INDEX }, + XML_TOKEN_MAP_END + }; + + pDetectiveOperationAttrTokenMap = new SvXMLTokenMap( aDetectiveOperationAttrTokenMap ); + } // if( !pDetectiveOperationAttrTokenMap ) + + return *pDetectiveOperationAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetTableCellRangeSourceAttrTokenMap() +{ + if( !pTableCellRangeSourceAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aTableCellRangeSourceAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_NAME }, + { XML_NAMESPACE_XLINK, XML_HREF, XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_HREF }, + { XML_NAMESPACE_TABLE, XML_FILTER_NAME, XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_FILTER_NAME }, + { XML_NAMESPACE_TABLE, XML_FILTER_OPTIONS, XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_FILTER_OPTIONS }, + { XML_NAMESPACE_TABLE, XML_LAST_COLUMN_SPANNED, XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_LAST_COLUMN }, + { XML_NAMESPACE_TABLE, XML_LAST_ROW_SPANNED, XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_LAST_ROW }, + { XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_REFRESH_DELAY }, + XML_TOKEN_MAP_END + }; + + pTableCellRangeSourceAttrTokenMap = new SvXMLTokenMap( aTableCellRangeSourceAttrTokenMap ); + } // if( !pTableCellRangeSourceAttrTokenMap ) + + return *pTableCellRangeSourceAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetNamedExpressionsElemTokenMap() +{ + if( !pNamedExpressionsElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aNamedExpressionsTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_NAMED_RANGE, XML_TOK_NAMED_EXPRESSIONS_NAMED_RANGE }, + { XML_NAMESPACE_TABLE, XML_NAMED_EXPRESSION, XML_TOK_NAMED_EXPRESSIONS_NAMED_EXPRESSION }, + XML_TOKEN_MAP_END + }; + + pNamedExpressionsElemTokenMap = new SvXMLTokenMap( aNamedExpressionsTokenMap ); + } // if( !pNamedExpressionsElemTokenMap ) + + return *pNamedExpressionsElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetNamedRangeAttrTokenMap() +{ + if( !pNamedRangeAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aNamedRangeAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_NAMED_RANGE_ATTR_NAME }, + { XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, XML_TOK_NAMED_RANGE_ATTR_CELL_RANGE_ADDRESS }, + { XML_NAMESPACE_TABLE, XML_BASE_CELL_ADDRESS, XML_TOK_NAMED_RANGE_ATTR_BASE_CELL_ADDRESS }, + { XML_NAMESPACE_TABLE, XML_RANGE_USABLE_AS, XML_TOK_NAMED_RANGE_ATTR_RANGE_USABLE_AS }, + XML_TOKEN_MAP_END + }; + + pNamedRangeAttrTokenMap = new SvXMLTokenMap( aNamedRangeAttrTokenMap ); + } // if( !pNamedRangeAttrTokenMap ) + + return *pNamedRangeAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetNamedExpressionAttrTokenMap() +{ + if( !pNamedExpressionAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aNamedExpressionAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_NAMED_EXPRESSION_ATTR_NAME }, + { XML_NAMESPACE_TABLE, XML_BASE_CELL_ADDRESS, XML_TOK_NAMED_EXPRESSION_ATTR_BASE_CELL_ADDRESS }, + { XML_NAMESPACE_TABLE, XML_EXPRESSION, XML_TOK_NAMED_EXPRESSION_ATTR_EXPRESSION }, + XML_TOKEN_MAP_END + }; + + pNamedExpressionAttrTokenMap = new SvXMLTokenMap( aNamedExpressionAttrTokenMap ); + } // if( !pNamedExpressionAttrTokenMap ) + + return *pNamedExpressionAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDatabaseRangesElemTokenMap() +{ + if( !pDatabaseRangesElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aDatabaseRangesTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_DATABASE_RANGE, XML_TOK_DATABASE_RANGE }, + XML_TOKEN_MAP_END + }; + + pDatabaseRangesElemTokenMap = new SvXMLTokenMap( aDatabaseRangesTokenMap ); + } // if( !pDatabaseRangesElemTokenMap ) + + return *pDatabaseRangesElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDatabaseRangeElemTokenMap() +{ + if( !pDatabaseRangeElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aDatabaseRangeTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_SQL, XML_TOK_DATABASE_RANGE_SOURCE_SQL }, + { XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_TABLE, XML_TOK_DATABASE_RANGE_SOURCE_TABLE }, + { XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_QUERY, XML_TOK_DATABASE_RANGE_SOURCE_QUERY }, + { XML_NAMESPACE_TABLE, XML_FILTER, XML_TOK_FILTER }, + { XML_NAMESPACE_TABLE, XML_SORT, XML_TOK_SORT }, + { XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULES, XML_TOK_DATABASE_RANGE_SUBTOTAL_RULES }, + XML_TOKEN_MAP_END + }; + + pDatabaseRangeElemTokenMap = new SvXMLTokenMap( aDatabaseRangeTokenMap ); + } // if( !pDatabaseRangeElemTokenMap ) + + return *pDatabaseRangeElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDatabaseRangeAttrTokenMap() +{ + if( !pDatabaseRangeAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aDatabaseRangeAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_DATABASE_RANGE_ATTR_NAME }, + { XML_NAMESPACE_TABLE, XML_IS_SELECTION, XML_TOK_DATABASE_RANGE_ATTR_IS_SELECTION }, + { XML_NAMESPACE_TABLE, XML_ON_UPDATE_KEEP_STYLES, XML_TOK_DATABASE_RANGE_ATTR_ON_UPDATE_KEEP_STYLES }, + { XML_NAMESPACE_TABLE, XML_ON_UPDATE_KEEP_SIZE, XML_TOK_DATABASE_RANGE_ATTR_ON_UPDATE_KEEP_SIZE }, + { XML_NAMESPACE_TABLE, XML_HAS_PERSISTENT_DATA, XML_TOK_DATABASE_RANGE_ATTR_HAS_PERSISTENT_DATA }, + { XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_TOK_DATABASE_RANGE_ATTR_ORIENTATION }, + { XML_NAMESPACE_TABLE, XML_CONTAINS_HEADER, XML_TOK_DATABASE_RANGE_ATTR_CONTAINS_HEADER }, + { XML_NAMESPACE_TABLE, XML_DISPLAY_FILTER_BUTTONS, XML_TOK_DATABASE_RANGE_ATTR_DISPLAY_FILTER_BUTTONS }, + { XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, XML_TOK_DATABASE_RANGE_ATTR_TARGET_RANGE_ADDRESS }, + { XML_NAMESPACE_TABLE, XML_REFRESH_DELAY, XML_TOK_DATABASE_RANGE_ATTR_REFRESH_DELAY }, + XML_TOKEN_MAP_END + }; + + pDatabaseRangeAttrTokenMap = new SvXMLTokenMap( aDatabaseRangeAttrTokenMap ); + } // if( !pDatabaseRangeAttrTokenMap ) + + return *pDatabaseRangeAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDatabaseRangeSourceSQLAttrTokenMap() +{ + if( !pDatabaseRangeSourceSQLAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aDatabaseRangeSourceSQLAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_DATABASE_NAME, XML_TOK_SOURCE_SQL_ATTR_DATABASE_NAME }, + { XML_NAMESPACE_XLINK, XML_HREF, XML_TOK_SOURCE_SQL_ATTR_HREF }, + { XML_NAMESPACE_TABLE, XML_CONNECTION_RESOURCE, XML_TOK_SOURCE_SQL_ATTR_CONNECTION_RESSOURCE}, + { XML_NAMESPACE_TABLE, XML_SQL_STATEMENT, XML_TOK_SOURCE_SQL_ATTR_SQL_STATEMENT }, + { XML_NAMESPACE_TABLE, XML_PARSE_SQL_STATEMENT, XML_TOK_SOURCE_SQL_ATTR_PARSE_SQL_STATEMENT }, + XML_TOKEN_MAP_END + }; + + pDatabaseRangeSourceSQLAttrTokenMap = new SvXMLTokenMap( aDatabaseRangeSourceSQLAttrTokenMap ); + } // if( !pDatabaseRangeSourceSQLAttrTokenMap ) + + return *pDatabaseRangeSourceSQLAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDatabaseRangeSourceTableAttrTokenMap() +{ + if( !pDatabaseRangeSourceTableAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aDatabaseRangeSourceTableAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_DATABASE_NAME, XML_TOK_SOURCE_TABLE_ATTR_DATABASE_NAME }, + { XML_NAMESPACE_XLINK, XML_HREF, XML_TOK_SOURCE_TABLE_ATTR_HREF }, + { XML_NAMESPACE_TABLE, XML_CONNECTION_RESOURCE, XML_TOK_SOURCE_TABLE_ATTR_CONNECTION_RESSOURCE }, + { XML_NAMESPACE_TABLE, XML_TABLE_NAME, XML_TOK_SOURCE_TABLE_ATTR_TABLE_NAME }, + XML_TOKEN_MAP_END + }; + + pDatabaseRangeSourceTableAttrTokenMap = new SvXMLTokenMap( aDatabaseRangeSourceTableAttrTokenMap ); + } // if( !pDatabaseRangeSourceTableAttrTokenMap ) + + return *pDatabaseRangeSourceTableAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDatabaseRangeSourceQueryAttrTokenMap() +{ + if( !pDatabaseRangeSourceQueryAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aDatabaseRangeSourceQueryAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_DATABASE_NAME, XML_TOK_SOURCE_QUERY_ATTR_DATABASE_NAME }, + { XML_NAMESPACE_XLINK, XML_HREF, XML_TOK_SOURCE_QUERY_ATTR_HREF }, + { XML_NAMESPACE_TABLE, XML_CONNECTION_RESOURCE, XML_TOK_SOURCE_QUERY_ATTR_CONNECTION_RESSOURCE }, + { XML_NAMESPACE_TABLE, XML_QUERY_NAME, XML_TOK_SOURCE_QUERY_ATTR_QUERY_NAME }, + XML_TOKEN_MAP_END + }; + + pDatabaseRangeSourceQueryAttrTokenMap = new SvXMLTokenMap( aDatabaseRangeSourceQueryAttrTokenMap ); + } // if( !pDatabaseRangeSourceQueryAttrTokenMap ) + + return *pDatabaseRangeSourceQueryAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetFilterElemTokenMap() +{ + if( !pFilterElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aFilterTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_FILTER_AND, XML_TOK_FILTER_AND }, + { XML_NAMESPACE_TABLE, XML_FILTER_OR, XML_TOK_FILTER_OR }, + { XML_NAMESPACE_TABLE, XML_FILTER_CONDITION, XML_TOK_FILTER_CONDITION }, + XML_TOKEN_MAP_END + }; + + pFilterElemTokenMap = new SvXMLTokenMap( aFilterTokenMap ); + } // if( !pFilterElemTokenMap ) + + return *pFilterElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetFilterAttrTokenMap() +{ + if( !pFilterAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aFilterAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, XML_TOK_FILTER_ATTR_TARGET_RANGE_ADDRESS }, + { XML_NAMESPACE_TABLE, XML_CONDITION_SOURCE_RANGE_ADDRESS, XML_TOK_FILTER_ATTR_CONDITION_SOURCE_RANGE_ADDRESS }, + { XML_NAMESPACE_TABLE, XML_CONDITION_SOURCE, XML_TOK_FILTER_ATTR_CONDITION_SOURCE }, + { XML_NAMESPACE_TABLE, XML_DISPLAY_DUPLICATES, XML_TOK_FILTER_ATTR_DISPLAY_DUPLICATES }, + XML_TOKEN_MAP_END + }; + + pFilterAttrTokenMap = new SvXMLTokenMap( aFilterAttrTokenMap ); + } // if( !pFilterAttrTokenMap ) + + return *pFilterAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetFilterConditionAttrTokenMap() +{ + if( !pFilterConditionAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aFilterConditionAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, XML_TOK_CONDITION_ATTR_FIELD_NUMBER }, + { XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TOK_CONDITION_ATTR_CASE_SENSITIVE }, + { XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_TOK_CONDITION_ATTR_DATA_TYPE }, + { XML_NAMESPACE_TABLE, XML_VALUE, XML_TOK_CONDITION_ATTR_VALUE }, + { XML_NAMESPACE_TABLE, XML_OPERATOR, XML_TOK_CONDITION_ATTR_OPERATOR }, + XML_TOKEN_MAP_END + }; + + pFilterConditionAttrTokenMap = new SvXMLTokenMap( aFilterConditionAttrTokenMap ); + } // if( !pFilterConditionAttrTokenMap ) + + return *pFilterConditionAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetSortElemTokenMap() +{ + if( !pSortElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aSortTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_SORT_BY, XML_TOK_SORT_SORT_BY }, + XML_TOKEN_MAP_END + }; + + pSortElemTokenMap = new SvXMLTokenMap( aSortTokenMap ); + } // if( !pSortElemTokenMap ) + + return *pSortElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetSortAttrTokenMap() +{ + if( !pSortAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aSortAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_BIND_STYLES_TO_CONTENT, XML_TOK_SORT_ATTR_BIND_STYLES_TO_CONTENT }, + { XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, XML_TOK_SORT_ATTR_TARGET_RANGE_ADDRESS }, + { XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TOK_SORT_ATTR_CASE_SENSITIVE }, + { XML_NAMESPACE_TABLE, XML_LANGUAGE, XML_TOK_SORT_ATTR_LANGUAGE }, + { XML_NAMESPACE_TABLE, XML_COUNTRY, XML_TOK_SORT_ATTR_COUNTRY }, + { XML_NAMESPACE_TABLE, XML_ALGORITHM, XML_TOK_SORT_ATTR_ALGORITHM }, + XML_TOKEN_MAP_END + }; + + pSortAttrTokenMap = new SvXMLTokenMap( aSortAttrTokenMap ); + } // if( !pSortAttrTokenMap ) + + return *pSortAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetSortSortByAttrTokenMap() +{ + if( !pSortSortByAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aSortSortByAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, XML_TOK_SORT_BY_ATTR_FIELD_NUMBER }, + { XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_TOK_SORT_BY_ATTR_DATA_TYPE }, + { XML_NAMESPACE_TABLE, XML_ORDER, XML_TOK_SORT_BY_ATTR_ORDER }, + XML_TOKEN_MAP_END + }; + + pSortSortByAttrTokenMap = new SvXMLTokenMap( aSortSortByAttrTokenMap ); + } // if( !pSortSortByAttrTokenMap ) + + return *pSortSortByAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDatabaseRangeSubTotalRulesElemTokenMap() +{ + if( !pDatabaseRangeSubTotalRulesElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aDatabaseRangeSubTotalRulesTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_SORT_GROUPS, XML_TOK_SUBTOTAL_RULES_SORT_GROUPS }, + { XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULE, XML_TOK_SUBTOTAL_RULES_SUBTOTAL_RULE }, + XML_TOKEN_MAP_END + }; + + pDatabaseRangeSubTotalRulesElemTokenMap = new SvXMLTokenMap( aDatabaseRangeSubTotalRulesTokenMap ); + } // if( !pDatabaseRangeSubTotalRulesElemTokenMap ) + + return *pDatabaseRangeSubTotalRulesElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDatabaseRangeSubTotalRulesAttrTokenMap() +{ + if( !pDatabaseRangeSubTotalRulesAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aDatabaseRangeSubTotalRulesAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_BIND_STYLES_TO_CONTENT, XML_TOK_SUBTOTAL_RULES_ATTR_BIND_STYLES_TO_CONTENT }, + { XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TOK_SUBTOTAL_RULES_ATTR_CASE_SENSITIVE }, + { XML_NAMESPACE_TABLE, XML_PAGE_BREAKS_ON_GROUP_CHANGE, XML_TOK_SUBTOTAL_RULES_ATTR_PAGE_BREAKS_ON_GROUP_CHANGE }, + XML_TOKEN_MAP_END + }; + + pDatabaseRangeSubTotalRulesAttrTokenMap = new SvXMLTokenMap( aDatabaseRangeSubTotalRulesAttrTokenMap ); + } // if( !pDatabaseRangeSubTotalRulesAttrTokenMap ) + + return *pDatabaseRangeSubTotalRulesAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetSubTotalRulesSortGroupsAttrTokenMap() +{ + if( !pSubTotalRulesSortGroupsAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aSubTotalRulesSortGroupsAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_TOK_SORT_GROUPS_ATTR_DATA_TYPE }, + { XML_NAMESPACE_TABLE, XML_ORDER, XML_TOK_SORT_GROUPS_ATTR_ORDER }, + XML_TOKEN_MAP_END + }; + + pSubTotalRulesSortGroupsAttrTokenMap = new SvXMLTokenMap( aSubTotalRulesSortGroupsAttrTokenMap ); + } // if( !pSubTotalRulesSortGroupsAttrTokenMap ) + + return *pSubTotalRulesSortGroupsAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetSubTotalRulesSubTotalRuleElemTokenMap() +{ + if( !pSubTotalRulesSubTotalRuleElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aSubTotalRulesSubTotalRuleTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_SUBTOTAL_FIELD, XML_TOK_SUBTOTAL_RULE_SUBTOTAL_FIELD }, + XML_TOKEN_MAP_END + }; + + pSubTotalRulesSubTotalRuleElemTokenMap = new SvXMLTokenMap( aSubTotalRulesSubTotalRuleTokenMap ); + } // if( !pSubTotalRulesSubTotalRuleElemTokenMap ) + + return *pSubTotalRulesSubTotalRuleElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetSubTotalRulesSubTotalRuleAttrTokenMap() +{ + if( !pSubTotalRulesSubTotalRuleAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aSubTotalRulesSubTotalRuleAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_GROUP_BY_FIELD_NUMBER, XML_TOK_SUBTOTAL_RULE_ATTR_GROUP_BY_FIELD_NUMBER }, + XML_TOKEN_MAP_END + }; + + pSubTotalRulesSubTotalRuleAttrTokenMap = new SvXMLTokenMap( aSubTotalRulesSubTotalRuleAttrTokenMap ); + } // if( !pSubTotalRulesSubTotalRuleAttrTokenMap ) + + return *pSubTotalRulesSubTotalRuleAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetSubTotalRuleSubTotalFieldAttrTokenMap() +{ + if( !pSubTotalRuleSubTotalFieldAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aSubTotalRuleSubTotalFieldAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, XML_TOK_SUBTOTAL_FIELD_ATTR_FIELD_NUMBER }, + { XML_NAMESPACE_TABLE, XML_FUNCTION, XML_TOK_SUBTOTAL_FIELD_ATTR_FUNCTION }, + XML_TOKEN_MAP_END + }; + + pSubTotalRuleSubTotalFieldAttrTokenMap = new SvXMLTokenMap( aSubTotalRuleSubTotalFieldAttrTokenMap ); + } // if( !pSubTotalRuleSubTotalFieldAttrTokenMap ) + + return *pSubTotalRuleSubTotalFieldAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDataPilotTablesElemTokenMap() +{ + if( !pDataPilotTablesElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aDataPilotTablesElemTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_DATA_PILOT_TABLE, XML_TOK_DATA_PILOT_TABLE }, + XML_TOKEN_MAP_END + }; + + pDataPilotTablesElemTokenMap = new SvXMLTokenMap( aDataPilotTablesElemTokenMap ); + } // if( !pDataPilotTablesElemTokenMap ) + + return *pDataPilotTablesElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDataPilotTableAttrTokenMap() +{ + if( !pDataPilotTableAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aDataPilotTableAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_DATA_PILOT_TABLE_ATTR_NAME }, + { XML_NAMESPACE_TABLE, XML_APPLICATION_DATA, XML_TOK_DATA_PILOT_TABLE_ATTR_APPLICATION_DATA }, + { XML_NAMESPACE_TABLE, XML_GRAND_TOTAL, XML_TOK_DATA_PILOT_TABLE_ATTR_GRAND_TOTAL }, + { XML_NAMESPACE_TABLE, XML_IGNORE_EMPTY_ROWS, XML_TOK_DATA_PILOT_TABLE_ATTR_IGNORE_EMPTY_ROWS }, + { XML_NAMESPACE_TABLE, XML_IDENTIFY_CATEGORIES, XML_TOK_DATA_PILOT_TABLE_ATTR_IDENTIFY_CATEGORIES }, + { XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS, XML_TOK_DATA_PILOT_TABLE_ATTR_TARGET_RANGE_ADDRESS }, + { XML_NAMESPACE_TABLE, XML_BUTTONS, XML_TOK_DATA_PILOT_TABLE_ATTR_BUTTONS }, + { XML_NAMESPACE_TABLE, XML_SHOW_FILTER_BUTTON, XML_TOK_DATA_PILOT_TABLE_ATTR_SHOW_FILTER_BUTTON }, + { XML_NAMESPACE_TABLE, XML_DRILL_DOWN_ON_DOUBLE_CLICK, XML_TOK_DATA_PILOT_TABLE_ATTR_DRILL_DOWN }, + XML_TOKEN_MAP_END + }; + + pDataPilotTableAttrTokenMap = new SvXMLTokenMap( aDataPilotTableAttrTokenMap ); + } // if( !pDataPilotTableAttrTokenMap ) + + return *pDataPilotTableAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDataPilotTableElemTokenMap() +{ + if( !pDataPilotTableElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aDataPilotTableElemTokenMap[] = + { + { 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 }, + { XML_NAMESPACE_TABLE, XML_DATA_PILOT_FIELD, XML_TOK_DATA_PILOT_TABLE_ELEM_DATA_PILOT_FIELD }, + XML_TOKEN_MAP_END + }; + + pDataPilotTableElemTokenMap = new SvXMLTokenMap( aDataPilotTableElemTokenMap ); + } // if( !pDataPilotTableElemTokenMap ) + + return *pDataPilotTableElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDataPilotTableSourceServiceAttrTokenMap() +{ + if( !pDataPilotTableSourceServiceAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aDataPilotTableSourceServiceAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_SOURCE_SERVICE_ATTR_NAME }, + { XML_NAMESPACE_TABLE, XML_SOURCE_NAME, XML_TOK_SOURCE_SERVICE_ATTR_SOURCE_NAME }, + { XML_NAMESPACE_TABLE, XML_OBJECT_NAME, XML_TOK_SOURCE_SERVICE_ATTR_OBJECT_NAME }, + { XML_NAMESPACE_TABLE, XML_USER_NAME, XML_TOK_SOURCE_SERVICE_ATTR_USER_NAME }, + { XML_NAMESPACE_TABLE, XML_PASSWORD, XML_TOK_SOURCE_SERVICE_ATTR_PASSWORD }, + XML_TOKEN_MAP_END + }; + + pDataPilotTableSourceServiceAttrTokenMap = new SvXMLTokenMap( aDataPilotTableSourceServiceAttrTokenMap ); + } // if( !pDataPilotTableSourceServiceAttrTokenMap ) + + 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_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME_EXT }, + XML_TOKEN_MAP_END + }; + + pDataPilotGrandTotalAttrTokenMap = new SvXMLTokenMap( aDataPilotGrandTotalAttrTokenMap ); + } + + return *pDataPilotGrandTotalAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDataPilotTableSourceCellRangeAttrTokenMap() +{ + if( !pDataPilotTableSourceCellRangeAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aDataPilotTableSourceCellRangeAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_CELL_RANGE_ADDRESS, XML_TOK_SOURCE_CELL_RANGE_ATTR_CELL_RANGE_ADDRESS}, + XML_TOKEN_MAP_END + }; + + pDataPilotTableSourceCellRangeAttrTokenMap = new SvXMLTokenMap( aDataPilotTableSourceCellRangeAttrTokenMap ); + } // if( !pDataPilotTableSourceCellRangeAttrTokenMap ) + + return *pDataPilotTableSourceCellRangeAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDataPilotTableSourceCellRangeElemTokenMap() +{ + if( !pDataPilotTableSourceCellRangeElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aDataPilotTableSourceCellRangeElemTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_FILTER, XML_TOK_SOURCE_CELL_RANGE_ELEM_FILTER}, + XML_TOKEN_MAP_END + }; + + pDataPilotTableSourceCellRangeElemTokenMap = new SvXMLTokenMap( aDataPilotTableSourceCellRangeElemTokenMap ); + } // if( !pDataPilotTableSourceCellRangeElemTokenMap ) + + return *pDataPilotTableSourceCellRangeElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDataPilotFieldAttrTokenMap() +{ + if( !pDataPilotFieldAttrTokenMap ) + { + 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_EXT, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME_EXT }, + { 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 }, + { XML_NAMESPACE_TABLE, XML_SELECTED_PAGE, XML_TOK_DATA_PILOT_FIELD_ATTR_SELECTED_PAGE }, + { XML_NAMESPACE_TABLE, XML_USED_HIERARCHY, XML_TOK_DATA_PILOT_FIELD_ATTR_USED_HIERARCHY }, + XML_TOKEN_MAP_END + }; + + pDataPilotFieldAttrTokenMap = new SvXMLTokenMap( aDataPilotFieldAttrTokenMap ); + } // if( !pDataPilotFieldAttrTokenMap ) + + return *pDataPilotFieldAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDataPilotFieldElemTokenMap() +{ + if( !pDataPilotFieldElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aDataPilotFieldElemTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_DATA_PILOT_LEVEL, XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_LEVEL }, + { XML_NAMESPACE_TABLE, XML_DATA_PILOT_FIELD_REFERENCE, XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_REFERENCE }, + { XML_NAMESPACE_TABLE, XML_DATA_PILOT_GROUPS, XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_GROUPS }, + XML_TOKEN_MAP_END + }; + + pDataPilotFieldElemTokenMap = new SvXMLTokenMap( aDataPilotFieldElemTokenMap ); + } // if( !pDataPilotFieldElemTokenMap ) + + return *pDataPilotFieldElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDataPilotLevelAttrTokenMap() +{ + if( !pDataPilotLevelAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aDataPilotLevelAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_SHOW_EMPTY, XML_TOK_DATA_PILOT_LEVEL_ATTR_SHOW_EMPTY }, + XML_TOKEN_MAP_END + }; + + pDataPilotLevelAttrTokenMap = new SvXMLTokenMap( aDataPilotLevelAttrTokenMap ); + } // if( !pDataPilotLevelAttrTokenMap ) + + return *pDataPilotLevelAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDataPilotLevelElemTokenMap() +{ + if( !pDataPilotLevelElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aDataPilotLevelElemTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_DATA_PILOT_SUBTOTALS, XML_TOK_DATA_PILOT_LEVEL_ELEM_DATA_PILOT_SUBTOTALS }, + { XML_NAMESPACE_TABLE, XML_DATA_PILOT_MEMBERS, XML_TOK_DATA_PILOT_LEVEL_ELEM_DATA_PILOT_MEMBERS }, + { XML_NAMESPACE_TABLE, XML_DATA_PILOT_DISPLAY_INFO, XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_DISPLAY_INFO }, + { XML_NAMESPACE_TABLE, XML_DATA_PILOT_SORT_INFO, XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_SORT_INFO }, + { XML_NAMESPACE_TABLE, XML_DATA_PILOT_LAYOUT_INFO, XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_LAYOUT_INFO }, + XML_TOKEN_MAP_END + }; + + pDataPilotLevelElemTokenMap = new SvXMLTokenMap( aDataPilotLevelElemTokenMap ); + } // if( !pDataPilotLevelElemTokenMap ) + + return *pDataPilotLevelElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDataPilotSubTotalsElemTokenMap() +{ + if( !pDataPilotSubTotalsElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aDataPilotSubTotalsElemTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_DATA_PILOT_SUBTOTAL, XML_TOK_DATA_PILOT_SUBTOTALS_ELEM_DATA_PILOT_SUBTOTAL }, + XML_TOKEN_MAP_END + }; + + pDataPilotSubTotalsElemTokenMap = new SvXMLTokenMap( aDataPilotSubTotalsElemTokenMap ); + } // if( !pDataPilotSubTotalsElemTokenMap ) + + return *pDataPilotSubTotalsElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDataPilotSubTotalAttrTokenMap() +{ + if( !pDataPilotSubTotalAttrTokenMap ) + { + 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_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME_EXT }, + XML_TOKEN_MAP_END + }; + + pDataPilotSubTotalAttrTokenMap = new SvXMLTokenMap( aDataPilotSubTotalAttrTokenMap ); + } // if( !pDataPilotSubTotalAttrTokenMap ) + + return *pDataPilotSubTotalAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDataPilotMembersElemTokenMap() +{ + if( !pDataPilotMembersElemTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aDataPilotMembersElemTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_DATA_PILOT_MEMBER, XML_TOK_DATA_PILOT_MEMBERS_ELEM_DATA_PILOT_MEMBER }, + XML_TOKEN_MAP_END + }; + + pDataPilotMembersElemTokenMap = new SvXMLTokenMap( aDataPilotMembersElemTokenMap ); + } // if( !pDataPilotMembersElemTokenMap ) + + return *pDataPilotMembersElemTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetDataPilotMemberAttrTokenMap() +{ + if( !pDataPilotMemberAttrTokenMap ) + { + 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_EXT, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME_EXT }, + { 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 + }; + + pDataPilotMemberAttrTokenMap = new SvXMLTokenMap( aDataPilotMemberAttrTokenMap ); + } // if( !pDataPilotMemberAttrTokenMap ) + + return *pDataPilotMemberAttrTokenMap; +} + +const SvXMLTokenMap& ScXMLImport::GetConsolidationAttrTokenMap() +{ + if( !pConsolidationAttrTokenMap ) + { + static __FAR_DATA SvXMLTokenMapEntry aConsolidationAttrTokenMap[] = + { + { XML_NAMESPACE_TABLE, XML_FUNCTION, XML_TOK_CONSOLIDATION_ATTR_FUNCTION }, + { XML_NAMESPACE_TABLE, XML_SOURCE_CELL_RANGE_ADDRESSES, XML_TOK_CONSOLIDATION_ATTR_SOURCE_RANGES }, + { XML_NAMESPACE_TABLE, XML_TARGET_CELL_ADDRESS, XML_TOK_CONSOLIDATION_ATTR_TARGET_ADDRESS }, + { XML_NAMESPACE_TABLE, XML_USE_LABEL, XML_TOK_CONSOLIDATION_ATTR_USE_LABEL }, + { XML_NAMESPACE_TABLE, XML_LINK_TO_SOURCE_DATA, XML_TOK_CONSOLIDATION_ATTR_LINK_TO_SOURCE }, + XML_TOKEN_MAP_END + }; + + pConsolidationAttrTokenMap = new SvXMLTokenMap( aConsolidationAttrTokenMap ); + } // if( !pConsolidationAttrTokenMap ) + + return *pConsolidationAttrTokenMap; +} + + +SvXMLImportContext *ScXMLImport::CreateContext( sal_uInt16 nPrefix, + const OUString& rLocalName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext = 0; + + if( (XML_NAMESPACE_OFFICE == nPrefix) && + ( IsXMLToken(rLocalName, XML_DOCUMENT_STYLES) || + IsXMLToken(rLocalName, XML_DOCUMENT_CONTENT) || + IsXMLToken(rLocalName, XML_DOCUMENT_SETTINGS) )) { + pContext = new ScXMLDocContext_Impl( *this, nPrefix, rLocalName, + xAttrList ); + } else if ( (XML_NAMESPACE_OFFICE == nPrefix) && + ( IsXMLToken(rLocalName, XML_DOCUMENT_META)) ) { + pContext = CreateMetaContext(rLocalName); + } else if ( (XML_NAMESPACE_OFFICE == nPrefix) && + ( IsXMLToken(rLocalName, XML_DOCUMENT)) ) { + uno::Reference<xml::sax::XDocumentHandler> xDocBuilder( + mxServiceFactory->createInstance(::rtl::OUString::createFromAscii( + "com.sun.star.xml.dom.SAXDocumentBuilder")), + uno::UNO_QUERY_THROW); + uno::Reference<document::XDocumentPropertiesSupplier> xDPS( + GetModel(), uno::UNO_QUERY_THROW); + // flat OpenDocument file format + pContext = new ScXMLFlatDocContext_Impl( *this, nPrefix, rLocalName, + xAttrList, xDPS->getDocumentProperties(), xDocBuilder); + } + else + pContext = SvXMLImport::CreateContext( nPrefix, rLocalName, xAttrList ); + + return pContext; +} + +// #110680# +ScXMLImport::ScXMLImport( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory, + const sal_uInt16 nImportFlag) +: SvXMLImport( xServiceFactory, nImportFlag ), + pDoc( NULL ), + pChangeTrackingImportHelper(NULL), + pStylesImportHelper(NULL), + sNumberFormat(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_NUMFMT)), + sLocale(RTL_CONSTASCII_USTRINGPARAM(SC_LOCALE)), + sCellStyle(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CELLSTYL)), + sStandardFormat(RTL_CONSTASCII_USTRINGPARAM(SC_STANDARDFORMAT)), + sType(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_TYPE)), +// pScAutoStylePool(new SvXMLAutoStylePoolP), +// pParaItemMapper( 0 ), +// pI18NMap( new SvI18NMap ), + pDocElemTokenMap( 0 ), + pStylesElemTokenMap( 0 ), + pStylesAttrTokenMap( 0 ), + pStyleElemTokenMap( 0 ), + pBodyElemTokenMap( 0 ), + pContentValidationsElemTokenMap( 0 ), + pContentValidationElemTokenMap( 0 ), + pContentValidationAttrTokenMap( 0 ), + pContentValidationMessageElemTokenMap( 0 ), + pContentValidationHelpMessageAttrTokenMap( 0 ), + pContentValidationErrorMessageAttrTokenMap( 0 ), + pContentValidationErrorMacroAttrTokenMap( 0 ), + pLabelRangesElemTokenMap( 0 ), + pLabelRangeAttrTokenMap( 0 ), + pTableElemTokenMap( 0 ), + pTableRowsElemTokenMap( 0 ), + pTableColsElemTokenMap( 0 ), + pTableScenarioAttrTokenMap( 0 ), + pTableAttrTokenMap( 0 ), + pTableColAttrTokenMap( 0 ), + pTableRowElemTokenMap( 0 ), + pTableRowAttrTokenMap( 0 ), + pTableRowCellElemTokenMap( 0 ), + pTableRowCellAttrTokenMap( 0 ), + pTableAnnotationAttrTokenMap( 0 ), + pDetectiveElemTokenMap( 0 ), + pDetectiveHighlightedAttrTokenMap( 0 ), + pDetectiveOperationAttrTokenMap( 0 ), + pTableCellRangeSourceAttrTokenMap( 0 ), + pNamedExpressionsElemTokenMap( 0 ), + pNamedRangeAttrTokenMap( 0 ), + pNamedExpressionAttrTokenMap( 0 ), + pDatabaseRangesElemTokenMap( 0 ), + pDatabaseRangeElemTokenMap( 0 ), + pDatabaseRangeAttrTokenMap( 0 ), + pDatabaseRangeSourceSQLAttrTokenMap( 0 ), + pDatabaseRangeSourceTableAttrTokenMap( 0 ), + pDatabaseRangeSourceQueryAttrTokenMap( 0 ), + pFilterElemTokenMap( 0 ), + pFilterAttrTokenMap( 0 ), + pFilterConditionAttrTokenMap( 0 ), + pSortElemTokenMap( 0 ), + pSortAttrTokenMap( 0 ), + pSortSortByAttrTokenMap( 0 ), + pDatabaseRangeSubTotalRulesElemTokenMap( 0 ), + pDatabaseRangeSubTotalRulesAttrTokenMap( 0 ), + pSubTotalRulesSortGroupsAttrTokenMap( 0 ), + pSubTotalRulesSubTotalRuleElemTokenMap( 0 ), + pSubTotalRulesSubTotalRuleAttrTokenMap( 0 ), + pSubTotalRuleSubTotalFieldAttrTokenMap( 0 ), + pDataPilotTablesElemTokenMap( 0 ), + pDataPilotTableAttrTokenMap( 0 ), + pDataPilotTableElemTokenMap( 0 ), + pDataPilotTableSourceServiceAttrTokenMap( 0 ), + pDataPilotGrandTotalAttrTokenMap(NULL), + pDataPilotTableSourceCellRangeElemTokenMap( 0 ), + pDataPilotTableSourceCellRangeAttrTokenMap( 0 ), + pDataPilotFieldAttrTokenMap( 0 ), + pDataPilotFieldElemTokenMap( 0 ), + pDataPilotLevelAttrTokenMap( 0 ), + pDataPilotLevelElemTokenMap( 0 ), + pDataPilotSubTotalsElemTokenMap( 0 ), + pDataPilotSubTotalAttrTokenMap( 0 ), + pDataPilotMembersElemTokenMap( 0 ), + pDataPilotMemberAttrTokenMap( 0 ), + pConsolidationAttrTokenMap( 0 ), + aTables(*this), + pMyNamedExpressions(NULL), + pMyLabelRanges(NULL), + pValidations(NULL), + pDetectiveOpArray(NULL), + pScUnoGuard(NULL), + pNumberFormatAttributesExportHelper(NULL), + pStyleNumberFormats(NULL), + sPrevStyleName(), + sPrevCurrency(), + nSolarMutexLocked(0), + nProgressCount(0), + nStyleFamilyMask( 0 ), + nPrevCellType(0), + bLoadDoc( sal_True ), + bRemoveLastChar(sal_False), + bNullDateSetted(sal_False), + bSelfImportingXMLSet(sal_False), + bLatinDefaultStyle(sal_False), + bFromWrapper(sal_False) +{ + pStylesImportHelper = new ScMyStylesImportHelper(*this); + + xScPropHdlFactory = new XMLScPropHdlFactory; + xCellStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScCellStylesProperties, xScPropHdlFactory); + xColumnStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScColumnStylesProperties, xScPropHdlFactory); + xRowStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScRowStylesImportProperties, xScPropHdlFactory); + xTableStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScTableStylesImportProperties, xScPropHdlFactory); + + // #i66550# needed for 'presentation:event-listener' element for URLs in shapes + GetNamespaceMap().Add( + GetXMLToken( XML_NP_PRESENTATION ), + GetXMLToken( XML_N_PRESENTATION ), + XML_NAMESPACE_PRESENTATION ); + + // initialize cell type map. + const struct { XMLTokenEnum _token; sal_Int16 _type; } aCellTypePairs[] = + { + { XML_FLOAT, util::NumberFormat::NUMBER }, + { XML_STRING, util::NumberFormat::TEXT }, + { XML_TIME, util::NumberFormat::TIME }, + { XML_DATE, util::NumberFormat::DATETIME }, + { XML_PERCENTAGE, util::NumberFormat::PERCENT }, + { XML_CURRENCY, util::NumberFormat::CURRENCY }, + { XML_BOOLEAN, util::NumberFormat::LOGICAL } + }; + size_t n = sizeof(aCellTypePairs)/sizeof(aCellTypePairs[0]); + for (size_t i = 0; i < n; ++i) + { + aCellTypeMap.insert( + CellTypeMap::value_type( + GetXMLToken(aCellTypePairs[i]._token), aCellTypePairs[i]._type)); + } +} + +ScXMLImport::~ScXMLImport() throw() +{ + // delete pI18NMap; + delete pDocElemTokenMap; + delete pStylesElemTokenMap; + delete pStylesAttrTokenMap; + delete pStyleElemTokenMap; + delete pBodyElemTokenMap; + delete pContentValidationsElemTokenMap; + delete pContentValidationElemTokenMap; + delete pContentValidationAttrTokenMap; + delete pContentValidationMessageElemTokenMap; + delete pContentValidationHelpMessageAttrTokenMap; + delete pContentValidationErrorMessageAttrTokenMap; + delete pContentValidationErrorMacroAttrTokenMap; + delete pLabelRangesElemTokenMap; + delete pLabelRangeAttrTokenMap; + delete pTableElemTokenMap; + delete pTableRowsElemTokenMap; + delete pTableColsElemTokenMap; + delete pTableAttrTokenMap; + delete pTableScenarioAttrTokenMap; + delete pTableColAttrTokenMap; + delete pTableRowElemTokenMap; + delete pTableRowAttrTokenMap; + delete pTableRowCellElemTokenMap; + delete pTableRowCellAttrTokenMap; + delete pTableAnnotationAttrTokenMap; + delete pDetectiveElemTokenMap; + delete pDetectiveHighlightedAttrTokenMap; + delete pDetectiveOperationAttrTokenMap; + delete pTableCellRangeSourceAttrTokenMap; + delete pNamedExpressionsElemTokenMap; + delete pNamedRangeAttrTokenMap; + delete pNamedExpressionAttrTokenMap; + delete pDatabaseRangesElemTokenMap; + delete pDatabaseRangeElemTokenMap; + delete pDatabaseRangeAttrTokenMap; + delete pDatabaseRangeSourceSQLAttrTokenMap; + delete pDatabaseRangeSourceTableAttrTokenMap; + delete pDatabaseRangeSourceQueryAttrTokenMap; + delete pFilterElemTokenMap; + delete pFilterAttrTokenMap; + delete pFilterConditionAttrTokenMap; + delete pSortElemTokenMap; + delete pSortAttrTokenMap; + delete pSortSortByAttrTokenMap; + delete pDatabaseRangeSubTotalRulesElemTokenMap; + delete pDatabaseRangeSubTotalRulesAttrTokenMap; + delete pSubTotalRulesSortGroupsAttrTokenMap; + delete pSubTotalRulesSubTotalRuleElemTokenMap; + delete pSubTotalRulesSubTotalRuleAttrTokenMap; + delete pSubTotalRuleSubTotalFieldAttrTokenMap; + delete pDataPilotTablesElemTokenMap; + delete pDataPilotTableAttrTokenMap; + delete pDataPilotTableElemTokenMap; + delete pDataPilotTableSourceServiceAttrTokenMap; + delete pDataPilotTableSourceCellRangeAttrTokenMap; + delete pDataPilotTableSourceCellRangeElemTokenMap; + delete pDataPilotFieldAttrTokenMap; + delete pDataPilotFieldElemTokenMap; + delete pDataPilotLevelAttrTokenMap; + delete pDataPilotLevelElemTokenMap; + delete pDataPilotSubTotalsElemTokenMap; + delete pDataPilotSubTotalAttrTokenMap; + delete pDataPilotMembersElemTokenMap; + delete pDataPilotMemberAttrTokenMap; + delete pConsolidationAttrTokenMap; + + // if (pScAutoStylePool) + // delete pScAutoStylePool; + if (pChangeTrackingImportHelper) + delete pChangeTrackingImportHelper; + if (pNumberFormatAttributesExportHelper) + delete pNumberFormatAttributesExportHelper; + if (pStyleNumberFormats) + delete pStyleNumberFormats; + if (pStylesImportHelper) + delete pStylesImportHelper; + + if (pScUnoGuard) + delete pScUnoGuard; + + if (pMyNamedExpressions) + delete pMyNamedExpressions; + if (pMyLabelRanges) + delete pMyLabelRanges; + if (pValidations) + delete pValidations; + if (pDetectiveOpArray) + delete pDetectiveOpArray; +} + +// --------------------------------------------------------------------- + +SvXMLImportContext *ScXMLImport::CreateFontDeclsContext(const sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList) +{ + SvXMLImportContext *pContext = NULL; + if (!pContext) + { + XMLFontStylesContext *pFSContext( + new XMLFontStylesContext( *this, nPrefix, + rLocalName, xAttrList, + gsl_getSystemTextEncoding() )); + SetFontDecls( pFSContext ); + pContext = pFSContext; + } + return pContext; +} + +SvXMLImportContext *ScXMLImport::CreateStylesContext(const ::rtl::OUString& rLocalName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList, sal_Bool bIsAutoStyle ) +{ + SvXMLImportContext *pContext(NULL); + if (!pContext) + { + pContext = new XMLTableStylesContext(*this, XML_NAMESPACE_OFFICE, rLocalName, xAttrList, bIsAutoStyle); + if (bIsAutoStyle) + //xAutoStyles = pContext; + SetAutoStyles((SvXMLStylesContext*)pContext); + else + //xStyles = pContext; + SetStyles((SvXMLStylesContext*)pContext); + } + return pContext; +} + +SvXMLImportContext *ScXMLImport::CreateBodyContext(const ::rtl::OUString& rLocalName, + const uno::Reference<xml::sax::XAttributeList>& xAttrList) +{ + //GetShapeImport()->SetAutoStylesContext((XMLTableStylesContext *)&xAutoStyles); + //GetChartImport()->SetAutoStylesContext(GetAutoStyles()/*(XMLTableStylesContext *)&xAutoStyles*/); + + return new ScXMLBodyContext(*this, XML_NAMESPACE_OFFICE, rLocalName, xAttrList); +} + +SvXMLImportContext *ScXMLImport::CreateMetaContext( + const OUString& rLocalName ) +{ + SvXMLImportContext *pContext(0); + + if( !IsStylesOnlyMode() && (getImportFlags() & IMPORT_META)) + { + uno::Reference<xml::sax::XDocumentHandler> xDocBuilder( + mxServiceFactory->createInstance(::rtl::OUString::createFromAscii( + "com.sun.star.xml.dom.SAXDocumentBuilder")), + uno::UNO_QUERY_THROW); + uno::Reference<document::XDocumentPropertiesSupplier> xDPS( + GetModel(), uno::UNO_QUERY_THROW); + pContext = new SvXMLMetaDocumentContext(*this, + XML_NAMESPACE_OFFICE, rLocalName, + xDPS->getDocumentProperties(), xDocBuilder); + } + + if( !pContext ) + pContext = new SvXMLImportContext( *this, + XML_NAMESPACE_OFFICE, rLocalName ); + + return pContext; +} + +SvXMLImportContext *ScXMLImport::CreateScriptContext( + const OUString& rLocalName ) +{ + SvXMLImportContext *pContext(0); + + if( !(IsStylesOnlyMode()) ) + { + pContext = new XMLScriptContext( *this, + XML_NAMESPACE_OFFICE, rLocalName, + GetModel() ); + } + + if( !pContext ) + pContext = new SvXMLImportContext( *this, XML_NAMESPACE_OFFICE, + rLocalName ); + + return pContext; +} + +void ScXMLImport::SetStatistics( + const uno::Sequence<beans::NamedValue> & i_rStats) +{ + static const char* s_stats[] = + { "TableCount", "CellCount", "ObjectCount", 0 }; + + SvXMLImport::SetStatistics(i_rStats); + + sal_uInt32 nCount(0); + for (sal_Int32 i = 0; i < i_rStats.getLength(); ++i) { + for (const char** pStat = s_stats; *pStat != 0; ++pStat) { + if (i_rStats[i].Name.equalsAscii(*pStat)) { + sal_Int32 val = 0; + if (i_rStats[i].Value >>= val) { + nCount += val; + } else { + DBG_ERROR("ScXMLImport::SetStatistics: invalid entry"); + } + } + } + } + + if (nCount) + { + GetProgressBarHelper()->SetReference(nCount); + GetProgressBarHelper()->SetValue(0); + } +} + +sal_Int16 ScXMLImport::GetCellType(const OUString& rStrValue) const +{ + CellTypeMap::const_iterator itr = aCellTypeMap.find(rStrValue); + if (itr != aCellTypeMap.end()) + return itr->second; + + return util::NumberFormat::UNDEFINED; +} + +XMLShapeImportHelper* ScXMLImport::CreateShapeImport() +{ + /*UniReference < XMLPropertySetMapper > xShapeStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScShapeStylesProperties, xScPropHdlFactory); + SvXMLImportPropertyMapper *pShapeStylesImportPropertySetMapper = new SvXMLImportPropertyMapper( xShapeStylesPropertySetMapper );*/ + + return new XMLTableShapeImportHelper( *this/*, pShapeStylesImportPropertySetMapper*/ ); +} + +sal_Bool ScXMLImport::GetValidation(const rtl::OUString& sName, ScMyImportValidation& aValidation) +{ + if (pValidations) + { + sal_Bool bFound(sal_False); + ScMyImportValidations::iterator aItr(pValidations->begin()); + ScMyImportValidations::iterator aEndItr(pValidations->end()); + while(aItr != aEndItr && !bFound) + { + if (aItr->sName == sName) + { + // #b4974740# source position must be set as string, + // so sBaseCellAddress no longer has to be converted here + + bFound = sal_True; + } + else + ++aItr; + } + if (bFound) + aValidation = *aItr; + return bFound; + } + return sal_False; +} + +ScXMLChangeTrackingImportHelper* ScXMLImport::GetChangeTrackingImportHelper() +{ + if (!pChangeTrackingImportHelper) + pChangeTrackingImportHelper = new ScXMLChangeTrackingImportHelper(); + return pChangeTrackingImportHelper; +} + +void ScXMLImport::InsertStyles() +{ + GetStyles()->CopyStylesToDoc(sal_True); + + // if content is going to be loaded with the same import, set bLatinDefaultStyle flag now + if ( getImportFlags() & IMPORT_CONTENT ) + ExamineDefaultStyle(); +} + +void ScXMLImport::ExamineDefaultStyle() +{ + if (pDoc) + { + // #i62435# after inserting the styles, check if the default style has a latin-script-only + // number format (then, value cells can be pre-initialized with western script type) + + const ScPatternAttr* pDefPattern = pDoc->GetDefPattern(); + SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); + if ( pFormatter && pDefPattern ) + { + sal_uInt32 nKey = pDefPattern->GetNumberFormat(pFormatter); + const SvNumberformat* pFormat = pFormatter->GetEntry(nKey); + if ( pFormat && pFormat->IsStandard() ) + { + // The standard format is all-latin if the decimal separator dosen't + // have a different script type + + String aDecSep; + LanguageType nFormatLang = pFormat->GetLanguage(); + if ( nFormatLang == LANGUAGE_SYSTEM ) + aDecSep = ScGlobal::pLocaleData->getNumDecimalSep(); + else + { + LocaleDataWrapper aLocaleData( pDoc->GetServiceManager(), + MsLangId::convertLanguageToLocale( nFormatLang ) ); + aDecSep = aLocaleData.getNumDecimalSep(); + } + + sal_uInt8 nScript = pDoc->GetStringScriptType( aDecSep ); + if ( nScript == 0 || nScript == SCRIPTTYPE_LATIN ) + bLatinDefaultStyle = sal_True; + } + } + } +} + +void ScXMLImport::SetChangeTrackingViewSettings(const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& rChangeProps) +{ + if (pDoc) + { + sal_Int32 nCount(rChangeProps.getLength()); + if (nCount) + { + LockSolarMutex(); + sal_Int16 nTemp16(0); + ScChangeViewSettings* pViewSettings(new ScChangeViewSettings()); + for (sal_Int32 i = 0; i < nCount; ++i) + { + rtl::OUString sName(rChangeProps[i].Name); + if (sName.compareToAscii("ShowChanges") == 0) + pViewSettings->SetShowChanges(::cppu::any2bool(rChangeProps[i].Value)); + else if (sName.compareToAscii("ShowAcceptedChanges") == 0) + pViewSettings->SetShowAccepted(::cppu::any2bool(rChangeProps[i].Value)); + else if (sName.compareToAscii("ShowRejectedChanges") == 0) + pViewSettings->SetShowRejected(::cppu::any2bool(rChangeProps[i].Value)); + else if (sName.compareToAscii("ShowChangesByDatetime") == 0) + pViewSettings->SetHasDate(::cppu::any2bool(rChangeProps[i].Value)); + else if (sName.compareToAscii("ShowChangesByDatetimeMode") == 0) + { + if (rChangeProps[i].Value >>= nTemp16) + pViewSettings->SetTheDateMode(ScChgsDateMode(nTemp16)); + } + else if (sName.compareToAscii("ShowChangesByDatetimeFirstDatetime") == 0) + { + util::DateTime aDateTime; + if (rChangeProps[i].Value >>= aDateTime) + { + DateTime aCoreDateTime; + ScXMLConverter::ConvertAPIToCoreDateTime(aDateTime, aCoreDateTime); + pViewSettings->SetTheFirstDateTime(aCoreDateTime); + } + } + else if (sName.compareToAscii("ShowChangesByDatetimeSecondDatetime") == 0) + { + util::DateTime aDateTime; + if (rChangeProps[i].Value >>= aDateTime) + { + DateTime aCoreDateTime; + ScXMLConverter::ConvertAPIToCoreDateTime(aDateTime, aCoreDateTime); + pViewSettings->SetTheLastDateTime(aCoreDateTime); + } + } + else if (sName.compareToAscii("ShowChangesByAuthor") == 0) + pViewSettings->SetHasAuthor(::cppu::any2bool(rChangeProps[i].Value)); + else if (sName.compareToAscii("ShowChangesByAuthorName") == 0) + { + rtl::OUString sOUName; + if (rChangeProps[i].Value >>= sOUName) + { + String sAuthorName(sOUName); + pViewSettings->SetTheAuthorToShow(sAuthorName); + } + } + else if (sName.compareToAscii("ShowChangesByComment") == 0) + pViewSettings->SetHasComment(::cppu::any2bool(rChangeProps[i].Value)); + else if (sName.compareToAscii("ShowChangesByCommentText") == 0) + { + rtl::OUString sOUComment; + if (rChangeProps[i].Value >>= sOUComment) + { + String sComment(sOUComment); + pViewSettings->SetTheComment(sComment); + } + } + else if (sName.compareToAscii("ShowChangesByRanges") == 0) + pViewSettings->SetHasRange(::cppu::any2bool(rChangeProps[i].Value)); + else if (sName.compareToAscii("ShowChangesByRangesList") == 0) + { + rtl::OUString sRanges; + if ((rChangeProps[i].Value >>= sRanges) && sRanges.getLength()) + { + ScRangeList aRangeList; + ScRangeStringConverter::GetRangeListFromString( + aRangeList, sRanges, GetDocument(), FormulaGrammar::CONV_OOO); + pViewSettings->SetTheRangeList(aRangeList); + } + } + } + pDoc->SetChangeViewSettings(*pViewSettings); + UnlockSolarMutex(); + } + } +} + +void ScXMLImport::SetViewSettings(const uno::Sequence<beans::PropertyValue>& aViewProps) +{ + sal_Int32 nCount(aViewProps.getLength()); + sal_Int32 nHeight(0); + sal_Int32 nLeft(0); + sal_Int32 nTop(0); + sal_Int32 nWidth(0); + for (sal_Int32 i = 0; i < nCount; ++i) + { + rtl::OUString sName(aViewProps[i].Name); + if (sName.compareToAscii("VisibleAreaHeight") == 0) + aViewProps[i].Value >>= nHeight; + else if (sName.compareToAscii("VisibleAreaLeft") == 0) + aViewProps[i].Value >>= nLeft; + else if (sName.compareToAscii("VisibleAreaTop") == 0) + aViewProps[i].Value >>= nTop; + else if (sName.compareToAscii("VisibleAreaWidth") == 0) + aViewProps[i].Value >>= nWidth; + else if (sName.compareToAscii("TrackedChangesViewSettings") == 0) + { + uno::Sequence<beans::PropertyValue> aChangeProps; + if(aViewProps[i].Value >>= aChangeProps) + SetChangeTrackingViewSettings(aChangeProps); + } + } + if (nHeight && nWidth) + { + if (GetModel().is()) + { + ScModelObj* pDocObj(ScModelObj::getImplementation( GetModel() )); + if (pDocObj) + { + SfxObjectShell* pEmbeddedObj = pDocObj->GetEmbeddedObject(); + if (pEmbeddedObj) + { + Rectangle aRect; + aRect.setX( nLeft ); + aRect.setY( nTop ); + aRect.setWidth( nWidth ); + aRect.setHeight( nHeight ); + pEmbeddedObj->SetVisArea(aRect); + } + } + } + } +} + +void ScXMLImport::SetConfigurationSettings(const uno::Sequence<beans::PropertyValue>& aConfigProps) +{ + if (GetModel().is()) + { + uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY); + if (xMultiServiceFactory.is()) + { + sal_Int32 nCount(aConfigProps.getLength()); + rtl::OUString sCTName(RTL_CONSTASCII_USTRINGPARAM("TrackedChangesProtectionKey")); + rtl::OUString sVBName(RTL_CONSTASCII_USTRINGPARAM("VBACompatibilityMode")); + rtl::OUString sSCName(RTL_CONSTASCII_USTRINGPARAM("ScriptConfiguration")); + for (sal_Int32 i = nCount - 1; i >= 0; --i) + { + if (aConfigProps[i].Name == sCTName) + { + rtl::OUString sKey; + if (aConfigProps[i].Value >>= sKey) + { + uno::Sequence<sal_Int8> aPass; + SvXMLUnitConverter::decodeBase64(aPass, sKey); + if (aPass.getLength()) + { + if (pDoc->GetChangeTrack()) + pDoc->GetChangeTrack()->SetProtection(aPass); + else + { + ScStrCollection aUsers; + ScChangeTrack* pTrack = new ScChangeTrack(pDoc, aUsers); + pTrack->SetProtection(aPass); + pDoc->SetChangeTrack(pTrack); + } + } + } + } + // store the following items for later use (after document is loaded) + else if ((aConfigProps[i].Name == sVBName) || (aConfigProps[i].Name == sSCName)) + { + uno::Reference< beans::XPropertySet > xImportInfo = getImportInfo(); + if (xImportInfo.is()) + { + uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = xImportInfo->getPropertySetInfo(); + if (xPropertySetInfo.is() && xPropertySetInfo->hasPropertyByName(aConfigProps[i].Name)) + xImportInfo->setPropertyValue( aConfigProps[i].Name, aConfigProps[i].Value ); + } + } + } + uno::Reference <uno::XInterface> xInterface = xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.SpreadsheetSettings"))); + uno::Reference <beans::XPropertySet> xProperties(xInterface, uno::UNO_QUERY); + if (xProperties.is()) + SvXMLUnitConverter::convertPropertySet(xProperties, aConfigProps); + } + } +} + +sal_Int32 ScXMLImport::SetCurrencySymbol(const sal_Int32 nKey, const rtl::OUString& rCurrency) +{ + uno::Reference <util::XNumberFormatsSupplier> xNumberFormatsSupplier(GetNumberFormatsSupplier()); + if (xNumberFormatsSupplier.is()) + { + uno::Reference <util::XNumberFormats> xLocalNumberFormats(xNumberFormatsSupplier->getNumberFormats()); + if (xLocalNumberFormats.is()) + { + rtl::OUString sFormatString; + try + { + uno::Reference <beans::XPropertySet> xProperties(xLocalNumberFormats->getByKey(nKey)); + if (xProperties.is()) + { + lang::Locale aLocale; + if (GetDocument() && (xProperties->getPropertyValue(sLocale) >>= aLocale)) + { + LockSolarMutex(); + LocaleDataWrapper aLocaleData( GetDocument()->GetServiceManager(), aLocale ); + rtl::OUStringBuffer aBuffer(15); + aBuffer.appendAscii("#"); + aBuffer.append( aLocaleData.getNumThousandSep() ); + aBuffer.appendAscii("##0"); + aBuffer.append( aLocaleData.getNumDecimalSep() ); + aBuffer.appendAscii("00 [$"); + aBuffer.append(rCurrency); + aBuffer.appendAscii("]"); + UnlockSolarMutex(); + sFormatString = aBuffer.makeStringAndClear(); + sal_Int32 nNewKey = xLocalNumberFormats->queryKey(sFormatString, aLocale, sal_True); + if (nNewKey == -1) + nNewKey = xLocalNumberFormats->addNew(sFormatString, aLocale); + return nNewKey; + } + } + } + catch ( util::MalformedNumberFormatException& rException ) + { + rtl::OUString sErrorMessage(RTL_CONSTASCII_USTRINGPARAM("Fehler im Formatstring ")); + sErrorMessage += sFormatString; + sErrorMessage += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" an Position ")); + sErrorMessage += rtl::OUString::valueOf(rException.CheckPos); + uno::Sequence<rtl::OUString> aSeq(1); + aSeq[0] = sErrorMessage; + uno::Reference<xml::sax::XLocator> xLocator; + SetError(XMLERROR_API | XMLERROR_FLAG_ERROR, aSeq, rException.Message, xLocator); + } + } + } + return nKey; +} + +sal_Bool ScXMLImport::IsCurrencySymbol(const sal_Int32 nNumberFormat, const rtl::OUString& sCurrentCurrency, const rtl::OUString& sBankSymbol) +{ + uno::Reference <util::XNumberFormatsSupplier> xNumberFormatsSupplier(GetNumberFormatsSupplier()); + if (xNumberFormatsSupplier.is()) + { + uno::Reference <util::XNumberFormats> xLocalNumberFormats(xNumberFormatsSupplier->getNumberFormats()); + if (xLocalNumberFormats.is()) + { + try + { + uno::Reference <beans::XPropertySet> xNumberPropertySet(xLocalNumberFormats->getByKey(nNumberFormat)); + if (xNumberPropertySet.is()) + { + rtl::OUString sTemp; + if ( xNumberPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_CURRENCYSYMBOL))) >>= sTemp) + { + if (sCurrentCurrency.equals(sTemp)) + return sal_True; + // #i61657# This may be a legacy currency symbol that changed in the meantime. + if (SvNumberFormatter::GetLegacyOnlyCurrencyEntry( sCurrentCurrency, sBankSymbol) != NULL) + return true; + // In the rare case that sCurrentCurrency is not the + // currency symbol, but a matching ISO code + // abbreviation instead that was obtained through + // XMLNumberFormatAttributesExportHelper::GetCellType(), + // check with the number format's symbol. This happens, + // for example, in the es_BO locale, where a legacy + // B$,BOB matched B$->BOP, which leads to + // sCurrentCurrency being BOP, and the previous call + // with BOP,BOB didn't find an entry, but B$,BOB will. + return SvNumberFormatter::GetLegacyOnlyCurrencyEntry( sTemp, sBankSymbol) != NULL; + } + } + } + catch ( uno::Exception& ) + { + DBG_ERROR("Numberformat not found"); + } + } + } + return sal_False; +} + +void ScXMLImport::SetType(uno::Reference <beans::XPropertySet>& rProperties, + sal_Int32& rNumberFormat, + const sal_Int16 nCellType, + const rtl::OUString& rCurrency) +{ + if ((nCellType != util::NumberFormat::TEXT) && (nCellType != util::NumberFormat::UNDEFINED)) + { + if (rNumberFormat == -1) + rProperties->getPropertyValue( sNumberFormat ) >>= rNumberFormat; + DBG_ASSERT(rNumberFormat != -1, "no NumberFormat"); + sal_Bool bIsStandard; + // sCurrentCurrency may be the ISO code abbreviation if the currency + // symbol matches such, or if no match found the symbol itself! + rtl::OUString sCurrentCurrency; + sal_Int32 nCurrentCellType( + GetNumberFormatAttributesExportHelper()->GetCellType( + rNumberFormat, sCurrentCurrency, bIsStandard) & ~util::NumberFormat::DEFINED); + if ((nCellType != nCurrentCellType) && !((nCellType == util::NumberFormat::NUMBER && + ((nCurrentCellType == util::NumberFormat::SCIENTIFIC) || + (nCurrentCellType == util::NumberFormat::FRACTION) || + (nCurrentCellType == util::NumberFormat::LOGICAL) || + (nCurrentCellType == 0))) || (nCurrentCellType == util::NumberFormat::TEXT)) && !((nCellType == util::NumberFormat::DATETIME) && + (nCurrentCellType == util::NumberFormat::DATE))) + { + if (!xNumberFormats.is()) + { + uno::Reference <util::XNumberFormatsSupplier> xNumberFormatsSupplier(GetNumberFormatsSupplier()); + if (xNumberFormatsSupplier.is()) + xNumberFormats.set(xNumberFormatsSupplier->getNumberFormats()); + } + if (xNumberFormats.is()) + { + try + { + uno::Reference < beans::XPropertySet> xNumberFormatProperties(xNumberFormats->getByKey(rNumberFormat)); + if (xNumberFormatProperties.is()) + { + if (nCellType != util::NumberFormat::CURRENCY) + { + lang::Locale aLocale; + if ( xNumberFormatProperties->getPropertyValue(sLocale) >>= aLocale ) + { + if (!xNumberFormatTypes.is()) + xNumberFormatTypes.set(uno::Reference <util::XNumberFormatTypes>(xNumberFormats, uno::UNO_QUERY)); + rProperties->setPropertyValue( sNumberFormat, uno::makeAny(xNumberFormatTypes->getStandardFormat(nCellType, aLocale)) ); + } + } + else if (rCurrency.getLength() && sCurrentCurrency.getLength()) + { + if (!sCurrentCurrency.equals(rCurrency)) + if (!IsCurrencySymbol(rNumberFormat, sCurrentCurrency, rCurrency)) + rProperties->setPropertyValue( sNumberFormat, uno::makeAny(SetCurrencySymbol(rNumberFormat, rCurrency))); + } + } + } + catch ( uno::Exception& ) + { + DBG_ERROR("Numberformat not found"); + } + } + } + else + { + if ((nCellType == util::NumberFormat::CURRENCY) && rCurrency.getLength() && sCurrentCurrency.getLength() && + !sCurrentCurrency.equals(rCurrency) && !IsCurrencySymbol(rNumberFormat, sCurrentCurrency, rCurrency)) + rProperties->setPropertyValue( sNumberFormat, uno::makeAny(SetCurrencySymbol(rNumberFormat, rCurrency))); + } + } +} + +void ScXMLImport::AddStyleRange(const table::CellRangeAddress& rCellRange) +{ + if (!xSheetCellRanges.is() && GetModel().is()) + { + uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY); + if (xMultiServiceFactory.is()) + xSheetCellRanges.set(uno::Reference <sheet::XSheetCellRangeContainer>(xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SheetCellRanges"))), uno::UNO_QUERY)); + DBG_ASSERT(xSheetCellRanges.is(), "didn't get SheetCellRanges"); + + } + xSheetCellRanges->addRangeAddress(rCellRange, sal_False); +} + +void ScXMLImport::SetStyleToRanges() +{ + if (sPrevStyleName.getLength()) + { + uno::Reference <beans::XPropertySet> xProperties (xSheetCellRanges, uno::UNO_QUERY); + if (xProperties.is()) + { + XMLTableStylesContext *pStyles((XMLTableStylesContext *)GetAutoStyles()); + XMLTableStyleContext* pStyle( pStyles ? (XMLTableStyleContext *)pStyles->FindStyleChildContext( + XML_STYLE_FAMILY_TABLE_CELL, sPrevStyleName, sal_True) : NULL ); + if (pStyle) + { + pStyle->FillPropertySet(xProperties); + sal_Int32 nNumberFormat(pStyle->GetNumberFormat()); + SetType(xProperties, nNumberFormat, nPrevCellType, sPrevCurrency); + + // store first cell of first range for each style, once per sheet + uno::Sequence<table::CellRangeAddress> aAddresses(xSheetCellRanges->getRangeAddresses()); + if ( aAddresses.getLength() > 0 ) + { + const table::CellRangeAddress& rRange = aAddresses[0]; + if ( rRange.Sheet != pStyle->GetLastSheet() ) + { + ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetModel())->GetSheetSaveData(); + pSheetData->AddCellStyle( sPrevStyleName, + ScAddress( (SCCOL)rRange.StartColumn, (SCROW)rRange.StartRow, (SCTAB)rRange.Sheet ) ); + pStyle->SetLastSheet(rRange.Sheet); + } + } + } + else + { + xProperties->setPropertyValue(sCellStyle, uno::makeAny(GetStyleDisplayName( XML_STYLE_FAMILY_TABLE_CELL, sPrevStyleName ))); + sal_Int32 nNumberFormat(GetStyleNumberFormats()->GetStyleNumberFormat(sPrevStyleName)); + sal_Bool bInsert(nNumberFormat == -1); + SetType(xProperties, nNumberFormat, nPrevCellType, sPrevCurrency); + if (bInsert) + GetStyleNumberFormats()->AddStyleNumberFormat(sPrevStyleName, nNumberFormat); + } + } + } + if (GetModel().is()) + { + uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY); + if (xMultiServiceFactory.is()) + xSheetCellRanges.set(uno::Reference <sheet::XSheetCellRangeContainer>( + xMultiServiceFactory->createInstance( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SheetCellRanges"))), + uno::UNO_QUERY)); + } + DBG_ASSERT(xSheetCellRanges.is(), "didn't get SheetCellRanges"); +} + +void ScXMLImport::SetStyleToRange(const ScRange& rRange, const rtl::OUString* pStyleName, + const sal_Int16 nCellType, const rtl::OUString* pCurrency) +{ + if (!sPrevStyleName.getLength()) + { + nPrevCellType = nCellType; + if (pStyleName) + sPrevStyleName = *pStyleName; + if (pCurrency) + sPrevCurrency = *pCurrency; + else if (sPrevCurrency.getLength()) + sPrevCurrency = sEmpty; + } + else if ((nCellType != nPrevCellType) || + ((pStyleName && !pStyleName->equals(sPrevStyleName)) || + (!pStyleName && sPrevStyleName.getLength())) || + ((pCurrency && !pCurrency->equals(sPrevCurrency)) || + (!pCurrency && sPrevCurrency.getLength()))) + { + SetStyleToRanges(); + nPrevCellType = nCellType; + if (pStyleName) + sPrevStyleName = *pStyleName; + else if(sPrevStyleName.getLength()) + sPrevStyleName = sEmpty; + if (pCurrency) + sPrevCurrency = *pCurrency; + else if(sPrevCurrency.getLength()) + sPrevCurrency = sEmpty; + } + table::CellRangeAddress aCellRange; + aCellRange.StartColumn = rRange.aStart.Col(); + aCellRange.StartRow = rRange.aStart.Row(); + aCellRange.Sheet = rRange.aStart.Tab(); + aCellRange.EndColumn = rRange.aEnd.Col(); + aCellRange.EndRow = rRange.aEnd.Row(); + AddStyleRange(aCellRange); +} + +sal_Bool ScXMLImport::SetNullDateOnUnitConverter() +{ + if (!bNullDateSetted) + bNullDateSetted = GetMM100UnitConverter().setNullDate(GetModel()); + DBG_ASSERT(bNullDateSetted, "could not set the null date"); + return bNullDateSetted; +} + +XMLNumberFormatAttributesExportHelper* ScXMLImport::GetNumberFormatAttributesExportHelper() +{ + if (!pNumberFormatAttributesExportHelper) + pNumberFormatAttributesExportHelper = new XMLNumberFormatAttributesExportHelper(GetNumberFormatsSupplier()); + return pNumberFormatAttributesExportHelper; +} + +ScMyStyleNumberFormats* ScXMLImport::GetStyleNumberFormats() +{ + if (!pStyleNumberFormats) + pStyleNumberFormats = new ScMyStyleNumberFormats(); + return pStyleNumberFormats; +} + +void ScXMLImport::SetStylesToRangesFinished() +{ + SetStyleToRanges(); + sPrevStyleName = sEmpty; +} + +// XImporter +void SAL_CALL ScXMLImport::setTargetDocument( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& xDoc ) +throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) +{ + LockSolarMutex(); + SvXMLImport::setTargetDocument( xDoc ); + + uno::Reference<frame::XModel> xModel(xDoc, uno::UNO_QUERY); + pDoc = ScXMLConverter::GetScDocument( xModel ); + DBG_ASSERT( pDoc, "ScXMLImport::setTargetDocument - no ScDocument!" ); + if (!pDoc) + throw lang::IllegalArgumentException(); + + bFromWrapper = pDoc->IsXMLFromWrapper(); // UnlockSolarMutex below still works normally + + uno::Reference<document::XActionLockable> xActionLockable(xDoc, uno::UNO_QUERY); + if (xActionLockable.is()) + xActionLockable->addActionLock(); + UnlockSolarMutex(); +} + +// XServiceInfo +::rtl::OUString SAL_CALL ScXMLImport::getImplementationName( ) +throw(::com::sun::star::uno::RuntimeException) +{ + switch( getImportFlags() ) + { + case IMPORT_ALL: + return ScXMLImport_getImplementationName(); + case (IMPORT_STYLES|IMPORT_MASTERSTYLES|IMPORT_AUTOSTYLES|IMPORT_FONTDECLS): + return ScXMLImport_Styles_getImplementationName(); + case (IMPORT_AUTOSTYLES|IMPORT_CONTENT|IMPORT_SCRIPTS|IMPORT_FONTDECLS): + return ScXMLImport_Content_getImplementationName(); + case IMPORT_META: + return ScXMLImport_Meta_getImplementationName(); + case IMPORT_SETTINGS: + return ScXMLImport_Settings_getImplementationName(); + default: + // generic name for 'unknown' cases + return ScXMLImport_getImplementationName(); + } + return SvXMLImport::getImplementationName(); +} + +// ::com::sun::star::xml::sax::XDocumentHandler +void SAL_CALL ScXMLImport::startDocument(void) +throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException ) +{ + LockSolarMutex(); + SvXMLImport::startDocument(); + if (pDoc && !pDoc->IsImportingXML()) + { + ScModelObj::getImplementation(GetModel())->BeforeXMLLoading(); + bSelfImportingXMLSet = sal_True; + } + + // if content and styles are loaded with separate imports, + // set bLatinDefaultStyle flag at the start of the content import + sal_uInt16 nFlags = getImportFlags(); + if ( ( nFlags & IMPORT_CONTENT ) && !( nFlags & IMPORT_STYLES ) ) + ExamineDefaultStyle(); + + if (getImportFlags() & IMPORT_CONTENT) + { + if (GetModel().is()) + { + // store initial namespaces, to find the ones that were added from the file later + ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetModel())->GetSheetSaveData(); + const SvXMLNamespaceMap& rNamespaces = GetNamespaceMap(); + pSheetData->StoreInitialNamespaces(rNamespaces); + } + } + + UnlockSolarMutex(); +} + +sal_Int32 ScXMLImport::GetRangeType(const rtl::OUString sRangeType) const +{ + sal_Int32 nRangeType(0); + rtl::OUStringBuffer sBuffer; + sal_Int16 i = 0; + while (i <= sRangeType.getLength()) + { + if ((sRangeType[i] == ' ') || (i == sRangeType.getLength())) + { + rtl::OUString sTemp = sBuffer.makeStringAndClear(); + if (sTemp.compareToAscii(SC_REPEAT_COLUMN) == 0) + nRangeType |= sheet::NamedRangeFlag::COLUMN_HEADER; + else if (sTemp.compareToAscii(SC_REPEAT_ROW) == 0) + nRangeType |= sheet::NamedRangeFlag::ROW_HEADER; + else if (sTemp.compareToAscii(SC_FILTER) == 0) + nRangeType |= sheet::NamedRangeFlag::FILTER_CRITERIA; + else if (sTemp.compareToAscii(SC_PRINT_RANGE) == 0) + nRangeType |= sheet::NamedRangeFlag::PRINT_AREA; + } + else if (i < sRangeType.getLength()) + sBuffer.append(sRangeType[i]); + ++i; + } + return nRangeType; +} + +void ScXMLImport::SetLabelRanges() +{ + ScMyLabelRanges* pLabelRanges = GetLabelRanges(); + if (pLabelRanges) + { + uno::Reference <beans::XPropertySet> xPropertySet (GetModel(), uno::UNO_QUERY); + if (xPropertySet.is()) + { + uno::Any aColAny = xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_COLLABELRNG))); + uno::Any aRowAny = xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ROWLABELRNG))); + + uno::Reference< sheet::XLabelRanges > xColRanges; + uno::Reference< sheet::XLabelRanges > xRowRanges; + + if ( ( aColAny >>= xColRanges ) && ( aRowAny >>= xRowRanges ) ) + { + table::CellRangeAddress aLabelRange; + table::CellRangeAddress aDataRange; + + ScMyLabelRanges::iterator aItr = pLabelRanges->begin(); + while (aItr != pLabelRanges->end()) + { + sal_Int32 nOffset1(0); + sal_Int32 nOffset2(0); + FormulaGrammar::AddressConvention eConv = FormulaGrammar::CONV_OOO; + + if (ScRangeStringConverter::GetRangeFromString( aLabelRange, (*aItr)->sLabelRangeStr, GetDocument(), eConv, nOffset1 ) && + ScRangeStringConverter::GetRangeFromString( aDataRange, (*aItr)->sDataRangeStr, GetDocument(), eConv, nOffset2 )) + { + if ( (*aItr)->bColumnOrientation ) + xColRanges->addNew( aLabelRange, aDataRange ); + else + xRowRanges->addNew( aLabelRange, aDataRange ); + } + + delete *aItr; + aItr = pLabelRanges->erase(aItr); + } + } + } + } +} + +void ScXMLImport::SetNamedRanges() +{ + ScMyNamedExpressions* pNamedExpressions(GetNamedExpressions()); + if (pNamedExpressions) + { + uno::Reference <beans::XPropertySet> xPropertySet (GetModel(), uno::UNO_QUERY); + if (xPropertySet.is()) + { + uno::Reference <sheet::XNamedRanges> xNamedRanges(xPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_NAMEDRANGES))), uno::UNO_QUERY); + if (xNamedRanges.is()) + { + ScMyNamedExpressions::iterator aItr(pNamedExpressions->begin()); + ScMyNamedExpressions::const_iterator aEndItr(pNamedExpressions->end()); + table::CellAddress aCellAddress; + rtl::OUString sTempContent(RTL_CONSTASCII_USTRINGPARAM("0")); + while (aItr != aEndItr) + { + sal_Int32 nOffset(0); + if (ScRangeStringConverter::GetAddressFromString( + aCellAddress, (*aItr)->sBaseCellAddress, GetDocument(), FormulaGrammar::CONV_OOO, nOffset )) + { + try + { + xNamedRanges->addNewByName((*aItr)->sName, sTempContent, aCellAddress, GetRangeType((*aItr)->sRangeType)); + } + catch( uno::RuntimeException& ) + { + DBG_ERROR("here are some Named Ranges with the same name"); + uno::Reference < container::XIndexAccess > xIndex(xNamedRanges, uno::UNO_QUERY); + if (xIndex.is()) + { + sal_Int32 nMax(xIndex->getCount()); + sal_Bool bInserted(sal_False); + sal_Int32 nCount(1); + rtl::OUStringBuffer sName((*aItr)->sName); + sName.append(sal_Unicode('_')); + while (!bInserted && nCount <= nMax) + { + rtl::OUStringBuffer sTemp(sName); + sTemp.append(rtl::OUString::valueOf(nCount)); + try + { + xNamedRanges->addNewByName(sTemp.makeStringAndClear(), sTempContent, aCellAddress, GetRangeType((*aItr)->sRangeType)); + bInserted = sal_True; + } + catch( uno::RuntimeException& ) + { + ++nCount; + } + } + } + } + } + ++aItr; + } + aItr = pNamedExpressions->begin(); + while (aItr != aEndItr) + { + sal_Int32 nOffset(0); + if (ScRangeStringConverter::GetAddressFromString( + aCellAddress, (*aItr)->sBaseCellAddress, GetDocument(), FormulaGrammar::CONV_OOO, nOffset )) + { + uno::Reference <sheet::XNamedRange> xNamedRange(xNamedRanges->getByName((*aItr)->sName), uno::UNO_QUERY); + if (xNamedRange.is()) + { + LockSolarMutex(); + ScNamedRangeObj* pNamedRangeObj = ScNamedRangeObj::getImplementation( xNamedRange); + if (pNamedRangeObj) + { + sTempContent = (*aItr)->sContent; + // Get rid of leading sheet dots in simple ranges. + if (!(*aItr)->bIsExpression) + ScXMLConverter::ParseFormula( sTempContent, false); + pNamedRangeObj->SetContentWithGrammar( sTempContent, (*aItr)->eGrammar); + } + UnlockSolarMutex(); + } + } + delete *aItr; + aItr = pNamedExpressions->erase(aItr); + } + } + } + } +} + +void SAL_CALL ScXMLImport::endDocument(void) +throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException ) +{ + LockSolarMutex(); + if (getImportFlags() & IMPORT_CONTENT) + { + if (GetModel().is()) + { + uno::Reference<document::XViewDataSupplier> xViewDataSupplier(GetModel(), uno::UNO_QUERY); + if (xViewDataSupplier.is()) + { + uno::Reference<container::XIndexAccess> xIndexAccess(xViewDataSupplier->getViewData()); + if (xIndexAccess.is() && xIndexAccess->getCount() > 0) + { + uno::Sequence< beans::PropertyValue > aSeq; + if (xIndexAccess->getByIndex(0) >>= aSeq) + { + sal_Int32 nCount (aSeq.getLength()); + for (sal_Int32 i = 0; i < nCount; ++i) + { + rtl::OUString sName(aSeq[i].Name); + if (sName.compareToAscii(SC_ACTIVETABLE) == 0) + { + rtl::OUString sValue; + if(aSeq[i].Value >>= sValue) + { + String sTabName(sValue); + SCTAB nTab(0); + if (pDoc->GetTable(sTabName, nTab)) + { + pDoc->SetVisibleTab(nTab); + i = nCount; + } + } + } + } + } + } + } + SetLabelRanges(); + SetNamedRanges(); + } + GetProgressBarHelper()->End(); // make room for subsequent SfxProgressBars + if (pDoc) + pDoc->CompileXML(); + + if (pDoc && GetModel().is()) + { + // set "valid stream" flags after loading (before UpdateRowHeights, so changed formula results + // in UpdateRowHeights can already clear the flags again) + ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetModel())->GetSheetSaveData(); + + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab=0; nTab<nTabCount; ++nTab) + if (!pSheetData->IsSheetBlocked( nTab )) + pDoc->SetStreamValid( nTab, sal_True ); + } + + aTables.UpdateRowHeights(); + aTables.ResizeShapes(); + } + if (GetModel().is()) + { + uno::Reference<document::XActionLockable> xActionLockable(GetModel(), uno::UNO_QUERY); + if (xActionLockable.is()) + xActionLockable->removeActionLock(); + } + SvXMLImport::endDocument(); + + if (pDoc && bSelfImportingXMLSet) + { + ScModelObj::getImplementation(GetModel())->AfterXMLLoading(sal_True); + } + + UnlockSolarMutex(); +} + +// XEventListener +void ScXMLImport::DisposingModel() +{ + SvXMLImport::DisposingModel(); + pDoc = NULL; +} + +void ScXMLImport::LockSolarMutex() +{ + // #i62677# When called from DocShell/Wrapper, the SolarMutex is already locked, + // so there's no need to allocate (and later delete) the ScUnoGuard. + if (bFromWrapper) + { + DBG_TESTSOLARMUTEX(); + return; + } + + if (nSolarMutexLocked == 0) + { + DBG_ASSERT(!pScUnoGuard, "Solar Mutex is locked"); + pScUnoGuard = new ScUnoGuard(); + } + ++nSolarMutexLocked; +} + + +void ScXMLImport::UnlockSolarMutex() +{ + if (nSolarMutexLocked > 0) + { + nSolarMutexLocked--; + if (nSolarMutexLocked == 0) + { + DBG_ASSERT(pScUnoGuard, "Solar Mutex is always unlocked"); + delete pScUnoGuard; + pScUnoGuard = NULL; + } + } +} + +sal_Int32 ScXMLImport::GetByteOffset() +{ + sal_Int32 nOffset = -1; + uno::Reference<xml::sax::XLocator> xLocator = GetLocator(); + uno::Reference<io::XSeekable> xSeek( xLocator, uno::UNO_QUERY ); //! should use different interface + if ( xSeek.is() ) + nOffset = (sal_Int32)xSeek->getPosition(); + return nOffset; +} + +void ScXMLImport::SetRangeOverflowType(sal_uInt32 nType) +{ + // #i31130# Overflow is stored in the document, because the ScXMLImport object + // isn't available in ScXMLImportWrapper::ImportFromComponent when using the + // OOo->Oasis transformation. + + if ( pDoc ) + pDoc->SetRangeOverflowType( nType ); +} + +void ScXMLImport::ProgressBarIncrement(sal_Bool bEditCell, sal_Int32 nInc) +{ + nProgressCount += nInc; + if (bEditCell || nProgressCount > 100) + { + GetProgressBarHelper()->Increment(nProgressCount); + nProgressCount = 0; + } +} + +sal_Int32 ScXMLImport::GetVisibleSheet() +{ + // Get the visible sheet number from model's view data (after settings were loaded), + // or 0 (default: first sheet) if no settings available. + + uno::Reference<document::XViewDataSupplier> xSupp(GetModel(), uno::UNO_QUERY); + if (xSupp.is()) + { + uno::Reference<container::XIndexAccess> xIndex = xSupp->getViewData(); + if ( xIndex.is() && xIndex->getCount() > 0 ) + { + uno::Any aAny( xIndex->getByIndex(0) ); + uno::Sequence<beans::PropertyValue> aViewSettings; // settings for (first) view + if ( aAny >>= aViewSettings ) + { + sal_Int32 nCount = aViewSettings.getLength(); + for (sal_Int32 i = 0; i < nCount; ++i) + { + if ( aViewSettings[i].Name.compareToAscii(SC_ACTIVETABLE) == 0 ) + { + rtl::OUString sValue; + if(aViewSettings[i].Value >>= sValue) + { + String sTabName(sValue); + SCTAB nTab = 0; + if (pDoc->GetTable(sTabName, nTab)) + return nTab; + } + } + } + } + } + } + + return 0; +} + +void ScXMLImport::ExtractFormulaNamespaceGrammar( + OUString& rFormula, OUString& rFormulaNmsp, FormulaGrammar::Grammar& reGrammar, + const OUString& rAttrValue, bool bRestrictToExternalNmsp ) const +{ + // parse the attribute value, extract namespace ID, literal namespace, and formula string + rFormulaNmsp = OUString(); + sal_uInt16 nNsId = GetNamespaceMap()._GetKeyByAttrName( rAttrValue, 0, &rFormula, &rFormulaNmsp, sal_False ); + + // check if we have an ODF formula namespace + if( !bRestrictToExternalNmsp ) switch( nNsId ) + { + case XML_NAMESPACE_OOOC: + rFormulaNmsp = OUString(); // remove namespace string for built-in grammar + reGrammar = FormulaGrammar::GRAM_PODF; + return; + case XML_NAMESPACE_OF: + rFormulaNmsp = OUString(); // remove namespace string for built-in grammar + reGrammar = FormulaGrammar::GRAM_ODFF; + return; + } + + /* Find default grammar for formulas without namespace. There may be + documents in the wild that stored no namespace in ODF 1.0/1.1. Use + GRAM_PODF then (old style ODF 1.0/1.1 formulas). The default for ODF + 1.2 and later without namespace is GRAM_ODFF (OpenFormula). */ + FormulaGrammar::Grammar eDefaultGrammar = + (GetDocument()->GetStorageGrammar() == FormulaGrammar::GRAM_PODF) ? + FormulaGrammar::GRAM_PODF : FormulaGrammar::GRAM_ODFF; + + /* Check if we have no namespace at all. The value XML_NAMESPACE_NONE + indicates that there is no colon. If the first character of the + attribute value is the equality sign, the value XML_NAMESPACE_UNKNOWN + indicates that there is a colon somewhere in the formula string. */ + if( (nNsId == XML_NAMESPACE_NONE) || ((nNsId == XML_NAMESPACE_UNKNOWN) && (rAttrValue.toChar() == '=')) ) + { + rFormula = rAttrValue; // return entire string as formula + reGrammar = eDefaultGrammar; + return; + } + + /* Check if a namespace URL could be resolved from the attribute value. + Use that namespace only, if the Calc document knows an associated + external formula parser. This prevents that the range operator in + conjunction with defined names is confused as namespaces prefix, e.g. + in the expression 'table:A1' where 'table' is a named reference. */ + if( ((nNsId & XML_NAMESPACE_UNKNOWN_FLAG) != 0) && (rFormulaNmsp.getLength() > 0) && + GetDocument()->GetFormulaParserPool().hasFormulaParser( rFormulaNmsp ) ) + { + reGrammar = FormulaGrammar::GRAM_EXTERNAL; + return; + } + + /* All attempts failed (e.g. no namespace and no leading equality sign, or + an invalid namespace prefix), continue with the entire attribute value. */ + rFormula = rAttrValue; + rFormulaNmsp = OUString(); // remove any namespace string + reGrammar = eDefaultGrammar; +} + diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx new file mode 100644 index 000000000000..d11a5bc0e76a --- /dev/null +++ b/sc/source/filter/xml/xmlimprt.hxx @@ -0,0 +1,1048 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLIMPRT_HXX +#define SC_XMLIMPRT_HXX + +#include <rsc/rscsfx.hxx> +#include <xmloff/xmlictxt.hxx> +#include <xmloff/xmlimp.hxx> +#include <xmloff/xmltkmap.hxx> +#include <xmloff/xmlaustp.hxx> +#include <xmloff/xmlstyle.hxx> +#include <com/sun/star/frame/XModel.hpp> +#include <tools/time.hxx> +#include <com/sun/star/util/DateTime.hpp> +#include "xmlsubti.hxx" +#include "global.hxx" +#include "formula/grammar.hxx" + +#include "xmlstyle.hxx" +#include "XMLDetectiveContext.hxx" +#include <com/sun/star/sheet/ValidationAlertStyle.hpp> +#include <com/sun/star/sheet/ValidationType.hpp> +#include <com/sun/star/sheet/ConditionOperator.hpp> +#include <com/sun/star/table/CellAddress.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/util/XNumberFormatTypes.hpp> +#include <com/sun/star/sheet/XSheetCellRangeContainer.hpp> + +#include <vector> +#include <hash_map> + +class ScRangeList; +class ScMyStyleNumberFormats; +class XMLNumberFormatAttributesExportHelper; + +enum ScXMLDocTokens +{ + XML_TOK_DOC_FONTDECLS, + XML_TOK_DOC_STYLES, + XML_TOK_DOC_AUTOSTYLES, + XML_TOK_DOC_MASTERSTYLES, + XML_TOK_DOC_META, + XML_TOK_DOC_SCRIPTS, + XML_TOK_DOC_BODY, + XML_TOK_DOC_SETTINGS, + XML_TOK_OFFICE_END=XML_TOK_UNKNOWN +}; + +enum ScXMLStylesTokens +{ + XML_TOK_STYLES_STYLE +}; + +enum ScXMLStylesAttrTokens +{ + XML_TOK_STYLES_STYLE_NAME, + XML_TOK_STYLES_STYLE_FAMILY, + XML_TOK_STYLES_STYLE_PARENT_STYLE_NAME +}; + +enum ScXMLStyleTokens +{ + XML_TOK_STYLE_PROPERTIES +}; + +enum ScXMLBodyTokens +{ + XML_TOK_BODY_TRACKED_CHANGES, + XML_TOK_BODY_CALCULATION_SETTINGS, + XML_TOK_BODY_CONTENT_VALIDATIONS, + XML_TOK_BODY_LABEL_RANGES, + XML_TOK_BODY_TABLE, + XML_TOK_BODY_NAMED_EXPRESSIONS, + XML_TOK_BODY_DATABASE_RANGES, + XML_TOK_BODY_DATABASE_RANGE, + XML_TOK_BODY_DATA_PILOT_TABLES, + XML_TOK_BODY_CONSOLIDATION, + XML_TOK_BODY_DDE_LINKS +}; + +enum ScXMLContentValidationsElemTokens +{ + XML_TOK_CONTENT_VALIDATION +}; + +enum ScXMLContentValidationElemTokens +{ + XML_TOK_CONTENT_VALIDATION_ELEM_HELP_MESSAGE, + XML_TOK_CONTENT_VALIDATION_ELEM_ERROR_MESSAGE, + XML_TOK_CONTENT_VALIDATION_ELEM_ERROR_MACRO, + XML_TOK_CONTENT_VALIDATION_ELEM_EVENT_LISTENERS +}; + +enum ScXMLContentValidationAttrTokens +{ + XML_TOK_CONTENT_VALIDATION_NAME, + XML_TOK_CONTENT_VALIDATION_CONDITION, + XML_TOK_CONTENT_VALIDATION_BASE_CELL_ADDRESS, + XML_TOK_CONTENT_VALIDATION_ALLOW_EMPTY_CELL, + XML_TOK_CONTENT_VALIDATION_DISPLAY_LIST +}; + +enum ScXMLContentValidationMessageElemTokens +{ + XML_TOK_P +}; + +enum ScXMLContentValidationHelpMessageAttrTokens +{ + XML_TOK_HELP_MESSAGE_ATTR_TITLE, + XML_TOK_HELP_MESSAGE_ATTR_DISPLAY +}; + +enum ScXMLContentValidationErrorMessageAttrTokens +{ + XML_TOK_ERROR_MESSAGE_ATTR_TITLE, + XML_TOK_ERROR_MESSAGE_ATTR_DISPLAY, + XML_TOK_ERROR_MESSAGE_ATTR_MESSAGE_TYPE +}; + +enum ScXMLContentValidationErrorMacroAttrTokens +{ + XML_TOK_ERROR_MACRO_ATTR_NAME, + XML_TOK_ERROR_MACRO_ATTR_EXECUTE +}; + +enum ScXMLLabelRangesElemTokens +{ + XML_TOK_LABEL_RANGE_ELEM +}; + +enum ScXMLLabelRangeAttrTokens +{ + XML_TOK_LABEL_RANGE_ATTR_LABEL_RANGE, + XML_TOK_LABEL_RANGE_ATTR_DATA_RANGE, + XML_TOK_LABEL_RANGE_ATTR_ORIENTATION +}; + +enum ScXMLTableTokens +{ + XML_TOK_TABLE_COL_GROUP, + XML_TOK_TABLE_HEADER_COLS, + XML_TOK_TABLE_COLS, + XML_TOK_TABLE_COL, + XML_TOK_TABLE_ROW_GROUP, + XML_TOK_TABLE_HEADER_ROWS, + XML_TOK_TABLE_ROWS, + XML_TOK_TABLE_ROW, + XML_TOK_TABLE_SOURCE, + XML_TOK_TABLE_SCENARIO, + XML_TOK_TABLE_SHAPES, + XML_TOK_TABLE_FORMS, + XML_TOK_TABLE_EVENT_LISTENERS, + XML_TOK_TABLE_EVENT_LISTENERS_EXT +}; + +enum ScXMLTableRowsTokens +{ + XML_TOK_TABLE_ROWS_ROW_GROUP, + XML_TOK_TABLE_ROWS_HEADER_ROWS, + XML_TOK_TABLE_ROWS_ROWS, + XML_TOK_TABLE_ROWS_ROW +}; + +enum ScXMLTableColsTokens +{ + XML_TOK_TABLE_COLS_COL_GROUP, + XML_TOK_TABLE_COLS_HEADER_COLS, + XML_TOK_TABLE_COLS_COLS, + XML_TOK_TABLE_COLS_COL +}; + +enum ScXMLTableAttrTokens +{ + XML_TOK_TABLE_NAME, + XML_TOK_TABLE_STYLE_NAME, + XML_TOK_TABLE_PROTECTION, + XML_TOK_TABLE_PRINT_RANGES, + XML_TOK_TABLE_PASSWORD, + XML_TOK_TABLE_PRINT +}; + +enum ScXMLTableScenarioAttrTokens +{ + XML_TOK_TABLE_SCENARIO_ATTR_DISPLAY_BORDER, + XML_TOK_TABLE_SCENARIO_ATTR_BORDER_COLOR, + XML_TOK_TABLE_SCENARIO_ATTR_COPY_BACK, + XML_TOK_TABLE_SCENARIO_ATTR_COPY_STYLES, + XML_TOK_TABLE_SCENARIO_ATTR_COPY_FORMULAS, + XML_TOK_TABLE_SCENARIO_ATTR_IS_ACTIVE, + XML_TOK_TABLE_SCENARIO_ATTR_SCENARIO_RANGES, + XML_TOK_TABLE_SCENARIO_ATTR_COMMENT, + XML_TOK_TABLE_SCENARIO_ATTR_PROTECTED +}; + +enum ScXMLTableColAttrTokens +{ + XML_TOK_TABLE_COL_ATTR_STYLE_NAME, + XML_TOK_TABLE_COL_ATTR_REPEATED, + XML_TOK_TABLE_COL_ATTR_VISIBILITY, + XML_TOK_TABLE_COL_ATTR_DEFAULT_CELL_STYLE_NAME +}; + +enum ScXMLTableRowTokens +{ + XML_TOK_TABLE_ROW_CELL, + XML_TOK_TABLE_ROW_COVERED_CELL +}; + +enum ScXMLTableRowAttrTokens +{ + XML_TOK_TABLE_ROW_ATTR_STYLE_NAME, + XML_TOK_TABLE_ROW_ATTR_VISIBILITY, + XML_TOK_TABLE_ROW_ATTR_REPEATED, + XML_TOK_TABLE_ROW_ATTR_DEFAULT_CELL_STYLE_NAME +// XML_TOK_TABLE_ROW_ATTR_USE_OPTIMAL_HEIGHT +}; + +enum ScXMLTableRowCellTokens +{ + XML_TOK_TABLE_ROW_CELL_P, + XML_TOK_TABLE_ROW_CELL_TABLE, + XML_TOK_TABLE_ROW_CELL_ANNOTATION, + XML_TOK_TABLE_ROW_CELL_DETECTIVE, + XML_TOK_TABLE_ROW_CELL_CELL_RANGE_SOURCE +}; + +enum ScXMLTableRowCellAttrTokens +{ + XML_TOK_TABLE_ROW_CELL_ATTR_STYLE_NAME, + XML_TOK_TABLE_ROW_CELL_ATTR_CONTENT_VALIDATION_NAME, + XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_ROWS, + XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_COLS, + XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_COLS, + XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_ROWS, + XML_TOK_TABLE_ROW_CELL_ATTR_REPEATED, + XML_TOK_TABLE_ROW_CELL_ATTR_VALUE_TYPE, + XML_TOK_TABLE_ROW_CELL_ATTR_VALUE, + XML_TOK_TABLE_ROW_CELL_ATTR_DATE_VALUE, + XML_TOK_TABLE_ROW_CELL_ATTR_TIME_VALUE, + XML_TOK_TABLE_ROW_CELL_ATTR_STRING_VALUE, + XML_TOK_TABLE_ROW_CELL_ATTR_BOOLEAN_VALUE, + XML_TOK_TABLE_ROW_CELL_ATTR_FORMULA, + XML_TOK_TABLE_ROW_CELL_ATTR_CURRENCY +}; + +enum ScXMLAnnotationAttrTokens +{ + XML_TOK_TABLE_ANNOTATION_ATTR_AUTHOR, + XML_TOK_TABLE_ANNOTATION_ATTR_CREATE_DATE, + XML_TOK_TABLE_ANNOTATION_ATTR_CREATE_DATE_STRING, + XML_TOK_TABLE_ANNOTATION_ATTR_DISPLAY, + XML_TOK_TABLE_ANNOTATION_ATTR_X, + XML_TOK_TABLE_ANNOTATION_ATTR_Y +}; + +enum ScXMLDetectiveElemTokens +{ + XML_TOK_DETECTIVE_ELEM_HIGHLIGHTED, + XML_TOK_DETECTIVE_ELEM_OPERATION +}; + +enum ScXMLDetectiveHighlightedAttrTokens +{ + XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_CELL_RANGE, + XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_DIRECTION, + XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_CONTAINS_ERROR, + XML_TOK_DETECTIVE_HIGHLIGHTED_ATTR_MARKED_INVALID +}; + +enum ScXMLDetectiveOperationAttrTokens +{ + XML_TOK_DETECTIVE_OPERATION_ATTR_NAME, + XML_TOK_DETECTIVE_OPERATION_ATTR_INDEX +}; + +enum ScXMLCellRangeSourceAttrTokens +{ + XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_NAME, + XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_HREF, + XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_FILTER_NAME, + XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_FILTER_OPTIONS, + XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_LAST_COLUMN, + XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_LAST_ROW, + XML_TOK_TABLE_CELL_RANGE_SOURCE_ATTR_REFRESH_DELAY +}; + +enum ScXMLNamedExpressionsTokens +{ + XML_TOK_NAMED_EXPRESSIONS_NAMED_RANGE, + XML_TOK_NAMED_EXPRESSIONS_NAMED_EXPRESSION +}; + +enum ScXMLNamedRangeAttrTokens +{ + XML_TOK_NAMED_RANGE_ATTR_NAME, + XML_TOK_NAMED_RANGE_ATTR_CELL_RANGE_ADDRESS, + XML_TOK_NAMED_RANGE_ATTR_BASE_CELL_ADDRESS, + XML_TOK_NAMED_RANGE_ATTR_RANGE_USABLE_AS +}; + +enum ScXMLNamedExpressionAttrTokens +{ + XML_TOK_NAMED_EXPRESSION_ATTR_NAME, + XML_TOK_NAMED_EXPRESSION_ATTR_BASE_CELL_ADDRESS, + XML_TOK_NAMED_EXPRESSION_ATTR_EXPRESSION +}; + +enum ScXMLDatabaseRangesTokens +{ + XML_TOK_DATABASE_RANGE +}; + +enum ScXMLDatabaseRangeTokens +{ + XML_TOK_DATABASE_RANGE_SOURCE_SQL, + XML_TOK_DATABASE_RANGE_SOURCE_TABLE, + XML_TOK_DATABASE_RANGE_SOURCE_QUERY, + XML_TOK_FILTER, + XML_TOK_SORT, + XML_TOK_DATABASE_RANGE_SUBTOTAL_RULES +}; + +enum ScXMLDatabaseRangeAttrTokens +{ + XML_TOK_DATABASE_RANGE_ATTR_NAME, + XML_TOK_DATABASE_RANGE_ATTR_IS_SELECTION, + XML_TOK_DATABASE_RANGE_ATTR_ON_UPDATE_KEEP_STYLES, + XML_TOK_DATABASE_RANGE_ATTR_ON_UPDATE_KEEP_SIZE, + XML_TOK_DATABASE_RANGE_ATTR_HAS_PERSISTENT_DATA, + XML_TOK_DATABASE_RANGE_ATTR_ORIENTATION, + XML_TOK_DATABASE_RANGE_ATTR_CONTAINS_HEADER, + XML_TOK_DATABASE_RANGE_ATTR_DISPLAY_FILTER_BUTTONS, + XML_TOK_DATABASE_RANGE_ATTR_TARGET_RANGE_ADDRESS, + XML_TOK_DATABASE_RANGE_ATTR_REFRESH_DELAY +}; + +enum ScXMLDatabaseRangeSourceSQLAttrTokens +{ + XML_TOK_SOURCE_SQL_ATTR_DATABASE_NAME, + XML_TOK_SOURCE_SQL_ATTR_HREF, + XML_TOK_SOURCE_SQL_ATTR_CONNECTION_RESSOURCE, + XML_TOK_SOURCE_SQL_ATTR_SQL_STATEMENT, + XML_TOK_SOURCE_SQL_ATTR_PARSE_SQL_STATEMENT +}; + +enum ScXMLDatabaseRangeSourceTableAttrTokens +{ + XML_TOK_SOURCE_TABLE_ATTR_DATABASE_NAME, + XML_TOK_SOURCE_TABLE_ATTR_HREF, + XML_TOK_SOURCE_TABLE_ATTR_CONNECTION_RESSOURCE, + XML_TOK_SOURCE_TABLE_ATTR_TABLE_NAME +}; + +enum ScXMLDatabaseRangeSourceQueryAttrTokens +{ + XML_TOK_SOURCE_QUERY_ATTR_DATABASE_NAME, + XML_TOK_SOURCE_QUERY_ATTR_HREF, + XML_TOK_SOURCE_QUERY_ATTR_CONNECTION_RESSOURCE, + XML_TOK_SOURCE_QUERY_ATTR_QUERY_NAME +}; + +enum ScXMLFilterTokens +{ + XML_TOK_FILTER_AND, + XML_TOK_FILTER_OR, + XML_TOK_FILTER_CONDITION +}; + +enum ScXMLFilterAttrTokens +{ + XML_TOK_FILTER_ATTR_TARGET_RANGE_ADDRESS, + XML_TOK_FILTER_ATTR_CONDITION_SOURCE_RANGE_ADDRESS, + XML_TOK_FILTER_ATTR_CONDITION_SOURCE, + XML_TOK_FILTER_ATTR_DISPLAY_DUPLICATES +}; + +enum ScXMLFilterConditionAttrTokens +{ + XML_TOK_CONDITION_ATTR_FIELD_NUMBER, + XML_TOK_CONDITION_ATTR_CASE_SENSITIVE, + XML_TOK_CONDITION_ATTR_DATA_TYPE, + XML_TOK_CONDITION_ATTR_VALUE, + XML_TOK_CONDITION_ATTR_OPERATOR +}; + +enum ScXMLSortTokens +{ + XML_TOK_SORT_SORT_BY +}; + +enum ScXMLSortAttrTokens +{ + XML_TOK_SORT_ATTR_BIND_STYLES_TO_CONTENT, + XML_TOK_SORT_ATTR_TARGET_RANGE_ADDRESS, + XML_TOK_SORT_ATTR_CASE_SENSITIVE, + XML_TOK_SORT_ATTR_LANGUAGE, + XML_TOK_SORT_ATTR_COUNTRY, + XML_TOK_SORT_ATTR_ALGORITHM +}; + +enum ScXMLSortSortByAttrTokens +{ + XML_TOK_SORT_BY_ATTR_FIELD_NUMBER, + XML_TOK_SORT_BY_ATTR_DATA_TYPE, + XML_TOK_SORT_BY_ATTR_ORDER +}; + +enum ScXMLDatabaseRangeSubTotalRulesTokens +{ + XML_TOK_SUBTOTAL_RULES_SORT_GROUPS, + XML_TOK_SUBTOTAL_RULES_SUBTOTAL_RULE +}; + +enum ScXMLDatabaseRangeSubTotalRulesAttrTokens +{ + XML_TOK_SUBTOTAL_RULES_ATTR_BIND_STYLES_TO_CONTENT, + XML_TOK_SUBTOTAL_RULES_ATTR_CASE_SENSITIVE, + XML_TOK_SUBTOTAL_RULES_ATTR_PAGE_BREAKS_ON_GROUP_CHANGE +}; + +enum ScXMLSubTotalRulesSortGroupsAttrTokens +{ + XML_TOK_SORT_GROUPS_ATTR_DATA_TYPE, + XML_TOK_SORT_GROUPS_ATTR_ORDER +}; + +enum ScXMLSubTotalRulesSubTotalRuleTokens +{ + XML_TOK_SUBTOTAL_RULE_SUBTOTAL_FIELD +}; + +enum ScXMLSubTotalRulesSubTotalRuleAttrTokens +{ + XML_TOK_SUBTOTAL_RULE_ATTR_GROUP_BY_FIELD_NUMBER +}; + +enum ScXMLSubTotalRuleSubTotalField +{ + XML_TOK_SUBTOTAL_FIELD_ATTR_FIELD_NUMBER, + XML_TOK_SUBTOTAL_FIELD_ATTR_FUNCTION +}; + +enum ScXMLDataPilotTablesElemTokens +{ + XML_TOK_DATA_PILOT_TABLE +}; + +enum ScXMLDataPilotTableAttrTokens +{ + XML_TOK_DATA_PILOT_TABLE_ATTR_NAME, + XML_TOK_DATA_PILOT_TABLE_ATTR_APPLICATION_DATA, + XML_TOK_DATA_PILOT_TABLE_ATTR_GRAND_TOTAL, + XML_TOK_DATA_PILOT_TABLE_ATTR_IGNORE_EMPTY_ROWS, + XML_TOK_DATA_PILOT_TABLE_ATTR_IDENTIFY_CATEGORIES, + XML_TOK_DATA_PILOT_TABLE_ATTR_TARGET_RANGE_ADDRESS, + XML_TOK_DATA_PILOT_TABLE_ATTR_BUTTONS, + XML_TOK_DATA_PILOT_TABLE_ATTR_SHOW_FILTER_BUTTON, + XML_TOK_DATA_PILOT_TABLE_ATTR_DRILL_DOWN +}; + +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, + XML_TOK_DATA_PILOT_TABLE_ELEM_DATA_PILOT_FIELD +}; + +enum ScXMLDataPilotTableSourceServiceAttrTokens +{ + XML_TOK_SOURCE_SERVICE_ATTR_NAME, + XML_TOK_SOURCE_SERVICE_ATTR_SOURCE_NAME, + XML_TOK_SOURCE_SERVICE_ATTR_OBJECT_NAME, + XML_TOK_SOURCE_SERVICE_ATTR_USER_NAME, + 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, + XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME_EXT +}; + +enum ScXMLDataPilotTableSourceCellRangeElemTokens +{ + XML_TOK_SOURCE_CELL_RANGE_ELEM_FILTER +}; + +enum ScXMLDataPilotTableSourceCellRangeAttrTokens +{ + XML_TOK_SOURCE_CELL_RANGE_ATTR_CELL_RANGE_ADDRESS +}; + +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_DISPLAY_NAME_EXT, + XML_TOK_DATA_PILOT_FIELD_ATTR_IS_DATA_LAYOUT_FIELD, + XML_TOK_DATA_PILOT_FIELD_ATTR_FUNCTION, + XML_TOK_DATA_PILOT_FIELD_ATTR_ORIENTATION, + XML_TOK_DATA_PILOT_FIELD_ATTR_SELECTED_PAGE, + XML_TOK_DATA_PILOT_FIELD_ATTR_USED_HIERARCHY +}; + +enum ScXMLDataPilotFieldElemTokens +{ + XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_LEVEL, + XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_REFERENCE, + XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_GROUPS +}; + +enum ScXMLDataPilotLevelAttrTokens +{ + XML_TOK_DATA_PILOT_LEVEL_ATTR_SHOW_EMPTY +}; + +enum ScXMLDataPilotLevelElemTokens +{ + XML_TOK_DATA_PILOT_LEVEL_ELEM_DATA_PILOT_SUBTOTALS, + XML_TOK_DATA_PILOT_LEVEL_ELEM_DATA_PILOT_MEMBERS, + XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_DISPLAY_INFO, + XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_SORT_INFO, + XML_TOK_DATA_PILOT_FIELD_ELEM_DATA_PILOT_LAYOUT_INFO +}; + +enum ScXMLDataPilotSubTotalsElemTokens +{ + XML_TOK_DATA_PILOT_SUBTOTALS_ELEM_DATA_PILOT_SUBTOTAL +}; + +enum ScXMLDataPilotSubTotalAttrTokens +{ + XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_FUNCTION, + XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME, + XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME_EXT +}; + +enum ScXMLDataPilotMembersElemTokens +{ + XML_TOK_DATA_PILOT_MEMBERS_ELEM_DATA_PILOT_MEMBER +}; + +enum ScXMLDataPilotMemberAttrTokens +{ + XML_TOK_DATA_PILOT_MEMBER_ATTR_NAME, + XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME, + XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME_EXT, + XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY, + XML_TOK_DATA_PILOT_MEMBER_ATTR_SHOW_DETAILS +}; + +enum ScXMLConsolidationAttrTokens +{ + XML_TOK_CONSOLIDATION_ATTR_FUNCTION, + XML_TOK_CONSOLIDATION_ATTR_SOURCE_RANGES, + XML_TOK_CONSOLIDATION_ATTR_TARGET_ADDRESS, + XML_TOK_CONSOLIDATION_ATTR_USE_LABEL, + XML_TOK_CONSOLIDATION_ATTR_LINK_TO_SOURCE +}; + + +class SvI18NMap; +class SvXMLTokenMap; +//class SvXMLImportItemMapper; +class SvXMLStyleContext; +class SfxItemSet; +class SvXMLNumFmtHelper; +class XMLShapeImportHelper; +class ScXMLChangeTrackingImportHelper; +class ScUnoGuard; + +struct tScMyCellRange +{ + sal_Int16 Sheet; + sal_Int32 StartColumn, EndColumn; + sal_Int32 StartRow, EndRow; +}; + +struct ScMyNamedExpression +{ + rtl::OUString sName; + rtl::OUString sContent; + rtl::OUString sContentNmsp; + rtl::OUString sBaseCellAddress; + rtl::OUString sRangeType; + formula::FormulaGrammar::Grammar eGrammar; + sal_Bool bIsExpression; +}; + +typedef std::list<const ScMyNamedExpression*> ScMyNamedExpressions; + +struct ScMyLabelRange +{ + rtl::OUString sLabelRangeStr; + rtl::OUString sDataRangeStr; + sal_Bool bColumnOrientation; +}; + +typedef std::list<const ScMyLabelRange*> ScMyLabelRanges; + +struct ScMyImportValidation +{ + rtl::OUString sName; + rtl::OUString sImputTitle; + rtl::OUString sImputMessage; + rtl::OUString sErrorTitle; + rtl::OUString sErrorMessage; + rtl::OUString sFormula1; + rtl::OUString sFormula2; + rtl::OUString sFormulaNmsp1; + rtl::OUString sFormulaNmsp2; + rtl::OUString sBaseCellAddress; // #b4974740# string is used directly + com::sun::star::sheet::ValidationAlertStyle aAlertStyle; + com::sun::star::sheet::ValidationType aValidationType; + com::sun::star::sheet::ConditionOperator aOperator; + formula::FormulaGrammar::Grammar eGrammar1; + formula::FormulaGrammar::Grammar eGrammar2; + sal_Int16 nShowList; + sal_Bool bShowErrorMessage; + sal_Bool bShowImputMessage; + sal_Bool bIgnoreBlanks; +}; + +typedef std::vector<ScMyImportValidation> ScMyImportValidations; +typedef std::list<SvXMLImportContext*> ScMyViewContextList; +class ScMyStylesImportHelper; + +class ScXMLImport: public SvXMLImport +{ + typedef ::std::hash_map< ::rtl::OUString, sal_Int16, ::rtl::OUStringHash > CellTypeMap; + CellTypeMap aCellTypeMap; + + ScDocument* pDoc; + ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper; + ScMyViewContextList aViewContextList; + ScMyStylesImportHelper* pStylesImportHelper; + rtl::OUString sNumberFormat; + rtl::OUString sLocale; + rtl::OUString sCellStyle; + rtl::OUString sStandardFormat; + rtl::OUString sType; + +// SvXMLAutoStylePoolP *pScAutoStylePool; + UniReference < XMLPropertyHandlerFactory > xScPropHdlFactory; + UniReference < XMLPropertySetMapper > xCellStylesPropertySetMapper; + UniReference < XMLPropertySetMapper > xColumnStylesPropertySetMapper; + UniReference < XMLPropertySetMapper > xRowStylesPropertySetMapper; + UniReference < XMLPropertySetMapper > xTableStylesPropertySetMapper; +// SvXMLImportContextRef xStyles; +// SvXMLImportContextRef xAutoStyles; + +// SvXMLImportItemMapper *pParaItemMapper;// paragraph item import +// SvI18NMap *pI18NMap; // name mapping for I18N + SvXMLTokenMap *pDocElemTokenMap; + SvXMLTokenMap *pStylesElemTokenMap; + SvXMLTokenMap *pStylesAttrTokenMap; + SvXMLTokenMap *pStyleElemTokenMap; + SvXMLTokenMap *pBodyElemTokenMap; + SvXMLTokenMap *pContentValidationsElemTokenMap; + SvXMLTokenMap *pContentValidationElemTokenMap; + SvXMLTokenMap *pContentValidationAttrTokenMap; + SvXMLTokenMap *pContentValidationMessageElemTokenMap; + SvXMLTokenMap *pContentValidationHelpMessageAttrTokenMap; + SvXMLTokenMap *pContentValidationErrorMessageAttrTokenMap; + SvXMLTokenMap *pContentValidationErrorMacroAttrTokenMap; + SvXMLTokenMap *pLabelRangesElemTokenMap; + SvXMLTokenMap *pLabelRangeAttrTokenMap; + SvXMLTokenMap *pTableElemTokenMap; + SvXMLTokenMap *pTableRowsElemTokenMap; + SvXMLTokenMap *pTableColsElemTokenMap; + SvXMLTokenMap *pTableScenarioAttrTokenMap; + SvXMLTokenMap *pTableAttrTokenMap; + SvXMLTokenMap *pTableColAttrTokenMap; + SvXMLTokenMap *pTableRowElemTokenMap; + SvXMLTokenMap *pTableRowAttrTokenMap; + SvXMLTokenMap *pTableRowCellElemTokenMap; + SvXMLTokenMap *pTableRowCellAttrTokenMap; + SvXMLTokenMap *pTableAnnotationAttrTokenMap; + SvXMLTokenMap *pDetectiveElemTokenMap; + SvXMLTokenMap *pDetectiveHighlightedAttrTokenMap; + SvXMLTokenMap *pDetectiveOperationAttrTokenMap; + SvXMLTokenMap *pTableCellRangeSourceAttrTokenMap; + SvXMLTokenMap *pNamedExpressionsElemTokenMap; + SvXMLTokenMap *pNamedRangeAttrTokenMap; + SvXMLTokenMap *pNamedExpressionAttrTokenMap; + SvXMLTokenMap *pDatabaseRangesElemTokenMap; + SvXMLTokenMap *pDatabaseRangeElemTokenMap; + SvXMLTokenMap *pDatabaseRangeAttrTokenMap; + SvXMLTokenMap *pDatabaseRangeSourceSQLAttrTokenMap; + SvXMLTokenMap *pDatabaseRangeSourceTableAttrTokenMap; + SvXMLTokenMap *pDatabaseRangeSourceQueryAttrTokenMap; + SvXMLTokenMap *pFilterElemTokenMap; + SvXMLTokenMap *pFilterAttrTokenMap; + SvXMLTokenMap *pFilterConditionAttrTokenMap; + SvXMLTokenMap *pSortElemTokenMap; + SvXMLTokenMap *pSortAttrTokenMap; + SvXMLTokenMap *pSortSortByAttrTokenMap; + SvXMLTokenMap *pDatabaseRangeSubTotalRulesElemTokenMap; + SvXMLTokenMap *pDatabaseRangeSubTotalRulesAttrTokenMap; + SvXMLTokenMap *pSubTotalRulesSortGroupsAttrTokenMap; + SvXMLTokenMap *pSubTotalRulesSubTotalRuleElemTokenMap; + SvXMLTokenMap *pSubTotalRulesSubTotalRuleAttrTokenMap; + SvXMLTokenMap *pSubTotalRuleSubTotalFieldAttrTokenMap; + SvXMLTokenMap *pDataPilotTablesElemTokenMap; + SvXMLTokenMap *pDataPilotTableAttrTokenMap; + SvXMLTokenMap *pDataPilotTableElemTokenMap; + SvXMLTokenMap *pDataPilotTableSourceServiceAttrTokenMap; + SvXMLTokenMap *pDataPilotGrandTotalAttrTokenMap; + SvXMLTokenMap *pDataPilotTableSourceCellRangeElemTokenMap; + SvXMLTokenMap *pDataPilotTableSourceCellRangeAttrTokenMap; + SvXMLTokenMap *pDataPilotFieldAttrTokenMap; + SvXMLTokenMap *pDataPilotFieldElemTokenMap; + SvXMLTokenMap *pDataPilotLevelAttrTokenMap; + SvXMLTokenMap *pDataPilotLevelElemTokenMap; + SvXMLTokenMap *pDataPilotSubTotalsElemTokenMap; + SvXMLTokenMap *pDataPilotSubTotalAttrTokenMap; + SvXMLTokenMap *pDataPilotMembersElemTokenMap; + SvXMLTokenMap *pDataPilotMemberAttrTokenMap; + SvXMLTokenMap *pConsolidationAttrTokenMap; + + ScMyTables aTables; + + ScMyNamedExpressions* pMyNamedExpressions; + ScMyLabelRanges* pMyLabelRanges; + ScMyImportValidations* pValidations; + ScMyImpDetectiveOpArray* pDetectiveOpArray; + ScUnoGuard* pScUnoGuard; + + std::vector<rtl::OUString> aTableStyles; + XMLNumberFormatAttributesExportHelper* pNumberFormatAttributesExportHelper; + ScMyStyleNumberFormats* pStyleNumberFormats; + com::sun::star::uno::Reference <com::sun::star::util::XNumberFormats> xNumberFormats; + com::sun::star::uno::Reference <com::sun::star::util::XNumberFormatTypes> xNumberFormatTypes; + + com::sun::star::uno::Reference <com::sun::star::sheet::XSheetCellRangeContainer> xSheetCellRanges; + + rtl::OUString sEmpty; + rtl::OUString sPrevStyleName; + rtl::OUString sPrevCurrency; + sal_uInt32 nSolarMutexLocked; + sal_Int32 nProgressCount; + sal_uInt16 nStyleFamilyMask;// Mask of styles to load + sal_Int16 nPrevCellType; + sal_Bool bLoadDoc; // Load doc or styles only + sal_Bool bRemoveLastChar; + sal_Bool bNullDateSetted; + sal_Bool bSelfImportingXMLSet; + sal_Bool bLatinDefaultStyle; // latin-only number format in default style? + sal_Bool bFromWrapper; // called from ScDocShell / ScXMLImportWrapper? + + +protected: + + // This method is called after the namespace map has been updated, but + // before a context for the current element has been pushed. + virtual SvXMLImportContext *CreateContext(sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + virtual XMLShapeImportHelper* CreateShapeImport(); + +public: + // #110680# + ScXMLImport( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory, + const sal_uInt16 nImportFlag); + + ~ScXMLImport() throw(); + + // namespace office + // NB: in contrast to other CreateFooContexts, this particular one handles + // the root element (i.e. office:document-meta) + SvXMLImportContext *CreateMetaContext( + const ::rtl::OUString& rLocalName ); + SvXMLImportContext *CreateFontDeclsContext(const sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, + const com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList); + SvXMLImportContext *CreateScriptContext( + const ::rtl::OUString& rLocalName ); + SvXMLImportContext *CreateStylesContext(const ::rtl::OUString& rLocalName, + const com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList, sal_Bool bAutoStyles ); +// SvXMLImportContext *CreateUseStylesContext(const ::rtl::OUString& rLocalName , +// const ::com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList); + SvXMLImportContext *CreateBodyContext( + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void SetStatistics( + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue> & i_rStats); + + inline ScDocument* GetDocument() { return pDoc; } + inline const ScDocument* GetDocument() const { return pDoc; } + + ScMyTables& GetTables() { return aTables; } + + sal_uInt16 GetStyleFamilyMask() const { return nStyleFamilyMask; } + sal_Bool IsStylesOnlyMode() const { return !bLoadDoc; } + + sal_Bool IsLatinDefaultStyle() const { return bLatinDefaultStyle; } + + sal_Int16 GetCellType(const ::rtl::OUString& rStrValue) const; + +// SvI18NMap& GetI18NMap() { return *pI18NMap; } + +// inline const SvXMLImportItemMapper& GetParaItemMapper() const; +// SvXMLImportContext *CreateParaItemImportContext( sal_uInt16 nPrefix, +// const ::rtl::OUString& rLocalName, +// const ::com::sun::star::uno::Reference< +// ::com::sun::star::xml::sax::XAttributeList& xAttrList, +// SfxItemSet& rItemSet ); + + UniReference < XMLPropertySetMapper > GetCellStylesPropertySetMapper() const { return xCellStylesPropertySetMapper; } + UniReference < XMLPropertySetMapper > GetColumnStylesPropertySetMapper() const { return xColumnStylesPropertySetMapper; } + UniReference < XMLPropertySetMapper > GetRowStylesPropertySetMapper() const { return xRowStylesPropertySetMapper; } + UniReference < XMLPropertySetMapper > GetTableStylesPropertySetMapper() const { return xTableStylesPropertySetMapper; } +// SvXMLImportContextRef GetAutoStyles() const { return xAutoStyles; } +// SvXMLImportContextRef GetStyles() const { return xStyles; } + + const SvXMLTokenMap& GetDocElemTokenMap(); +//UNUSED2008-05 const SvXMLTokenMap& GetStylesElemTokenMap(); +//UNUSED2008-05 const SvXMLTokenMap& GetStylesAttrTokenMap(); +//UNUSED2008-05 const SvXMLTokenMap& GetStyleElemTokenMap(); + const SvXMLTokenMap& GetBodyElemTokenMap(); + const SvXMLTokenMap& GetContentValidationsElemTokenMap(); + const SvXMLTokenMap& GetContentValidationElemTokenMap(); + const SvXMLTokenMap& GetContentValidationAttrTokenMap(); + const SvXMLTokenMap& GetContentValidationMessageElemTokenMap(); + const SvXMLTokenMap& GetContentValidationHelpMessageAttrTokenMap(); + const SvXMLTokenMap& GetContentValidationErrorMessageAttrTokenMap(); + const SvXMLTokenMap& GetContentValidationErrorMacroAttrTokenMap(); + const SvXMLTokenMap& GetLabelRangesElemTokenMap(); + const SvXMLTokenMap& GetLabelRangeAttrTokenMap(); + const SvXMLTokenMap& GetTableElemTokenMap(); + const SvXMLTokenMap& GetTableRowsElemTokenMap(); + const SvXMLTokenMap& GetTableColsElemTokenMap(); + const SvXMLTokenMap& GetTableAttrTokenMap(); + const SvXMLTokenMap& GetTableScenarioAttrTokenMap(); + const SvXMLTokenMap& GetTableColAttrTokenMap(); + const SvXMLTokenMap& GetTableRowElemTokenMap(); + const SvXMLTokenMap& GetTableRowAttrTokenMap(); + const SvXMLTokenMap& GetTableRowCellElemTokenMap(); + const SvXMLTokenMap& GetTableRowCellAttrTokenMap(); + const SvXMLTokenMap& GetTableAnnotationAttrTokenMap(); + const SvXMLTokenMap& GetDetectiveElemTokenMap(); + const SvXMLTokenMap& GetDetectiveHighlightedAttrTokenMap(); + const SvXMLTokenMap& GetDetectiveOperationAttrTokenMap(); + const SvXMLTokenMap& GetTableCellRangeSourceAttrTokenMap(); + const SvXMLTokenMap& GetNamedExpressionsElemTokenMap(); + const SvXMLTokenMap& GetNamedRangeAttrTokenMap(); + const SvXMLTokenMap& GetNamedExpressionAttrTokenMap(); + const SvXMLTokenMap& GetDatabaseRangesElemTokenMap(); + const SvXMLTokenMap& GetDatabaseRangeElemTokenMap(); + const SvXMLTokenMap& GetDatabaseRangeAttrTokenMap(); + const SvXMLTokenMap& GetDatabaseRangeSourceSQLAttrTokenMap(); + const SvXMLTokenMap& GetDatabaseRangeSourceTableAttrTokenMap(); + const SvXMLTokenMap& GetDatabaseRangeSourceQueryAttrTokenMap(); + const SvXMLTokenMap& GetFilterElemTokenMap(); + const SvXMLTokenMap& GetFilterAttrTokenMap(); + const SvXMLTokenMap& GetFilterConditionAttrTokenMap(); + const SvXMLTokenMap& GetSortElemTokenMap(); + const SvXMLTokenMap& GetSortAttrTokenMap(); + const SvXMLTokenMap& GetSortSortByAttrTokenMap(); + const SvXMLTokenMap& GetDatabaseRangeSubTotalRulesElemTokenMap(); + const SvXMLTokenMap& GetDatabaseRangeSubTotalRulesAttrTokenMap(); + const SvXMLTokenMap& GetSubTotalRulesSortGroupsAttrTokenMap(); + const SvXMLTokenMap& GetSubTotalRulesSubTotalRuleElemTokenMap(); + const SvXMLTokenMap& GetSubTotalRulesSubTotalRuleAttrTokenMap(); + const SvXMLTokenMap& GetSubTotalRuleSubTotalFieldAttrTokenMap(); + const SvXMLTokenMap& GetDataPilotTablesElemTokenMap(); + const SvXMLTokenMap& GetDataPilotTableAttrTokenMap(); + const SvXMLTokenMap& GetDataPilotTableElemTokenMap(); + const SvXMLTokenMap& GetDataPilotTableSourceServiceAttrTokenMap(); + const SvXMLTokenMap& GetDataPilotGrandTotalAttrTokenMap(); + const SvXMLTokenMap& GetDataPilotTableSourceCellRangeElemTokenMap(); + const SvXMLTokenMap& GetDataPilotTableSourceCellRangeAttrTokenMap(); + const SvXMLTokenMap& GetDataPilotFieldAttrTokenMap(); + const SvXMLTokenMap& GetDataPilotFieldElemTokenMap(); + const SvXMLTokenMap& GetDataPilotLevelAttrTokenMap(); + const SvXMLTokenMap& GetDataPilotLevelElemTokenMap(); + const SvXMLTokenMap& GetDataPilotSubTotalsElemTokenMap(); + const SvXMLTokenMap& GetDataPilotSubTotalAttrTokenMap(); + const SvXMLTokenMap& GetDataPilotMembersElemTokenMap(); + const SvXMLTokenMap& GetDataPilotMemberAttrTokenMap(); + const SvXMLTokenMap& GetConsolidationAttrTokenMap(); +// const SvXMLTokenMap& GetTextPElemTokenMap(); +// const SvXMLTokenMap& GetTextPAttrTokenMap(); +// const SvXMLTokenMap& GetStyleStylesElemTokenMap(); +// const SvXMLTokenMap& GetTextListBlockAttrTokenMap(); +// const SvXMLTokenMap& GetTextListBlockElemTokenMap(); + + void AddNamedExpression(const ScMyNamedExpression* pMyNamedExpression) { + if (!pMyNamedExpressions) + pMyNamedExpressions = new ScMyNamedExpressions(); + pMyNamedExpressions->push_back(pMyNamedExpression); } + ScMyNamedExpressions* GetNamedExpressions() { return pMyNamedExpressions; } + + void AddLabelRange(const ScMyLabelRange* pMyLabelRange) { + if (!pMyLabelRanges) + pMyLabelRanges = new ScMyLabelRanges(); + pMyLabelRanges->push_back(pMyLabelRange); } + ScMyLabelRanges* GetLabelRanges() { return pMyLabelRanges; } + + void AddValidation(const ScMyImportValidation& rValidation) { + if (!pValidations) + pValidations = new ScMyImportValidations(); + pValidations->push_back(rValidation); } + sal_Bool GetValidation(const rtl::OUString& sName, ScMyImportValidation& aValidation); + + inline ScMyImpDetectiveOpArray* GetDetectiveOpArray() { + if (!pDetectiveOpArray) + pDetectiveOpArray = new ScMyImpDetectiveOpArray(); + return pDetectiveOpArray; } + + void SetRemoveLastChar(sal_Bool bValue) { bRemoveLastChar = bValue; } + sal_Bool GetRemoveLastChar() { return bRemoveLastChar; } + + ScXMLChangeTrackingImportHelper* GetChangeTrackingImportHelper(); + void AddViewContext(SvXMLImportContext* pContext) { aViewContextList.push_back(pContext); } + void InsertStyles(); + + void SetChangeTrackingViewSettings(const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& rChangeProps); + virtual void SetViewSettings(const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aViewProps); + virtual void SetConfigurationSettings(const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aConfigProps); + + void SetTableStyle(const rtl::OUString& rValue) { aTableStyles.push_back(rValue); } + std::vector<rtl::OUString> GetTableStyle() { return aTableStyles; } + ScMyStylesImportHelper* GetStylesImportHelper() { return pStylesImportHelper; } + sal_Int32 SetCurrencySymbol(const sal_Int32 nKey, const rtl::OUString& rCurrency); + sal_Bool IsCurrencySymbol(const sal_Int32 nNumberFormat, const rtl::OUString& sCurrencySymbol, const rtl::OUString& sBankSymbol); + void SetType(com::sun::star::uno::Reference <com::sun::star::beans::XPropertySet>& rProperties, + sal_Int32& rNumberFormat, + const sal_Int16 nCellType, + const rtl::OUString& rCurrency); + + void ProgressBarIncrement(sal_Bool bEditCell, sal_Int32 nInc = 1); + +private: + void AddStyleRange(const com::sun::star::table::CellRangeAddress& rCellRange); + void SetStyleToRanges(); + + void ExamineDefaultStyle(); +public: + void SetStyleToRange(const ScRange& rRange, const rtl::OUString* pStyleName, + const sal_Int16 nCellType, const rtl::OUString* pCurrency); + sal_Bool SetNullDateOnUnitConverter(); + XMLNumberFormatAttributesExportHelper* GetNumberFormatAttributesExportHelper(); + ScMyStyleNumberFormats* GetStyleNumberFormats(); + + void SetStylesToRangesFinished(); + + // XImporter + virtual void SAL_CALL setTargetDocument( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& xDoc ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::xml::sax::XDocumentHandler + virtual void SAL_CALL startDocument(void) + throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL endDocument(void) + throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException ); + + virtual void DisposingModel(); + + void LockSolarMutex(); + void UnlockSolarMutex(); + + sal_Int32 GetByteOffset(); + + void SetRangeOverflowType(sal_uInt32 nType); + + sal_Int32 GetRangeType(const rtl::OUString sRangeType) const; + void SetNamedRanges(); + void SetLabelRanges(); + void AddDefaultNote( const com::sun::star::table::CellAddress& aCell ); + + sal_Int32 GetVisibleSheet(); + /** Extracts the formula string, the formula grammar namespace URL, and a + grammar enum value from the passed formula attribute value. + + @param rFormula + (out-parameter) Returns the plain formula string with the leading + equality sign if existing. + + @param rFormulaNmsp + (out-parameter) Returns the URL of the formula grammar namespace if + the attribute value contains the prefix of an unknown namespace. + + @param reGrammar + (out-parameter) Returns the exact formula grammar if the formula + is in a supported ODF format (e.g. FormulaGrammar::GRAM_PODF for + ODF 1.0/1.1 formulas, or FormulaGrammar::GRAM_ODFF for ODF 1.2 + formulas a.k.a. OpenFormula). Returns the default storage grammar, + if the attribute value does not contain a namespace prefix. Returns + the special value FormulaGrammar::GRAM_EXTERNAL, if an unknown + namespace could be extracted from the formula which will be + contained in the parameter rFormulaNmsp then. + + @param rAttrValue + The value of the processed formula attribute. + + @param bRestrictToExternalNmsp + If set to sal_True, only namespaces of external formula grammars will + be recognized. Internal namespace prefixes (e.g. 'oooc:' or 'of:' + will be considered to be part of the formula, e.g. an expression + with range operator. + */ + void ExtractFormulaNamespaceGrammar( + ::rtl::OUString& rFormula, + ::rtl::OUString& rFormulaNmsp, + ::formula::FormulaGrammar::Grammar& reGrammar, + const ::rtl::OUString& rAttrValue, + bool bRestrictToExternalNmsp = false ) const; +}; + +#endif + diff --git a/sc/source/filter/xml/xmllabri.cxx b/sc/source/filter/xml/xmllabri.cxx new file mode 100644 index 000000000000..6c1c2cb55508 --- /dev/null +++ b/sc/source/filter/xml/xmllabri.cxx @@ -0,0 +1,145 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + +//___________________________________________________________________ +#include "xmllabri.hxx" +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmltoken.hxx> +#include "xmlimprt.hxx" + +using namespace ::com::sun::star; +using ::rtl::OUString; +using namespace xmloff::token; + + +//___________________________________________________________________ + +ScXMLLabelRangesContext::ScXMLLabelRangesContext( + ScXMLImport& rImport, + sal_uInt16 nPrefix, + const OUString& rLName, + const uno::Reference< xml::sax::XAttributeList >& /* xAttrList */ ): + SvXMLImportContext( rImport, nPrefix, rLName ) +{ + rImport.LockSolarMutex(); +} + +ScXMLLabelRangesContext::~ScXMLLabelRangesContext() +{ + GetScImport().UnlockSolarMutex(); +} + +SvXMLImportContext* ScXMLLabelRangesContext::CreateChildContext( + sal_uInt16 nPrefix, + const OUString& rLName, + const uno::Reference< xml::sax::XAttributeList >& xAttrList ) +{ + SvXMLImportContext* pContext(NULL); + const SvXMLTokenMap& rTokenMap(GetScImport().GetLabelRangesElemTokenMap()); + + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_LABEL_RANGE_ELEM: + pContext = new ScXMLLabelRangeContext( GetScImport(), nPrefix, rLName, xAttrList ); + break; + } + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLLabelRangesContext::EndElement() +{ +} + + +//___________________________________________________________________ + +ScXMLLabelRangeContext::ScXMLLabelRangeContext( + ScXMLImport& rImport, + sal_uInt16 nPrfx, + const OUString& rLName, + const uno::Reference< xml::sax::XAttributeList >& xAttrList ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + bColumnOrientation( sal_False ) +{ + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetLabelRangeAttrTokenMap()); + + for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex ) + { + const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex )); + const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex )); + OUString aLocalName; + sal_uInt16 nPrefix (GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_LABEL_RANGE_ATTR_LABEL_RANGE: + sLabelRangeStr = sValue; + break; + case XML_TOK_LABEL_RANGE_ATTR_DATA_RANGE: + sDataRangeStr = sValue; + break; + case XML_TOK_LABEL_RANGE_ATTR_ORIENTATION: + bColumnOrientation = IsXMLToken(sValue, XML_COLUMN ); + break; + } + } +} + +ScXMLLabelRangeContext::~ScXMLLabelRangeContext() +{ +} + +SvXMLImportContext* ScXMLLabelRangeContext::CreateChildContext( + sal_uInt16 nPrefix, + const OUString& rLName, + const uno::Reference< xml::sax::XAttributeList >& /* xAttrList */ ) +{ + return new SvXMLImportContext( GetImport(), nPrefix, rLName ); +} + +void ScXMLLabelRangeContext::EndElement() +{ + // #b5071088# Label ranges must be stored as strings until all sheets are loaded + // (like named expressions). + + ScMyLabelRange* pLabelRange = new ScMyLabelRange; + + pLabelRange->sLabelRangeStr = sLabelRangeStr; + pLabelRange->sDataRangeStr = sDataRangeStr; + pLabelRange->bColumnOrientation = bColumnOrientation; + + GetScImport().AddLabelRange(pLabelRange); +} + diff --git a/sc/source/filter/xml/xmllabri.hxx b/sc/source/filter/xml/xmllabri.hxx new file mode 100644 index 000000000000..9d7bbff1aa18 --- /dev/null +++ b/sc/source/filter/xml/xmllabri.hxx @@ -0,0 +1,90 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef SC_XMLLABRI_HXX +#define SC_XMLLABRI_HXX + +#include <xmloff/xmlictxt.hxx> + +class ScXMLImport; + + +//___________________________________________________________________ + +class ScXMLLabelRangesContext : public SvXMLImportContext +{ +private: + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLLabelRangesContext( + ScXMLImport& rImport, + sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList>& xAttrList + ); + virtual ~ScXMLLabelRangesContext(); + + virtual SvXMLImportContext* CreateChildContext( + sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList>& xAttrList + ); + virtual void EndElement(); +}; + + +//___________________________________________________________________ + +class ScXMLLabelRangeContext : public SvXMLImportContext +{ +private: + ::rtl::OUString sLabelRangeStr; + ::rtl::OUString sDataRangeStr; + sal_Bool bColumnOrientation; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScXMLLabelRangeContext( + ScXMLImport& rImport, + sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList>& xAttrList + ); + virtual ~ScXMLLabelRangeContext(); + + virtual SvXMLImportContext* CreateChildContext( + sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList>& xAttrList + ); + virtual void EndElement(); +}; + +#endif diff --git a/sc/source/filter/xml/xmlnexpi.cxx b/sc/source/filter/xml/xmlnexpi.cxx new file mode 100644 index 000000000000..13f7e4090a58 --- /dev/null +++ b/sc/source/filter/xml/xmlnexpi.cxx @@ -0,0 +1,250 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- +#include <rtl/ustrbuf.hxx> + +#include "xmlnexpi.hxx" +#include "xmlimprt.hxx" +#include "xmlcelli.hxx" +#include "docuno.hxx" +#include "global.hxx" +#include "document.hxx" +#include "XMLConverter.hxx" + +#include <xmloff/xmltkmap.hxx> +#include <xmloff/nmspmap.hxx> + +using namespace com::sun::star; + +//------------------------------------------------------------------ + +ScXMLNamedExpressionsContext::ScXMLNamedExpressionsContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) : + SvXMLImportContext( rImport, nPrfx, rLName ) +{ +/* sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName ); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetNamedRangeAttrTokenMap(); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + } + }*/ + rImport.LockSolarMutex(); +} + +ScXMLNamedExpressionsContext::~ScXMLNamedExpressionsContext() +{ + GetScImport().UnlockSolarMutex(); +} + +SvXMLImportContext *ScXMLNamedExpressionsContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + const SvXMLTokenMap& rTokenMap(GetScImport().GetNamedExpressionsElemTokenMap()); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_NAMED_EXPRESSIONS_NAMED_RANGE: + pContext = new ScXMLNamedRangeContext( GetScImport(), nPrefix, + rLName, xAttrList//, + //this + ); + break; + case XML_TOK_NAMED_EXPRESSIONS_NAMED_EXPRESSION: + pContext = new ScXMLNamedExpressionContext( GetScImport(), nPrefix, + rLName, xAttrList//, + //this + ); + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLNamedExpressionsContext::EndElement() +{ + // happends in ScXMLImport::EndDocument() + // because it has to be set after the Database Ranges +} + +ScXMLNamedRangeContext::ScXMLNamedRangeContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList) : + SvXMLImportContext( rImport, nPrfx, rLName ) +{ + ScMyNamedExpression* pNamedExpression(new ScMyNamedExpression); + // A simple table:cell-range-address is not a formula expression, stored + // without [] brackets but with dot, .A1 + pNamedExpression->eGrammar = formula::FormulaGrammar::mergeToGrammar( + GetScImport().GetDocument()->GetStorageGrammar(), + formula::FormulaGrammar::CONV_OOO); + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetNamedRangeAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_NAMED_RANGE_ATTR_NAME : + { + pNamedExpression->sName = sValue; + } + break; + case XML_TOK_NAMED_RANGE_ATTR_CELL_RANGE_ADDRESS : + { + pNamedExpression->sContent = sValue; + } + break; + case XML_TOK_NAMED_RANGE_ATTR_BASE_CELL_ADDRESS : + { + pNamedExpression->sBaseCellAddress = sValue; + } + break; + case XML_TOK_NAMED_RANGE_ATTR_RANGE_USABLE_AS : + { + pNamedExpression->sRangeType = sValue; + } + break; + } + } + pNamedExpression->bIsExpression = sal_False; + GetScImport().AddNamedExpression(pNamedExpression); +} + +ScXMLNamedRangeContext::~ScXMLNamedRangeContext() +{ +} + +SvXMLImportContext *ScXMLNamedRangeContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ +/* const SvXMLTokenMap& rTokenMap = GetScImport().GetTableElemTokenMap(); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + }*/ + return new SvXMLImportContext( GetImport(), nPrefix, rLName ); +} + +void ScXMLNamedRangeContext::EndElement() +{ +} + +ScXMLNamedExpressionContext::ScXMLNamedExpressionContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList) : + SvXMLImportContext( rImport, nPrfx, rLName ) +{ + ScMyNamedExpression* pNamedExpression(new ScMyNamedExpression); + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetNamedExpressionAttrTokenMap()); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_NAMED_EXPRESSION_ATTR_NAME : + { + pNamedExpression->sName = sValue; + } + break; + case XML_TOK_NAMED_EXPRESSION_ATTR_EXPRESSION : + { + GetScImport().ExtractFormulaNamespaceGrammar( + pNamedExpression->sContent, pNamedExpression->sContentNmsp, + pNamedExpression->eGrammar, sValue ); + } + break; + case XML_TOK_NAMED_EXPRESSION_ATTR_BASE_CELL_ADDRESS : + { + pNamedExpression->sBaseCellAddress = sValue; + } + break; + } + } + pNamedExpression->bIsExpression = sal_True; + GetScImport().AddNamedExpression(pNamedExpression); +} + +ScXMLNamedExpressionContext::~ScXMLNamedExpressionContext() +{ +} + +SvXMLImportContext *ScXMLNamedExpressionContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ +/* const SvXMLTokenMap& rTokenMap = GetScImport().GetTableElemTokenMap(); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + }*/ + return new SvXMLImportContext( GetImport(), nPrefix, rLName );; +} + +void ScXMLNamedExpressionContext::EndElement() +{ +} + diff --git a/sc/source/filter/xml/xmlnexpi.hxx b/sc/source/filter/xml/xmlnexpi.hxx new file mode 100644 index 000000000000..251407920bd9 --- /dev/null +++ b/sc/source/filter/xml/xmlnexpi.hxx @@ -0,0 +1,101 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef SC_XMLNEXPI_HXX +#define SC_XMLNEXPI_HXX + +#include <xmloff/xmlictxt.hxx> +#include <xmloff/xmlimp.hxx> + +class ScXMLImport; + +class ScXMLNamedExpressionsContext : public SvXMLImportContext +{ + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLNamedExpressionsContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList); + + virtual ~ScXMLNamedExpressionsContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLNamedRangeContext : public SvXMLImportContext +{ + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLNamedRangeContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList); + + virtual ~ScXMLNamedRangeContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLNamedExpressionContext : public SvXMLImportContext +{ + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLNamedExpressionContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList); + + virtual ~ScXMLNamedExpressionContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +#endif diff --git a/sc/source/filter/xml/xmlrowi.cxx b/sc/source/filter/xml/xmlrowi.cxx new file mode 100644 index 000000000000..cb302f5d5e0e --- /dev/null +++ b/sc/source/filter/xml/xmlrowi.cxx @@ -0,0 +1,369 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- + +#include "xmlrowi.hxx" +#include "xmlimprt.hxx" +#include "xmlcelli.hxx" +#include "global.hxx" +#include "xmlstyli.hxx" +#include "document.hxx" +#include "docuno.hxx" +#include "olinetab.hxx" +#include "sheetdata.hxx" + +#include <xmloff/xmltkmap.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/families.hxx> +#include <xmloff/xmltoken.hxx> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include <com/sun/star/sheet/XSpreadsheet.hpp> +#include <com/sun/star/table/XColumnRowRange.hpp> +#include <com/sun/star/sheet/XPrintAreas.hpp> + +#include <com/sun/star/table/CellAddress.hpp> + +#define SC_ISVISIBLE "IsVisible" +#define SC_OPTIMALHEIGHT "OptimalHeight" +#define SC_ISFILTERED "IsFiltered" + +using namespace com::sun::star; +using namespace xmloff::token; + +//------------------------------------------------------------------ + +ScXMLTableRowContext::ScXMLTableRowContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + sVisibility(GetXMLToken(XML_VISIBLE)), + nRepeatedRows(1), + bHasCell(sal_False) +{ + rtl::OUString sCellStyleName; + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetTableRowAttrTokenMap()); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_TABLE_ROW_ATTR_STYLE_NAME: + { + sStyleName = sValue; + } + break; + case XML_TOK_TABLE_ROW_ATTR_VISIBILITY: + { + sVisibility = sValue; + } + break; + case XML_TOK_TABLE_ROW_ATTR_REPEATED: + { + nRepeatedRows = std::max( sValue.toInt32(), (sal_Int32) 1 ); + } + break; + case XML_TOK_TABLE_ROW_ATTR_DEFAULT_CELL_STYLE_NAME: + { + sCellStyleName = sValue; + } + break; + /*case XML_TOK_TABLE_ROW_ATTR_USE_OPTIMAL_HEIGHT: + { + sOptimalHeight = sValue; + } + break;*/ + } + } + GetScImport().GetTables().AddRow(); + GetScImport().GetTables().SetRowStyle(sCellStyleName); +} + +ScXMLTableRowContext::~ScXMLTableRowContext() +{ +} + +SvXMLImportContext *ScXMLTableRowContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + const SvXMLTokenMap& rTokenMap(GetScImport().GetTableRowElemTokenMap()); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_TABLE_ROW_CELL: +// if( IsInsertCellPossible() ) + { + bHasCell = sal_True; + pContext = new ScXMLTableRowCellContext( GetScImport(), nPrefix, + rLName, xAttrList, sal_False, nRepeatedRows + //this + ); + } + break; + case XML_TOK_TABLE_ROW_COVERED_CELL: +// if( IsInsertCellPossible() ) + { + bHasCell = sal_True; + pContext = new ScXMLTableRowCellContext( GetScImport(), nPrefix, + rLName, xAttrList, sal_True, nRepeatedRows + //this + ); + } + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLTableRowContext::EndElement() +{ + ScXMLImport& rXMLImport(GetScImport()); + if (!bHasCell && nRepeatedRows > 1) + { + for (sal_Int32 i = 0; i < nRepeatedRows - 1; ++i) //one row is always added + GetScImport().GetTables().AddRow(); + DBG_ERRORFILE("it seems here is a nonvalid file; possible missing of table:table-cell element"); + } + sal_Int32 nSheet = rXMLImport.GetTables().GetCurrentSheet(); + sal_Int32 nCurrentRow(rXMLImport.GetTables().GetCurrentRow()); + uno::Reference<sheet::XSpreadsheet> xSheet(rXMLImport.GetTables().GetCurrentXSheet()); + ScDocument* pDoc = rXMLImport.GetDocument(); + if(xSheet.is()) + { + sal_Int32 nFirstRow(nCurrentRow - nRepeatedRows + 1); + if (nFirstRow > MAXROW) + nFirstRow = MAXROW; + if (nCurrentRow > MAXROW) + nCurrentRow = MAXROW; + uno::Reference <table::XCellRange> xCellRange(xSheet->getCellRangeByPosition(0, nFirstRow, 0, nCurrentRow)); + if (xCellRange.is()) + { + uno::Reference<table::XColumnRowRange> xColumnRowRange (xCellRange, uno::UNO_QUERY); + if (xColumnRowRange.is()) + { + uno::Reference <beans::XPropertySet> xRowProperties(xColumnRowRange->getRows(), uno::UNO_QUERY); + if (xRowProperties.is()) + { + if (sStyleName.getLength()) + { + XMLTableStylesContext *pStyles((XMLTableStylesContext *)rXMLImport.GetAutoStyles()); + if ( pStyles ) + { + XMLTableStyleContext* pStyle((XMLTableStyleContext *)pStyles->FindStyleChildContext( + XML_STYLE_FAMILY_TABLE_ROW, sStyleName, sal_True)); + if (pStyle) + { + pStyle->FillPropertySet(xRowProperties); + + if ( nSheet != pStyle->GetLastSheet() ) + { + ScSheetSaveData* pSheetData = ScModelObj::getImplementation(rXMLImport.GetModel())->GetSheetSaveData(); + pSheetData->AddRowStyle( sStyleName, ScAddress( 0, (SCROW)nFirstRow, (SCTAB)nSheet ) ); + pStyle->SetLastSheet(nSheet); + } + } + } + } + sal_Bool bVisible (sal_True); + sal_Bool bFiltered (sal_False); + if (IsXMLToken(sVisibility, XML_COLLAPSE)) + { + bVisible = sal_False; + } + else if (IsXMLToken(sVisibility, XML_FILTER)) + { + bVisible = sal_False; + bFiltered = sal_True; + } + + // #i116164# call SetRowHidden/SetRowFiltered directly, so the tree doesn't have to be rebuilt + // to compare with existing hidden flags. + if (!bVisible && pDoc) + pDoc->SetRowHidden((SCROW)nFirstRow, (SCROW)nCurrentRow, (SCTAB)nSheet, true); + if (bFiltered && pDoc) + pDoc->SetRowFiltered((SCROW)nFirstRow, (SCROW)nCurrentRow, (SCTAB)nSheet, true); + + //if (!bVisible) + // xRowProperties->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ISVISIBLE)), uno::makeAny(bVisible)); + //if (bFiltered) + // xRowProperties->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ISFILTERED)), uno::makeAny(bFiltered)); + } + } + } + } +} + +ScXMLTableRowsContext::ScXMLTableRowsContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + const sal_Bool bTempHeader, const sal_Bool bTempGroup ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + nHeaderStartRow(0), + nHeaderEndRow(0), + nGroupStartRow(0), + nGroupEndRow(0), + bHeader(bTempHeader), + bGroup(bTempGroup), + bGroupDisplay(sal_True) +{ + // don't have any attributes + if (bHeader) + { + nHeaderStartRow = rImport.GetTables().GetCurrentRow(); + ++nHeaderStartRow; + } + else if (bGroup) + { + nGroupStartRow = rImport.GetTables().GetCurrentRow(); + ++nGroupStartRow; + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(aLocalName, XML_DISPLAY)) + bGroupDisplay = IsXMLToken(sValue, XML_TRUE); + } + } +} + +ScXMLTableRowsContext::~ScXMLTableRowsContext() +{ +} + +SvXMLImportContext *ScXMLTableRowsContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + const SvXMLTokenMap& rTokenMap(GetScImport().GetTableRowsElemTokenMap()); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_TABLE_ROWS_ROW_GROUP: + pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix, + rLName, xAttrList, + sal_False, sal_True ); + break; + case XML_TOK_TABLE_ROWS_HEADER_ROWS: + pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix, + rLName, xAttrList, + sal_True, sal_False ); + break; + case XML_TOK_TABLE_ROWS_ROWS: + pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix, + rLName, xAttrList, + sal_False, sal_False ); + break; + case XML_TOK_TABLE_ROWS_ROW: + pContext = new ScXMLTableRowContext( GetScImport(), nPrefix, + rLName, xAttrList//, + //this + ); + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLTableRowsContext::EndElement() +{ + ScXMLImport& rXMLImport(GetScImport()); + if (bHeader) + { + nHeaderEndRow = rXMLImport.GetTables().GetCurrentRow(); + if (nHeaderStartRow <= nHeaderEndRow) + { + uno::Reference <sheet::XPrintAreas> xPrintAreas (rXMLImport.GetTables().GetCurrentXSheet(), uno::UNO_QUERY); + if (xPrintAreas.is()) + { + if (!xPrintAreas->getPrintTitleRows()) + { + xPrintAreas->setPrintTitleRows(sal_True); + table::CellRangeAddress aRowHeaderRange; + aRowHeaderRange.StartRow = nHeaderStartRow; + aRowHeaderRange.EndRow = nHeaderEndRow; + xPrintAreas->setTitleRows(aRowHeaderRange); + } + else + { + table::CellRangeAddress aRowHeaderRange(xPrintAreas->getTitleRows()); + aRowHeaderRange.EndRow = nHeaderEndRow; + xPrintAreas->setTitleRows(aRowHeaderRange); + } + } + } + } + else if (bGroup) + { + nGroupEndRow = rXMLImport.GetTables().GetCurrentRow(); + sal_Int32 nSheet(rXMLImport.GetTables().GetCurrentSheet()); + if (nGroupStartRow <= nGroupEndRow) + { + ScDocument* pDoc(GetScImport().GetDocument()); + if (pDoc) + { + GetScImport().LockSolarMutex(); + ScOutlineTable* pOutlineTable(pDoc->GetOutlineTable(static_cast<SCTAB>(nSheet), sal_True)); + ScOutlineArray* pRowArray(pOutlineTable->GetRowArray()); + sal_Bool bResized; + pRowArray->Insert(static_cast<SCROW>(nGroupStartRow), static_cast<SCROW>(nGroupEndRow), bResized, !bGroupDisplay, sal_True); + GetScImport().UnlockSolarMutex(); + } + } + } +} diff --git a/sc/source/filter/xml/xmlrowi.hxx b/sc/source/filter/xml/xmlrowi.hxx new file mode 100644 index 000000000000..707ebbea90f8 --- /dev/null +++ b/sc/source/filter/xml/xmlrowi.hxx @@ -0,0 +1,93 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef SC_XMLROWI_HXX +#define SC_XMLROWI_HXX + +#include <xmloff/xmlictxt.hxx> +#include <xmloff/xmlimp.hxx> + +class ScXMLImport; + +class ScXMLTableRowContext : public SvXMLImportContext +{ + rtl::OUString sStyleName; + rtl::OUString sVisibility; + sal_Int32 nRepeatedRows; + sal_Bool bHasCell; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLTableRowContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual ~ScXMLTableRowContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +class ScXMLTableRowsContext : public SvXMLImportContext +{ + sal_Int32 nHeaderStartRow; + sal_Int32 nHeaderEndRow; + sal_Int32 nGroupStartRow; + sal_Int32 nGroupEndRow; + sal_Bool bHeader; + sal_Bool bGroup; + sal_Bool bGroupDisplay; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLTableRowsContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + const sal_Bool bHeader, const sal_Bool bGroup); + + virtual ~ScXMLTableRowsContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +#endif diff --git a/sc/source/filter/xml/xmlsceni.cxx b/sc/source/filter/xml/xmlsceni.cxx new file mode 100644 index 000000000000..963c567804bc --- /dev/null +++ b/sc/source/filter/xml/xmlsceni.cxx @@ -0,0 +1,173 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- + +#include "document.hxx" +#include "xmlimprt.hxx" +#include "xmlsceni.hxx" +#include "docuno.hxx" +#include "attrib.hxx" +#include "XMLConverter.hxx" +#include "rangeutl.hxx" + +#include <xmloff/xmltkmap.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmluconv.hxx> +#include <xmloff/xmltoken.hxx> + +using namespace com::sun::star; +using namespace xmloff::token; +using ::rtl::OUString; + +//------------------------------------------------------------------ + +ScXMLTableScenarioContext::ScXMLTableScenarioContext( + ScXMLImport& rImport, + sal_uInt16 nPrfx, + const OUString& rLName, + const uno::Reference< xml::sax::XAttributeList >& xAttrList ): + SvXMLImportContext( rImport, nPrfx, rLName ), + aBorderColor( COL_BLACK ), + bDisplayBorder( sal_True ), + bCopyBack( sal_True ), + bCopyStyles( sal_True ), + bCopyFormulas( sal_True ), + bIsActive( sal_False ), + bProtected( sal_False ) +{ + rImport.LockSolarMutex(); + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetTableScenarioAttrTokenMap()); + for( sal_Int16 i = 0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_TABLE_SCENARIO_ATTR_DISPLAY_BORDER: + { + bDisplayBorder = IsXMLToken(sValue, XML_TRUE); + } + break; + case XML_TOK_TABLE_SCENARIO_ATTR_BORDER_COLOR: + { + SvXMLUnitConverter::convertColor(aBorderColor, sValue); + } + break; + case XML_TOK_TABLE_SCENARIO_ATTR_COPY_BACK: + { + bCopyBack = IsXMLToken(sValue, XML_TRUE); + } + break; + case XML_TOK_TABLE_SCENARIO_ATTR_COPY_STYLES: + { + bCopyStyles = IsXMLToken(sValue, XML_TRUE); + } + break; + case XML_TOK_TABLE_SCENARIO_ATTR_COPY_FORMULAS: + { + bCopyFormulas = IsXMLToken(sValue, XML_TRUE); + } + break; + case XML_TOK_TABLE_SCENARIO_ATTR_IS_ACTIVE: + { + bIsActive = IsXMLToken(sValue, XML_TRUE); + } + break; + case XML_TOK_TABLE_SCENARIO_ATTR_SCENARIO_RANGES: + { + ScRangeStringConverter::GetRangeListFromString( + aScenarioRanges, sValue, GetScImport().GetDocument(), ::formula::FormulaGrammar::CONV_OOO ); + } + break; + case XML_TOK_TABLE_SCENARIO_ATTR_COMMENT: + { + sComment = sValue; + } + break; + case XML_TOK_TABLE_SCENARIO_ATTR_PROTECTED: + { + bProtected = IsXMLToken(sValue, XML_TRUE); + } + break; + } + } +} + +ScXMLTableScenarioContext::~ScXMLTableScenarioContext() +{ + GetScImport().UnlockSolarMutex(); +} + +SvXMLImportContext *ScXMLTableScenarioContext::CreateChildContext( + sal_uInt16 nPrefix, + const OUString& rLName, + const uno::Reference< xml::sax::XAttributeList >& /* xAttrList */ ) +{ + return new SvXMLImportContext( GetImport(), nPrefix, rLName ); +} + +void ScXMLTableScenarioContext::EndElement() +{ + SCTAB nCurrTable( sal::static_int_cast<SCTAB>( GetScImport().GetTables().GetCurrentSheet() ) ); + ScDocument* pDoc(GetScImport().GetDocument()); + if (pDoc) + { + pDoc->SetScenario( nCurrTable, sal_True ); + sal_uInt16 nFlags( 0 ); + if( bDisplayBorder ) + nFlags |= SC_SCENARIO_SHOWFRAME; + if( bCopyBack ) + nFlags |= SC_SCENARIO_TWOWAY; + if( bCopyStyles ) + nFlags |= SC_SCENARIO_ATTRIB; + if( !bCopyFormulas ) + nFlags |= SC_SCENARIO_VALUE; + if( bProtected ) + nFlags |= SC_SCENARIO_PROTECT; + pDoc->SetScenarioData( nCurrTable, String( sComment ), aBorderColor, nFlags ); + for( sal_Int32 i = 0; i < static_cast<sal_Int32>(aScenarioRanges.Count()); ++i ) + { + ScRange* pRange(aScenarioRanges.GetObject( i )); + if( pRange ) + pDoc->ApplyFlagsTab( pRange->aStart.Col(), pRange->aStart.Row(), + pRange->aEnd.Col(), pRange->aEnd.Row(), nCurrTable, SC_MF_SCENARIO ); + } + pDoc->SetActiveScenario( nCurrTable, bIsActive ); + } +} + diff --git a/sc/source/filter/xml/xmlsceni.hxx b/sc/source/filter/xml/xmlsceni.hxx new file mode 100644 index 000000000000..8c9030cbce0b --- /dev/null +++ b/sc/source/filter/xml/xmlsceni.hxx @@ -0,0 +1,70 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef SC_XMLSCENI_HXX +#define SC_XMLSCENI_HXX + +#include <xmloff/xmlictxt.hxx> +#include <xmloff/xmlimp.hxx> +#include <tools/color.hxx> +#include "rangelst.hxx" + +class ScXMLImport; + +class ScXMLTableScenarioContext : public SvXMLImportContext +{ +private: + rtl::OUString sComment; + Color aBorderColor; + ScRangeList aScenarioRanges; + sal_Bool bDisplayBorder; + sal_Bool bCopyBack; + sal_Bool bCopyStyles; + sal_Bool bCopyFormulas; + sal_Bool bIsActive; + sal_Bool bProtected; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLTableScenarioContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual ~ScXMLTableScenarioContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +#endif diff --git a/sc/source/filter/xml/xmlsorti.cxx b/sc/source/filter/xml/xmlsorti.cxx new file mode 100644 index 000000000000..71e4a62e4a4f --- /dev/null +++ b/sc/source/filter/xml/xmlsorti.cxx @@ -0,0 +1,279 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- + +#include "xmlsorti.hxx" +#include "xmlimprt.hxx" +#include "docuno.hxx" +#include "convuno.hxx" +#include "XMLConverter.hxx" +#include "unonames.hxx" +#include "rangeutl.hxx" + +#include <xmloff/xmltkmap.hxx> +#include <xmloff/nmspmap.hxx> +#include <comphelper/extract.hxx> +#include <xmloff/xmltoken.hxx> + +#define SC_USERLIST "UserList" + +using namespace com::sun::star; +using namespace xmloff::token; + +//------------------------------------------------------------------ + +ScXMLSortContext::ScXMLSortContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pDatabaseRangeContext(pTempDatabaseRangeContext), + sCountry(), + sLanguage(), + sAlgorithm(), + nUserListIndex(0), + bCopyOutputData(sal_False), + bBindFormatsToContent(sal_True), + bIsCaseSensitive(sal_False), + bEnabledUserList(sal_False) +{ + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetSortAttrTokenMap()); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_SORT_ATTR_BIND_STYLES_TO_CONTENT : + { + bBindFormatsToContent = IsXMLToken(sValue, XML_TRUE); + } + break; + case XML_TOK_SORT_ATTR_TARGET_RANGE_ADDRESS : + { + ScRange aScRange; + sal_Int32 nOffset(0); + if (ScRangeStringConverter::GetRangeFromString( aScRange, sValue, GetScImport().GetDocument(), ::formula::FormulaGrammar::CONV_OOO, nOffset )) + { + ScUnoConversion::FillApiAddress( aOutputPosition, aScRange.aStart ); + bCopyOutputData = sal_True; + } + } + break; + case XML_TOK_SORT_ATTR_CASE_SENSITIVE : + { + bIsCaseSensitive = IsXMLToken(sValue, XML_TRUE); + } + break; + case XML_TOK_SORT_ATTR_LANGUAGE : + sLanguage = sValue; + break; + case XML_TOK_SORT_ATTR_COUNTRY : + sCountry = sValue; + break; + case XML_TOK_SORT_ATTR_ALGORITHM : + sAlgorithm = sValue; + break; + } + } +} + +ScXMLSortContext::~ScXMLSortContext() +{ +} + +SvXMLImportContext *ScXMLSortContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext *pContext(0); + + const SvXMLTokenMap& rTokenMap(GetScImport().GetSortElemTokenMap()); + switch( rTokenMap.Get( nPrefix, rLName ) ) + { + case XML_TOK_SORT_SORT_BY : + { + pContext = new ScXMLSortByContext( GetScImport(), nPrefix, + rLName, xAttrList, this); + } + break; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLSortContext::EndElement() +{ + sal_Int32 nLangLength(sLanguage.getLength()); + sal_Int32 nCountryLength(sCountry.getLength()); + sal_Int32 nAlgoLength(sAlgorithm.getLength()); + sal_uInt8 i (0); + if (nLangLength || nCountryLength) + ++i; + if (nAlgoLength) + ++i; + uno::Sequence <beans::PropertyValue> aSortDescriptor(7 + i); + aSortDescriptor[0].Name = rtl::OUString::createFromAscii(SC_UNONAME_BINDFMT); + aSortDescriptor[0].Value = ::cppu::bool2any(bBindFormatsToContent); + aSortDescriptor[1].Name = rtl::OUString::createFromAscii(SC_UNONAME_COPYOUT); + aSortDescriptor[1].Value = ::cppu::bool2any(bCopyOutputData); + aSortDescriptor[2].Name = rtl::OUString::createFromAscii(SC_UNONAME_ISCASE); + aSortDescriptor[2].Value = ::cppu::bool2any(bIsCaseSensitive); + aSortDescriptor[3].Name = rtl::OUString::createFromAscii(SC_UNONAME_ISULIST); + aSortDescriptor[3].Value = ::cppu::bool2any(bEnabledUserList); + aSortDescriptor[4].Name = rtl::OUString::createFromAscii(SC_UNONAME_OUTPOS); + aSortDescriptor[4].Value <<= aOutputPosition; + aSortDescriptor[5].Name = rtl::OUString::createFromAscii(SC_UNONAME_UINDEX); + aSortDescriptor[5].Value <<= nUserListIndex; + aSortDescriptor[6].Name = rtl::OUString::createFromAscii(SC_UNONAME_SORTFLD); + aSortDescriptor[6].Value <<= aSortFields; + if (nLangLength || nCountryLength) + { + lang::Locale aLocale; + aLocale.Language = sLanguage; + aLocale.Country = sCountry; + aSortDescriptor[7].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_COLLLOC)); + aSortDescriptor[7].Value <<= aLocale; + } + if (nAlgoLength) + { + aSortDescriptor[6 + i].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_COLLALG)); + aSortDescriptor[6 + i].Value <<= sAlgorithm; + } + pDatabaseRangeContext->SetSortSequence(aSortDescriptor); +} + +void ScXMLSortContext::AddSortField(const rtl::OUString& sFieldNumber, const rtl::OUString& sDataType, const rtl::OUString& sOrder) +{ + util::SortField aSortField; + aSortField.Field = sFieldNumber.toInt32(); + if (IsXMLToken(sOrder, XML_ASCENDING)) + aSortField.SortAscending = sal_True; + else + aSortField.SortAscending = sal_False; + if (sDataType.getLength() > 8) + { + rtl::OUString sTemp = sDataType.copy(0, 8); + if (sTemp.compareToAscii(SC_USERLIST) == 0) + { + bEnabledUserList = sal_True; + sTemp = sDataType.copy(8); + nUserListIndex = static_cast<sal_Int16>(sTemp.toInt32()); + } + else + { + if (IsXMLToken(sDataType, XML_AUTOMATIC)) + aSortField.FieldType = util::SortFieldType_AUTOMATIC; + } + } + else + { + if (IsXMLToken(sDataType, XML_TEXT)) + aSortField.FieldType = util::SortFieldType_ALPHANUMERIC; + else if (IsXMLToken(sDataType, XML_NUMBER)) + aSortField.FieldType = util::SortFieldType_NUMERIC; + } + aSortFields.realloc(aSortFields.getLength() + 1); + aSortFields[aSortFields.getLength() - 1] = aSortField; +} + +ScXMLSortByContext::ScXMLSortByContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLSortContext* pTempSortContext) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pSortContext(pTempSortContext), + sDataType(GetXMLToken(XML_AUTOMATIC)), + sOrder(GetXMLToken(XML_ASCENDING)) +{ + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetSortSortByAttrTokenMap()); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_SORT_BY_ATTR_FIELD_NUMBER : + { + sFieldNumber = sValue; + } + break; + case XML_TOK_SORT_BY_ATTR_DATA_TYPE : + { + sDataType = sValue; + } + break; + case XML_TOK_SORT_BY_ATTR_ORDER : + { + sOrder = sValue; + } + break; + } + } +} + +ScXMLSortByContext::~ScXMLSortByContext() +{ +} + +SvXMLImportContext *ScXMLSortByContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) +{ + return new SvXMLImportContext( GetImport(), nPrefix, rLName ); +} + +void ScXMLSortByContext::EndElement() +{ + pSortContext->AddSortField(sFieldNumber, sDataType, sOrder); +} + diff --git a/sc/source/filter/xml/xmlsorti.hxx b/sc/source/filter/xml/xmlsorti.hxx new file mode 100644 index 000000000000..630f66d3bd06 --- /dev/null +++ b/sc/source/filter/xml/xmlsorti.hxx @@ -0,0 +1,106 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef SC_XMLSORTI_HXX +#define SC_XMLSORTI_HXX + +#include <xmloff/xmlictxt.hxx> +#include <xmloff/xmlimp.hxx> +#include <com/sun/star/util/SortField.hpp> +#include <com/sun/star/table/CellAddress.hpp> + +#include "xmldrani.hxx" + +class ScXMLImport; + +class ScXMLSortContext : public SvXMLImportContext +{ + ScXMLDatabaseRangeContext* pDatabaseRangeContext; + + com::sun::star::uno::Sequence <com::sun::star::util::SortField> aSortFields; + com::sun::star::table::CellAddress aOutputPosition; + rtl::OUString sCountry; + rtl::OUString sLanguage; + rtl::OUString sAlgorithm; + sal_Int16 nUserListIndex; + sal_Bool bCopyOutputData; + sal_Bool bBindFormatsToContent; + sal_Bool bIsCaseSensitive; + sal_Bool bEnabledUserList; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLSortContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLDatabaseRangeContext* pTempDatabaseRangeContext); + + virtual ~ScXMLSortContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); + + void AddSortField(const rtl::OUString& sFieldNumber, const rtl::OUString& sDataType, const rtl::OUString& sOrder); +}; + +class ScXMLSortByContext : public SvXMLImportContext +{ + ScXMLSortContext* pSortContext; + + rtl::OUString sFieldNumber; + rtl::OUString sDataType; + rtl::OUString sOrder; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLSortByContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + ScXMLSortContext* pTempSortContext); + + virtual ~ScXMLSortByContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +#endif diff --git a/sc/source/filter/xml/xmlstyle.cxx b/sc/source/filter/xml/xmlstyle.cxx new file mode 100644 index 000000000000..d061ea24b194 --- /dev/null +++ b/sc/source/filter/xml/xmlstyle.cxx @@ -0,0 +1,1876 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + +#include "xmlstyle.hxx" +#include "xmlexprt.hxx" +#include "xmlimprt.hxx" + +#include "XMLConverter.hxx" +#include "rangeutl.hxx" + +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/xmluconv.hxx> +#include <xmloff/xmltypes.hxx> +#include <xmloff/families.hxx> +#include <xmloff/xmlnumfe.hxx> +#include <xmloff/xmlnumfi.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/attrlist.hxx> +#include <xmloff/contextid.hxx> +#include <xmloff/txtprmap.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/util/CellProtection.hpp> +#include <com/sun/star/table/CellOrientation.hpp> +#include <com/sun/star/table/CellVertJustify.hpp> +#include <com/sun/star/table/CellHoriJustify.hpp> +#include <com/sun/star/table/TableBorder.hpp> +#include <com/sun/star/sheet/XSheetConditionalEntries.hpp> +#include <com/sun/star/sheet/XSheetConditionalEntry.hpp> +#include <com/sun/star/sheet/XSheetCondition.hpp> +#include <com/sun/star/beans/XPropertyState.hpp> +#include <comphelper/extract.hxx> + +#include <rtl/ustrbuf.hxx> + +using namespace com::sun::star; +using namespace ::xmloff::token; +using namespace ::formula; +using ::rtl::OUString; + +#define MAP(name,prefix,token,type,context) { name, sizeof(name)-1, prefix, token, type, context, SvtSaveOptions::ODFVER_010 } +#define MAP_EXT(name,prefix,token,type,context) { name, sizeof(name)-1, prefix, token, type, context, SvtSaveOptions::ODFVER_LATEST } +#define MAP_END() { NULL, 0, 0, XML_TOKEN_INVALID, 0, 0, SvtSaveOptions::ODFVER_010 } + +const XMLPropertyMapEntry aXMLScCellStylesProperties[] = +{ + MAP( "AsianVerticalMode", XML_NAMESPACE_STYLE, XML_GLYPH_ORIENTATION_VERTICAL, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_VERTICAL, 0), + MAP( "BottomBorder", XML_NAMESPACE_FO, XML_BORDER_BOTTOM, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER, CTF_SC_BOTTOMBORDER ), + MAP( "BottomBorder", XML_NAMESPACE_STYLE, XML_BORDER_LINE_WIDTH_BOTTOM, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_BOTTOMBORDERWIDTH ), + MAP( "CellBackColor", XML_NAMESPACE_FO, XML_BACKGROUND_COLOR, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_COLORTRANSPARENT|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ), + MAP( "CellProtection", XML_NAMESPACE_STYLE, XML_CELL_PROTECT, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_CELLPROTECTION|MID_FLAG_MERGE_PROPERTY, 0 ), + MAP( "CellProtection", XML_NAMESPACE_STYLE, XML_PRINT_CONTENT, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_PRINTCONTENT|MID_FLAG_MERGE_PROPERTY, 0 ), + MAP( "CellStyle", XML_NAMESPACE_STYLE, XML_STYLE, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_STRING, CTF_SC_CELLSTYLE ), + MAP( "ConditionalFormatXML", XML_NAMESPACE_STYLE, XML_MAP, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_STRING|MID_FLAG_SPECIAL_ITEM, CTF_SC_IMPORT_MAP ), + MAP( "ConditionalFormatXML", XML_NAMESPACE_STYLE, XML_MAP, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_STRING|MID_FLAG_SPECIAL_ITEM, CTF_SC_MAP ), + MAP( "DiagonalBLTR", XML_NAMESPACE_STYLE, XML_DIAGONAL_BL_TR, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER, CTF_SC_DIAGONALBLTR ), + MAP( "DiagonalBLTR", XML_NAMESPACE_STYLE, XML_DIAGONAL_BL_TR_WIDTH, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_DIAGONALBLTRWIDTH ), // #i102690# for old files + MAP( "DiagonalBLTR", XML_NAMESPACE_STYLE, XML_DIAGONAL_BL_TR_WIDTHS, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_DIAGONALBLTRWIDTHS ), + MAP( "DiagonalTLBR", XML_NAMESPACE_STYLE, XML_DIAGONAL_TL_BR, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER, CTF_SC_DIAGONALTLBR ), + MAP( "DiagonalTLBR", XML_NAMESPACE_STYLE, XML_DIAGONAL_TL_BR_WIDTH, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_DIAGONALTLBRWIDTH ), // #i102690# for old files + MAP( "DiagonalTLBR", XML_NAMESPACE_STYLE, XML_DIAGONAL_TL_BR_WIDTHS, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_DIAGONALTLBRWIDTHS ), + MAP( "HoriJustify", XML_NAMESPACE_FO, XML_TEXT_ALIGN, XML_TYPE_PROP_PARAGRAPH|XML_SC_TYPE_HORIJUSTIFY|MID_FLAG_MERGE_PROPERTY, 0 ), + MAP( "HoriJustify", XML_NAMESPACE_STYLE, XML_TEXT_ALIGN_SOURCE, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_HORIJUSTIFYSOURCE|MID_FLAG_MERGE_PROPERTY, 0 ), + MAP( "HoriJustify", XML_NAMESPACE_STYLE, XML_REPEAT_CONTENT, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_HORIJUSTIFYREPEAT|MID_FLAG_MERGE_PROPERTY, 0 ), + MAP( "IsCellBackgroundTransparent", XML_NAMESPACE_FO, XML_BACKGROUND_COLOR, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_ISTRANSPARENT|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ), + MAP( "IsTextWrapped", XML_NAMESPACE_FO, XML_WRAP_OPTION, XML_TYPE_PROP_TABLE_CELL|XML_SC_ISTEXTWRAPPED, 0 ), + MAP( "LeftBorder", XML_NAMESPACE_FO, XML_BORDER, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER, CTF_SC_ALLBORDER ), + MAP( "LeftBorder", XML_NAMESPACE_FO, XML_BORDER_LEFT, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER, CTF_SC_LEFTBORDER ), + MAP( "LeftBorder", XML_NAMESPACE_STYLE, XML_BORDER_LINE_WIDTH, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_ALLBORDERWIDTH ), + MAP( "LeftBorder", XML_NAMESPACE_STYLE, XML_BORDER_LINE_WIDTH_LEFT, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_LEFTBORDERWIDTH ), + MAP( "NumberFormat", XML_NAMESPACE_STYLE, XML_DATA_STYLE_NAME, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_NUMBER|MID_FLAG_SPECIAL_ITEM, CTF_SC_NUMBERFORMAT), + MAP( "Orientation", XML_NAMESPACE_STYLE, XML_DIRECTION, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_ORIENTATION, 0 ), + MAP( "ParaBottomMargin", XML_NAMESPACE_FO, XML_PADDING, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_MEASURE, CTF_SC_ALLPADDING ), + MAP( "ParaBottomMargin", XML_NAMESPACE_FO, XML_PADDING_BOTTOM, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_MEASURE, CTF_SC_BOTTOMPADDING ), + MAP( "ParaIndent", XML_NAMESPACE_FO, XML_MARGIN_LEFT, XML_TYPE_PROP_PARAGRAPH|XML_TYPE_MEASURE16, 0 ), +// MAP( "ParaIsHyphenation", XML_NAMESPACE_FO, XML_HYPHENATE, XML_TYPE_PROP_TEXT|XML_TYPE_BOOL, 0 ), + MAP( "ParaLeftMargin", XML_NAMESPACE_FO, XML_PADDING_LEFT, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_MEASURE, CTF_SC_LEFTPADDING ), + MAP( "ParaRightMargin", XML_NAMESPACE_FO, XML_PADDING_RIGHT, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_MEASURE, CTF_SC_RIGHTPADDING ), + MAP( "ParaTopMargin", XML_NAMESPACE_FO, XML_PADDING_TOP, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_MEASURE, CTF_SC_TOPPADDING ), + MAP( "RightBorder", XML_NAMESPACE_FO, XML_BORDER_RIGHT, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER, CTF_SC_RIGHTBORDER ), + MAP( "RightBorder", XML_NAMESPACE_STYLE, XML_BORDER_LINE_WIDTH_RIGHT, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_RIGHTBORDERWIDTH ), + MAP( "RotateAngle", XML_NAMESPACE_STYLE, XML_ROTATION_ANGLE, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_ROTATEANGLE, 0 ), + MAP( "RotateReference", XML_NAMESPACE_STYLE, XML_ROTATION_ALIGN, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_ROTATEREFERENCE, 0), + MAP( "ShadowFormat", XML_NAMESPACE_STYLE, XML_SHADOW, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_TEXT_SHADOW, 0 ), + MAP( "ShrinkToFit", XML_NAMESPACE_STYLE, XML_SHRINK_TO_FIT, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BOOL, 0 ), + MAP( "StandardDecimals", XML_NAMESPACE_STYLE, XML_DECIMAL_PLACES, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_NUMBER16, 0 ), + MAP( "TopBorder", XML_NAMESPACE_FO, XML_BORDER_TOP, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER, CTF_SC_TOPBORDER ), + MAP( "TopBorder", XML_NAMESPACE_STYLE, XML_BORDER_LINE_WIDTH_TOP, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BORDER_WIDTH, CTF_SC_TOPBORDERWIDTH ), + MAP( "UserDefinedAttributes", XML_NAMESPACE_TEXT, XML_XMLNS, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_ATTRIBUTE_CONTAINER | MID_FLAG_SPECIAL_ITEM, 0 ), + MAP( "ValidationXML", XML_NAMESPACE_TABLE, XML_CONTENT_VALIDATION, XML_TYPE_PROP_TABLE_CELL|XML_TYPE_BUILDIN_CMP_ONLY, CTF_SC_VALIDATION ), + MAP( "VertJustify", XML_NAMESPACE_STYLE, XML_VERTICAL_ALIGN, XML_TYPE_PROP_TABLE_CELL|XML_SC_TYPE_VERTJUSTIFY, 0), +// MAP( "WritingMode", XML_NAMESPACE_STYLE, XML_WRITING_MODE, XML_TYPE_PROP_PARAGRAPH|XML_TYPE_TEXT_WRITING_MODE_WITH_DEFAULT, 0 ), + MAP_END() +}; + +const XMLPropertyMapEntry aXMLScColumnStylesProperties[] = +{ + MAP( "IsManualPageBreak", XML_NAMESPACE_FO, XML_BREAK_BEFORE, XML_TYPE_PROP_TABLE_COLUMN|XML_SC_TYPE_BREAKBEFORE, 0), + MAP( "IsVisible", XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TYPE_PROP_TABLE_COLUMN|XML_SC_TYPE_EQUAL|MID_FLAG_SPECIAL_ITEM, CTF_SC_ISVISIBLE ), + MAP( "Width", XML_NAMESPACE_STYLE, XML_COLUMN_WIDTH, XML_TYPE_PROP_TABLE_COLUMN|XML_TYPE_MEASURE, 0 ), +// MAP( "OptimalWidth", XML_NAMESPACE_STYLE, XML_USE_OPTIMAL_COLUMN_WIDTH, XML_TYPE_PROP_TABLE_COLUMN|XML_TYPE_BOOL, 0), + MAP_END() +}; + +const XMLPropertyMapEntry aXMLScRowStylesImportProperties[] = +{ + // #i57867# Include background color (CellBackColor/IsCellBackgroundTransparent) for import only. + // Import and export should use the same map, with MID_FLAG_NO_PROPERTY_EXPORT for the background entries, + // but this doesn't work at the moment because SvXMLImportPropertyMapper compares MID_FLAG_NO_PROPERTY to 0. + // If this is changed (not for 2.0.x), a single map can be used again. + + MAP( "CellBackColor", XML_NAMESPACE_FO, XML_BACKGROUND_COLOR, XML_TYPE_PROP_TABLE_ROW|XML_TYPE_COLORTRANSPARENT|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ), + MAP( "Height", XML_NAMESPACE_STYLE, XML_ROW_HEIGHT, XML_TYPE_PROP_TABLE_ROW|XML_TYPE_MEASURE, CTF_SC_ROWHEIGHT), + MAP( "IsCellBackgroundTransparent", XML_NAMESPACE_FO, XML_BACKGROUND_COLOR, XML_TYPE_PROP_TABLE_ROW|XML_TYPE_ISTRANSPARENT|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ), + MAP( "IsManualPageBreak", XML_NAMESPACE_FO, XML_BREAK_BEFORE, XML_TYPE_PROP_TABLE_ROW|XML_SC_TYPE_BREAKBEFORE, CTF_SC_ROWBREAKBEFORE), + MAP( "OptimalHeight", XML_NAMESPACE_STYLE, XML_USE_OPTIMAL_ROW_HEIGHT, XML_TYPE_PROP_TABLE_ROW|XML_TYPE_BOOL, CTF_SC_ROWOPTIMALHEIGHT), + MAP_END() +}; + +const XMLPropertyMapEntry aXMLScRowStylesProperties[] = +{ + MAP( "Height", XML_NAMESPACE_STYLE, XML_ROW_HEIGHT, XML_TYPE_PROP_TABLE_ROW|XML_TYPE_MEASURE, CTF_SC_ROWHEIGHT), + MAP( "IsManualPageBreak", XML_NAMESPACE_FO, XML_BREAK_BEFORE, XML_TYPE_PROP_TABLE_ROW|XML_SC_TYPE_BREAKBEFORE, CTF_SC_ROWBREAKBEFORE), + MAP( "OptimalHeight", XML_NAMESPACE_STYLE, XML_USE_OPTIMAL_ROW_HEIGHT, XML_TYPE_PROP_TABLE_ROW|XML_TYPE_BOOL, CTF_SC_ROWOPTIMALHEIGHT), + MAP_END() +}; + +const XMLPropertyMapEntry aXMLScTableStylesImportProperties[] = +{ + // #i57869# Include background color (CellBackColor/IsCellBackgroundTransparent) for import only. + // Import and export should use the same map, with MID_FLAG_NO_PROPERTY_EXPORT for the background entries, + // but this doesn't work at the moment because SvXMLImportPropertyMapper compares MID_FLAG_NO_PROPERTY to 0. + // If this is changed (not for 2.0.x), a single map can be used again. + + MAP( "CellBackColor", XML_NAMESPACE_FO, XML_BACKGROUND_COLOR, XML_TYPE_PROP_TABLE|XML_TYPE_COLORTRANSPARENT|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ), + MAP( "IsCellBackgroundTransparent", XML_NAMESPACE_FO, XML_BACKGROUND_COLOR, XML_TYPE_PROP_TABLE|XML_TYPE_ISTRANSPARENT|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ), + MAP( "IsVisible", XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TYPE_PROP_TABLE|XML_TYPE_BOOL, 0 ), + MAP( "PageStyle", XML_NAMESPACE_STYLE, XML_MASTER_PAGE_NAME, XML_TYPE_PROP_TABLE|XML_TYPE_STRING|MID_FLAG_SPECIAL_ITEM, CTF_SC_MASTERPAGENAME ), + MAP( "TableLayout", XML_NAMESPACE_STYLE, XML_WRITING_MODE, XML_TYPE_PROP_TABLE|XML_TYPE_TEXT_WRITING_MODE, 0 ), + MAP( "TabColor", XML_NAMESPACE_TABLE, XML_TAB_COLOR, XML_TYPE_PROP_TABLE|XML_TYPE_COLORAUTO, 0 ), + MAP_EXT( "TabColor", XML_NAMESPACE_TABLE_EXT, XML_TAB_COLOR, XML_TYPE_PROP_TABLE|XML_TYPE_COLORAUTO, 0 ), + MAP_END() +}; + +const XMLPropertyMapEntry aXMLScTableStylesProperties[] = +{ + MAP( "IsVisible", XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TYPE_PROP_TABLE|XML_TYPE_BOOL, 0 ), + MAP( "PageStyle", XML_NAMESPACE_STYLE, XML_MASTER_PAGE_NAME, XML_TYPE_PROP_TABLE|XML_TYPE_STRING|MID_FLAG_SPECIAL_ITEM, CTF_SC_MASTERPAGENAME ), + MAP( "TableLayout", XML_NAMESPACE_STYLE, XML_WRITING_MODE, XML_TYPE_PROP_TABLE|XML_TYPE_TEXT_WRITING_MODE, 0 ), + MAP_EXT( "TabColor", XML_NAMESPACE_TABLE_EXT, XML_TAB_COLOR, XML_TYPE_PROP_TABLE|XML_TYPE_COLORAUTO, 0 ), + MAP_END() +}; + +ScXMLCellExportPropertyMapper::ScXMLCellExportPropertyMapper( + const UniReference< XMLPropertySetMapper >& rMapper ) + : SvXMLExportPropertyMapper(rMapper) +{ +} + +ScXMLCellExportPropertyMapper::~ScXMLCellExportPropertyMapper() +{ +} + +void ScXMLCellExportPropertyMapper::ContextFilter( + ::std::vector< XMLPropertyState >& rProperties, + uno::Reference< beans::XPropertySet > rPropSet ) const +{ + XMLPropertyState* pPadding = NULL; + XMLPropertyState* pPadding_Bottom = NULL; + XMLPropertyState* pPadding_Left = NULL; + XMLPropertyState* pPadding_Right = NULL; + XMLPropertyState* pPadding_Top = NULL; + + XMLPropertyState* pBorder = NULL; + XMLPropertyState* pBorder_Bottom = NULL; + XMLPropertyState* pBorder_Left = NULL; + XMLPropertyState* pBorder_Right = NULL; + XMLPropertyState* pBorder_Top = NULL; + XMLPropertyState* pSWBorder = NULL; + XMLPropertyState* pSWBorder_Bottom = NULL; + XMLPropertyState* pSWBorder_Left = NULL; + XMLPropertyState* pSWBorder_Right = NULL; + XMLPropertyState* pSWBorder_Top = NULL; + XMLPropertyState* pDiagonalTLBR = NULL; + XMLPropertyState* pDiagonalBLTR = NULL; + + XMLPropertyState* pAllBorderWidthState = NULL; + XMLPropertyState* pLeftBorderWidthState = NULL; + XMLPropertyState* pRightBorderWidthState = NULL; + XMLPropertyState* pTopBorderWidthState = NULL; + XMLPropertyState* pBottomBorderWidthState = NULL; + XMLPropertyState* pSWAllBorderWidthState = NULL; + XMLPropertyState* pSWLeftBorderWidthState = NULL; + XMLPropertyState* pSWRightBorderWidthState = NULL; + XMLPropertyState* pSWTopBorderWidthState = NULL; + XMLPropertyState* pSWBottomBorderWidthState = NULL; + XMLPropertyState* pDiagonalTLBRWidthState = NULL; + XMLPropertyState* pDiagonalBLTRWidthState = NULL; + + XMLPropertyState* pParaMarginLeft = NULL; + XMLPropertyState* pParaMarginLeftRel = NULL; + XMLPropertyState* pParaMarginRight = NULL; + XMLPropertyState* pParaMarginRightRel = NULL; + XMLPropertyState* pParaMarginTop = NULL; + XMLPropertyState* pParaMarginTopRel = NULL; + XMLPropertyState* pParaMarginBottom = NULL; + XMLPropertyState* pParaMarginBottomRel = NULL; + + XMLPropertyState* pParaAdjust = NULL; + XMLPropertyState* pParaAdjustLast = NULL; + + ::std::vector< XMLPropertyState >::iterator aEndIter(rProperties.end()); + for( ::std::vector< XMLPropertyState >::iterator aIter = rProperties.begin(); + aIter != aEndIter; ++aIter ) + { + XMLPropertyState* propertie = &(*aIter); + if (propertie->mnIndex != -1) + { + switch( getPropertySetMapper()->GetEntryContextId( propertie->mnIndex ) ) + { + case CTF_SC_ALLPADDING: pPadding = propertie; break; + case CTF_SC_BOTTOMPADDING: pPadding_Bottom = propertie; break; + case CTF_SC_LEFTPADDING: pPadding_Left = propertie; break; + case CTF_SC_RIGHTPADDING: pPadding_Right = propertie; break; + case CTF_SC_TOPPADDING: pPadding_Top = propertie; break; + case CTF_SC_ALLBORDER: pBorder = propertie; break; + case CTF_SC_LEFTBORDER: pBorder_Left = propertie; break; + case CTF_SC_RIGHTBORDER: pBorder_Right = propertie; break; + case CTF_SC_BOTTOMBORDER: pBorder_Bottom = propertie; break; + case CTF_SC_TOPBORDER: pBorder_Top = propertie; break; + case CTF_SC_ALLBORDERWIDTH: pAllBorderWidthState = propertie; break; + case CTF_SC_LEFTBORDERWIDTH: pLeftBorderWidthState = propertie; break; + case CTF_SC_RIGHTBORDERWIDTH: pRightBorderWidthState = propertie; break; + case CTF_SC_TOPBORDERWIDTH: pTopBorderWidthState = propertie; break; + case CTF_SC_BOTTOMBORDERWIDTH: pBottomBorderWidthState = propertie; break; + case CTF_ALLBORDER: pSWBorder = propertie; break; + case CTF_LEFTBORDER: pSWBorder_Left = propertie; break; + case CTF_RIGHTBORDER: pSWBorder_Right = propertie; break; + case CTF_BOTTOMBORDER: pSWBorder_Bottom = propertie; break; + case CTF_TOPBORDER: pSWBorder_Top = propertie; break; + case CTF_ALLBORDERWIDTH: pSWAllBorderWidthState = propertie; break; + case CTF_LEFTBORDERWIDTH: pSWLeftBorderWidthState = propertie; break; + case CTF_RIGHTBORDERWIDTH: pSWRightBorderWidthState = propertie; break; + case CTF_TOPBORDERWIDTH: pSWTopBorderWidthState = propertie; break; + case CTF_BOTTOMBORDERWIDTH: pSWBottomBorderWidthState = propertie; break; + case CTF_SC_DIAGONALTLBR: pDiagonalTLBR = propertie; break; + case CTF_SC_DIAGONALTLBRWIDTH: pDiagonalTLBRWidthState = propertie; break; + case CTF_SC_DIAGONALBLTR: pDiagonalBLTR = propertie; break; + case CTF_SC_DIAGONALBLTRWIDTH: pDiagonalBLTRWidthState = propertie; break; + case CTF_SD_SHAPE_PARA_ADJUST: pParaAdjust = propertie; break; + case CTF_PARA_ADJUSTLAST: pParaAdjustLast = propertie; break; + case CTF_PARALEFTMARGIN: pParaMarginLeft = propertie; break; + case CTF_PARALEFTMARGIN_REL: pParaMarginLeftRel = propertie; break; + case CTF_PARARIGHTMARGIN: pParaMarginRight = propertie; break; + case CTF_PARARIGHTMARGIN_REL: pParaMarginRightRel = propertie; break; + case CTF_PARATOPMARGIN: pParaMarginTop = propertie; break; + case CTF_PARATOPMARGIN_REL: pParaMarginTopRel = propertie; break; + case CTF_PARABOTTOMMARGIN: pParaMarginBottom = propertie; break; + case CTF_PARABOTTOMMARGIN_REL: pParaMarginBottomRel = propertie; break; + } + } + } + + if (pPadding && pPadding_Bottom && pPadding_Left && pPadding_Right && pPadding_Top) + { + sal_Int32 nBottom = 0, nTop = 0, nLeft = 0, nRight = 0; + if ((pPadding_Bottom->maValue >>= nBottom) && + (pPadding_Left->maValue >>= nLeft) && + (pPadding_Right->maValue >>= nRight) && + (pPadding_Top->maValue >>= nTop)) + { + if ((nBottom == nTop) && (nLeft == nRight) && (nTop == nLeft)) + { + pPadding_Bottom->mnIndex = -1; + pPadding_Bottom->maValue.clear(); + pPadding_Left->mnIndex = -1; + pPadding_Left->maValue.clear(); + pPadding_Right->mnIndex = -1; + pPadding_Right->maValue.clear(); + pPadding_Top->mnIndex = -1; + pPadding_Top->maValue.clear(); + } + else + { + pPadding->mnIndex = -1; + pPadding->maValue.clear(); + } + } + } + if( pBorder ) + { + if( pBorder_Left && pBorder_Right && pBorder_Top && pBorder_Bottom ) + { + table::BorderLine aLeft, aRight, aTop, aBottom; + + pBorder_Left->maValue >>= aLeft; + pBorder_Right->maValue >>= aRight; + pBorder_Top->maValue >>= aTop; + pBorder_Bottom->maValue >>= aBottom; + if( aLeft.Color == aRight.Color && aLeft.InnerLineWidth == aRight.InnerLineWidth && + aLeft.OuterLineWidth == aRight.OuterLineWidth && aLeft.LineDistance == aRight.LineDistance && + aLeft.Color == aTop.Color && aLeft.InnerLineWidth == aTop.InnerLineWidth && + aLeft.OuterLineWidth == aTop.OuterLineWidth && aLeft.LineDistance == aTop.LineDistance && + aLeft.Color == aBottom.Color && aLeft.InnerLineWidth == aBottom.InnerLineWidth && + aLeft.OuterLineWidth == aBottom.OuterLineWidth && aLeft.LineDistance == aBottom.LineDistance ) + { + pBorder_Left->mnIndex = -1; + pBorder_Left->maValue.clear(); + pBorder_Right->mnIndex = -1; + pBorder_Right->maValue.clear(); + pBorder_Top->mnIndex = -1; + pBorder_Top->maValue.clear(); + pBorder_Bottom->mnIndex = -1; + pBorder_Bottom->maValue.clear(); + } + else + { + pBorder->mnIndex = -1; + pBorder->maValue.clear(); + } + } + else + { + pBorder->mnIndex = -1; + pBorder->maValue.clear(); + } + } + if( pAllBorderWidthState ) + { + if( pLeftBorderWidthState && pRightBorderWidthState && pTopBorderWidthState && pBottomBorderWidthState ) + { + table::BorderLine aLeft, aRight, aTop, aBottom; + + pLeftBorderWidthState->maValue >>= aLeft; + pRightBorderWidthState->maValue >>= aRight; + pTopBorderWidthState->maValue >>= aTop; + pBottomBorderWidthState->maValue >>= aBottom; + if( aLeft.InnerLineWidth == aRight.InnerLineWidth && aLeft.OuterLineWidth == aRight.OuterLineWidth && + aLeft.LineDistance == aRight.LineDistance && aLeft.InnerLineWidth == aTop.InnerLineWidth && + aLeft.OuterLineWidth == aTop.OuterLineWidth && aLeft.LineDistance == aTop.LineDistance && + aLeft.InnerLineWidth == aBottom.InnerLineWidth && aLeft.OuterLineWidth == aBottom.OuterLineWidth && + aLeft.LineDistance == aBottom.LineDistance ) + { + pLeftBorderWidthState->mnIndex = -1; + pLeftBorderWidthState->maValue.clear(); + pRightBorderWidthState->mnIndex = -1; + pRightBorderWidthState->maValue.clear(); + pTopBorderWidthState->mnIndex = -1; + pTopBorderWidthState->maValue.clear(); + pBottomBorderWidthState->mnIndex = -1; + pBottomBorderWidthState->maValue.clear(); + } + else + { + pAllBorderWidthState->mnIndex = -1; + pAllBorderWidthState->maValue.clear(); + } + } + else + { + pAllBorderWidthState->mnIndex = -1; + pAllBorderWidthState->maValue.clear(); + } + } + + if (pParaAdjust) + { + pParaAdjust->mnIndex = -1; + pParaAdjust->maValue.clear(); + } + if (pParaAdjustLast) + { + pParaAdjustLast->mnIndex = -1; + pParaAdjustLast->maValue.clear(); + } + if (pSWBorder) + { + pSWBorder->mnIndex = -1; + pSWBorder->maValue.clear(); + } + if (pSWBorder_Left) + { + pSWBorder_Left->mnIndex = -1; + pSWBorder_Left->maValue.clear(); + } + if (pSWBorder_Right) + { + pSWBorder_Right->mnIndex = -1; + pSWBorder_Right->maValue.clear(); + } + if (pSWBorder_Bottom) + { + pSWBorder_Bottom->mnIndex = -1; + pSWBorder_Bottom->maValue.clear(); + } + if (pSWBorder_Top) + { + pSWBorder_Top->mnIndex = -1; + pSWBorder_Top->maValue.clear(); + } + if (pSWAllBorderWidthState) + { + pSWAllBorderWidthState->mnIndex = -1; + pSWAllBorderWidthState->maValue.clear(); + } + if (pSWLeftBorderWidthState) + { + pSWLeftBorderWidthState->mnIndex = -1; + pSWLeftBorderWidthState->maValue.clear(); + } + if (pSWRightBorderWidthState) + { + pSWRightBorderWidthState->mnIndex = -1; + pSWRightBorderWidthState->maValue.clear(); + } + if (pSWTopBorderWidthState) + { + pSWTopBorderWidthState->mnIndex = -1; + pSWTopBorderWidthState->maValue.clear(); + } + if (pSWBottomBorderWidthState) + { + pSWBottomBorderWidthState->mnIndex = -1; + pSWBottomBorderWidthState->maValue.clear(); + } + + if (pParaMarginLeft) + { + pParaMarginLeft->mnIndex = -1; + pParaMarginLeft->maValue.clear(); + } + if (pParaMarginLeftRel) + { + pParaMarginLeftRel->mnIndex = -1; + pParaMarginLeftRel->maValue.clear(); + } + if (pParaMarginRight) + { + pParaMarginRight->mnIndex = -1; + pParaMarginRight->maValue.clear(); + } + if (pParaMarginRightRel) + { + pParaMarginRightRel->mnIndex = -1; + pParaMarginRightRel->maValue.clear(); + } + if (pParaMarginTop) + { + pParaMarginTop->mnIndex = -1; + pParaMarginTop->maValue.clear(); + } + if (pParaMarginTopRel) + { + pParaMarginTopRel->mnIndex = -1; + pParaMarginTopRel->maValue.clear(); + } + if (pParaMarginBottom) + { + pParaMarginBottom->mnIndex = -1; + pParaMarginBottom->maValue.clear(); + } + if (pParaMarginBottomRel) + { + pParaMarginBottomRel->mnIndex = -1; + pParaMarginBottomRel->maValue.clear(); + } + + // #i102690# old diagonal line attribute names without "s" are only read, not written + if (pDiagonalTLBRWidthState) + { + pDiagonalTLBRWidthState->mnIndex = -1; + pDiagonalTLBRWidthState->maValue.clear(); + } + if (pDiagonalBLTRWidthState) + { + pDiagonalBLTRWidthState->mnIndex = -1; + pDiagonalBLTRWidthState->maValue.clear(); + } + + SvXMLExportPropertyMapper::ContextFilter(rProperties, rPropSet); +} + +/** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_EXPORT flag set */ +void ScXMLCellExportPropertyMapper::handleSpecialItem( + SvXMLAttributeList& /* rAttrList */, + const XMLPropertyState& /* rProperty */, + const SvXMLUnitConverter& /* rUnitConverter */, + const SvXMLNamespaceMap& /* rNamespaceMap */, + const ::std::vector< XMLPropertyState > * /* pProperties */, + sal_uInt32 /* nIdx */ ) const +{ + // the SpecialItem NumberFormat must not be handled by this method + // the SpecialItem ConditionlaFormat must not be handled by this method + // the SpecialItem CharBackColor must not be handled by this method +} + +ScXMLRowExportPropertyMapper::ScXMLRowExportPropertyMapper( + const UniReference< XMLPropertySetMapper >& rMapper ) + : SvXMLExportPropertyMapper(rMapper) +{ +} + +ScXMLRowExportPropertyMapper::~ScXMLRowExportPropertyMapper() +{ +} + +void ScXMLRowExportPropertyMapper::ContextFilter( + ::std::vector< XMLPropertyState >& /* rProperties */, + uno::Reference< beans::XPropertySet > /* rPropSet */ ) const +{ + //#108550#; don't filter the height, so other applications know the calculated height + +/* XMLPropertyState* pHeight = NULL; + XMLPropertyState* pOptimalHeight = NULL; + + for( ::std::vector< XMLPropertyState >::iterator propertie = rProperties.begin(); + propertie != rProperties.end(); + ++propertie ) + { + switch( getPropertySetMapper()->GetEntryContextId( propertie->mnIndex ) ) + { + case CTF_SC_ROWHEIGHT: pHeight = propertie; break; + case CTF_SC_ROWOPTIMALHEIGHT: pOptimalHeight = propertie; break; + } + } + if ((pHeight && pOptimalHeight && ::cppu::any2bool( pOptimalHeight->maValue )) || + (pHeight && !pOptimalHeight)) + { + pHeight->mnIndex = -1; + pHeight->maValue.clear(); + } + if (pOptimalHeight) + { + pOptimalHeight->mnIndex = -1; + pOptimalHeight->maValue.clear(); + }*/ +} + +ScXMLColumnExportPropertyMapper::ScXMLColumnExportPropertyMapper( + const UniReference< XMLPropertySetMapper >& rMapper ) + : SvXMLExportPropertyMapper(rMapper) +{ +} + +ScXMLColumnExportPropertyMapper::~ScXMLColumnExportPropertyMapper() +{ +} + +/** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_EXPORT flag set */ +void ScXMLColumnExportPropertyMapper::handleSpecialItem( + SvXMLAttributeList& /* rAttrList */, + const XMLPropertyState& /* rProperty */, + const SvXMLUnitConverter& /* rUnitConverter */, + const SvXMLNamespaceMap& /* rNamespaceMap */, + const ::std::vector< XMLPropertyState > * /* pProperties */, + sal_uInt32 /* nIdx */ ) const +{ + // the SpecialItem IsVisible must not be handled by this method +} + +ScXMLTableExportPropertyMapper::ScXMLTableExportPropertyMapper( + const UniReference< XMLPropertySetMapper >& rMapper ) + : SvXMLExportPropertyMapper(rMapper) +{ +} + +ScXMLTableExportPropertyMapper::~ScXMLTableExportPropertyMapper() +{ +} + +/** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_EXPORT flag set */ +void ScXMLTableExportPropertyMapper::handleSpecialItem( + SvXMLAttributeList& /* rAttrList */, + const XMLPropertyState& /* rProperty */, + const SvXMLUnitConverter& /* rUnitConverter */, + const SvXMLNamespaceMap& /* rNamespaceMap */, + const ::std::vector< XMLPropertyState > * /* pProperties */, + sal_uInt32 /* nIdx */ ) const +{ + // the SpecialItem PageStyle must not be handled by this method +} + +void ScXMLAutoStylePoolP::exportStyleAttributes( + SvXMLAttributeList& rAttrList, + sal_Int32 nFamily, + const ::std::vector< XMLPropertyState >& rProperties, + const SvXMLExportPropertyMapper& rPropExp + , const SvXMLUnitConverter& rUnitConverter, + const SvXMLNamespaceMap& rNamespaceMap + ) const +{ + SvXMLAutoStylePoolP::exportStyleAttributes( rAttrList, nFamily, rProperties, rPropExp, rUnitConverter, rNamespaceMap ); + if (nFamily == XML_STYLE_FAMILY_TABLE_CELL) + { + ::std::vector< XMLPropertyState >::const_iterator i(rProperties.begin()); + ::std::vector< XMLPropertyState >::const_iterator endi(rProperties.end()); + while (i != endi) + { + UniReference< XMLPropertySetMapper > aPropMapper(rScXMLExport.GetCellStylesPropertySetMapper()); + sal_Int16 nContextID(aPropMapper->GetEntryContextId(i->mnIndex)); + switch (nContextID) + { + case CTF_SC_NUMBERFORMAT : + { + sal_Int32 nNumberFormat = 0; + if (i->maValue >>= nNumberFormat) + { + rtl::OUString sAttrValue(rScXMLExport.getDataStyleName(nNumberFormat)); + if (sAttrValue.getLength()) + { + GetExport().AddAttribute( + aPropMapper->GetEntryNameSpace(i->mnIndex), + aPropMapper->GetEntryXMLName(i->mnIndex), + sAttrValue ); + } + } + } + break; + } + ++i; + } + } + else if (nFamily == XML_STYLE_FAMILY_TABLE_TABLE) + { + ::std::vector< XMLPropertyState >::const_iterator i(rProperties.begin()); + ::std::vector< XMLPropertyState >::const_iterator endi(rProperties.end()); + while(i != endi) + { + UniReference< XMLPropertySetMapper > aPropMapper(rScXMLExport.GetTableStylesPropertySetMapper()); + sal_Int16 nContextID(aPropMapper->GetEntryContextId(i->mnIndex)); + switch (nContextID) + { + case CTF_SC_MASTERPAGENAME : + { + rtl::OUString sName; + if (i->maValue >>= sName) + { + GetExport().AddAttribute( + aPropMapper->GetEntryNameSpace(i->mnIndex), + aPropMapper->GetEntryXMLName(i->mnIndex), + GetExport().EncodeStyleName( sName )); + } + } + break; + } + ++i; + } + } +} + +void ScXMLAutoStylePoolP::exportStyleContent( + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > & rHandler, + sal_Int32 nFamily, + const std::vector< XMLPropertyState >& rProperties, + const SvXMLExportPropertyMapper& rPropExp + , const SvXMLUnitConverter& rUnitConverter, + const SvXMLNamespaceMap& rNamespaceMap + ) const +{ + SvXMLAutoStylePoolP::exportStyleContent( rHandler, nFamily, rProperties, rPropExp, rUnitConverter, rNamespaceMap ); + if (nFamily == XML_STYLE_FAMILY_TABLE_CELL) + { + sal_Bool bNotFound = sal_True; + ::std::vector< XMLPropertyState >::const_iterator i(rProperties.begin()); + ::std::vector< XMLPropertyState >::const_iterator endi(rProperties.end()); + while ((i != endi) && bNotFound) + { + if (i->mnIndex != -1) + { + sal_Int16 nContextID = rScXMLExport.GetCellStylesPropertySetMapper()->GetEntryContextId(i->mnIndex); + switch (nContextID) + { + case CTF_SC_MAP : + { + uno::Reference<container::XIndexAccess> xIndex( i->maValue, uno::UNO_QUERY ); + if ( xIndex.is() ) + { + sal_Int32 nConditionCount(xIndex->getCount()); + for (sal_Int32 nCondition = 0; nCondition < nConditionCount; ++nCondition) + { + uno::Reference <sheet::XSheetConditionalEntry> xSheetConditionalEntry(xIndex->getByIndex(nCondition), uno::UNO_QUERY); + if (xSheetConditionalEntry.is()) + { + rtl::OUString sStyleName(xSheetConditionalEntry->getStyleName()); + uno::Reference <sheet::XSheetCondition> xSheetCondition(xSheetConditionalEntry, uno::UNO_QUERY); + if (xSheetCondition.is()) + { + sheet::ConditionOperator aOperator = xSheetCondition->getOperator(); + if (aOperator != sheet::ConditionOperator_NONE) + { + if (aOperator == sheet::ConditionOperator_FORMULA) + { + rtl::OUString sCondition(RTL_CONSTASCII_USTRINGPARAM("is-true-formula(")); + sCondition += xSheetCondition->getFormula1(); + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")")); + rScXMLExport.AddAttribute(XML_NAMESPACE_STYLE, XML_CONDITION, sCondition); + rScXMLExport.AddAttribute(XML_NAMESPACE_STYLE, XML_APPLY_STYLE_NAME, rScXMLExport.EncodeStyleName( sStyleName )); + OUString sOUBaseAddress; + ScDocument* pDoc = rScXMLExport.GetDocument(); + ScRangeStringConverter::GetStringFromAddress( sOUBaseAddress, + xSheetCondition->getSourcePosition(), pDoc, FormulaGrammar::CONV_OOO ); + rScXMLExport.AddAttribute(XML_NAMESPACE_STYLE, XML_BASE_CELL_ADDRESS, sOUBaseAddress); + SvXMLElementExport aMElem(rScXMLExport, XML_NAMESPACE_STYLE, XML_MAP, sal_True, sal_True); + } + else + { + rtl::OUString sCondition; + if (aOperator == sheet::ConditionOperator_BETWEEN || + aOperator == sheet::ConditionOperator_NOT_BETWEEN) + { + if (aOperator == sheet::ConditionOperator_BETWEEN) + sCondition = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-between(")); + else + sCondition = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content-is-not-between(")); + sCondition += xSheetCondition->getFormula1(); + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(",")); + sCondition += xSheetCondition->getFormula2(); + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")")); + } + else + { + sCondition = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cell-content()")); + switch (aOperator) + { + case sheet::ConditionOperator_LESS: + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<")); + break; + case sheet::ConditionOperator_GREATER: + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">")); + break; + case sheet::ConditionOperator_LESS_EQUAL: + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<=")); + break; + case sheet::ConditionOperator_GREATER_EQUAL: + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">=")); + break; + case sheet::ConditionOperator_EQUAL: + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("=")); + break; + case sheet::ConditionOperator_NOT_EQUAL: + sCondition += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("!=")); + break; + default: + { + // added to avoid warnings + } + } + sCondition += xSheetCondition->getFormula1(); + } + rScXMLExport.AddAttribute(XML_NAMESPACE_STYLE, XML_CONDITION, sCondition); + rScXMLExport.AddAttribute(XML_NAMESPACE_STYLE, XML_APPLY_STYLE_NAME, rScXMLExport.EncodeStyleName( sStyleName )); + OUString sOUBaseAddress; + ScRangeStringConverter::GetStringFromAddress( sOUBaseAddress, + xSheetCondition->getSourcePosition(), rScXMLExport.GetDocument(), FormulaGrammar::CONV_OOO ); + rScXMLExport.AddAttribute(XML_NAMESPACE_STYLE, XML_BASE_CELL_ADDRESS, sOUBaseAddress); + SvXMLElementExport aMElem(rScXMLExport, XML_NAMESPACE_STYLE, XML_MAP, sal_True, sal_True); + } + } + } + } + } + } + } + break; + } + } + ++i; + } + } +} + +ScXMLAutoStylePoolP::ScXMLAutoStylePoolP(ScXMLExport& rTempScXMLExport): + SvXMLAutoStylePoolP(rTempScXMLExport), + rScXMLExport(rTempScXMLExport) +{ +} + +ScXMLAutoStylePoolP::~ScXMLAutoStylePoolP() +{ +} + + +void ScXMLStyleExport::exportStyleAttributes( + const ::com::sun::star::uno::Reference< + ::com::sun::star::style::XStyle > & rStyle ) +{ + uno::Reference< beans::XPropertySet > xPropSet( rStyle, uno::UNO_QUERY ); + if (xPropSet.is()) + { + uno::Reference< beans::XPropertySetInfo > xPropSetInfo(xPropSet->getPropertySetInfo()); + rtl::OUString sNumberFormat(RTL_CONSTASCII_USTRINGPARAM("NumberFormat")); + if( xPropSetInfo->hasPropertyByName( sNumberFormat ) ) + { + uno::Reference< beans::XPropertyState > xPropState( xPropSet, uno::UNO_QUERY ); + if( xPropState.is() && (beans::PropertyState_DIRECT_VALUE == + xPropState->getPropertyState( sNumberFormat )) ) + { + sal_Int32 nNumberFormat = 0; + if (xPropSet->getPropertyValue( sNumberFormat ) >>= nNumberFormat) + GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_DATA_STYLE_NAME, + GetExport().getDataStyleName(nNumberFormat) ); + } + } + } +} + +void ScXMLStyleExport::exportStyleContent( + const ::com::sun::star::uno::Reference< + ::com::sun::star::style::XStyle > & /* rStyle */ ) +{ +} + +ScXMLStyleExport::ScXMLStyleExport( + SvXMLExport& rExp, + const ::rtl::OUString& rPoolStyleName, + SvXMLAutoStylePoolP *pAutoStyleP ) + : XMLStyleExport(rExp, rPoolStyleName, pAutoStyleP) +{ +} + +ScXMLStyleExport::~ScXMLStyleExport() +{ +} + +XMLScPropHdlFactory::XMLScPropHdlFactory() + : XMLPropertyHandlerFactory() +{ +} + +XMLScPropHdlFactory::~XMLScPropHdlFactory() +{ +} + +const XMLPropertyHandler* XMLScPropHdlFactory::GetPropertyHandler( sal_Int32 nType ) const +{ + nType &= MID_FLAG_MASK; + + XMLPropertyHandler* pHdl((XMLPropertyHandler*)XMLPropertyHandlerFactory::GetPropertyHandler( nType )); + if(!pHdl) + { + switch(nType) + { + case XML_SC_TYPE_CELLPROTECTION : + { + pHdl = new XmlScPropHdl_CellProtection; + } + break; + case XML_SC_TYPE_PRINTCONTENT : + { + pHdl = new XmlScPropHdl_PrintContent; + } + break; + case XML_SC_TYPE_HORIJUSTIFY : + { + pHdl = new XmlScPropHdl_HoriJustify; + } + break; + case XML_SC_TYPE_HORIJUSTIFYSOURCE : + { + pHdl = new XmlScPropHdl_HoriJustifySource; + } + break; + case XML_SC_TYPE_HORIJUSTIFYREPEAT : + { + pHdl = new XmlScPropHdl_HoriJustifyRepeat; + } + break; + case XML_SC_TYPE_ORIENTATION : + { + pHdl = new XmlScPropHdl_Orientation; + } + break; + case XML_SC_TYPE_ROTATEANGLE : + { + pHdl = new XmlScPropHdl_RotateAngle; + } + break; + case XML_SC_TYPE_ROTATEREFERENCE : + { + pHdl = new XmlScPropHdl_RotateReference; + } + break; + case XML_SC_TYPE_VERTJUSTIFY : + { + pHdl = new XmlScPropHdl_VertJustify; + } + break; + case XML_SC_TYPE_BREAKBEFORE : + { + pHdl = new XmlScPropHdl_BreakBefore; + } + break; + case XML_SC_ISTEXTWRAPPED : + { + pHdl = new XmlScPropHdl_IsTextWrapped; + } + break; + case XML_SC_TYPE_EQUAL : + { + pHdl = new XmlScPropHdl_IsEqual; + } + break; + case XML_SC_TYPE_VERTICAL : + { + pHdl = new XmlScPropHdl_Vertical; + } + break; + } + + if(pHdl) + PutHdlCache(nType, pHdl); + } + + return pHdl; +} + +XmlScPropHdl_CellProtection::~XmlScPropHdl_CellProtection() +{ +} + +bool XmlScPropHdl_CellProtection::equals( + const ::com::sun::star::uno::Any& r1, + const ::com::sun::star::uno::Any& r2 ) const +{ + util::CellProtection aCellProtection1, aCellProtection2; + + if((r1 >>= aCellProtection1) && (r2 >>= aCellProtection2)) + { + return ((aCellProtection1.IsHidden == aCellProtection2.IsHidden) && + (aCellProtection1.IsLocked == aCellProtection2.IsLocked) && + (aCellProtection1.IsFormulaHidden == aCellProtection2.IsFormulaHidden)); + } + return sal_False; +} + +sal_Bool XmlScPropHdl_CellProtection::importXML( + const ::rtl::OUString& rStrImpValue, + ::com::sun::star::uno::Any& rValue, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + sal_Bool bRetval(sal_False); + + util::CellProtection aCellProtection; + sal_Bool bDefault(sal_False); + if (!rValue.hasValue()) + { + aCellProtection.IsHidden = sal_False; + aCellProtection.IsLocked = sal_True; + aCellProtection.IsFormulaHidden = sal_False; + aCellProtection.IsPrintHidden = sal_False; + bDefault = sal_True; + } + if ((rValue >>= aCellProtection) || bDefault) + { + if (!IsXMLToken(rStrImpValue, XML_NONE)) + { + if (!IsXMLToken(rStrImpValue, XML_HIDDEN_AND_PROTECTED)) + { + if (!IsXMLToken(rStrImpValue, XML_PROTECTED)) + { + if (!IsXMLToken(rStrImpValue, XML_FORMULA_HIDDEN)) + { + sal_Int16 i(0); + while (i < rStrImpValue.getLength() && rStrImpValue[i] != ' ') + ++i; + rtl::OUString sFirst(rStrImpValue.copy(0, i)); + rtl::OUString sSecond(rStrImpValue.copy(i + 1)); + aCellProtection.IsFormulaHidden = sal_False; + aCellProtection.IsHidden = sal_False; + aCellProtection.IsLocked = sal_False; + if ((IsXMLToken(sFirst, XML_PROTECTED)) || (IsXMLToken(sSecond, XML_PROTECTED))) + aCellProtection.IsLocked = sal_True; + if ((IsXMLToken(sFirst, XML_FORMULA_HIDDEN)) || (IsXMLToken(sSecond, XML_FORMULA_HIDDEN))) + aCellProtection.IsFormulaHidden = sal_True; + rValue <<= aCellProtection; + bRetval = sal_True; + } + else + { + aCellProtection.IsFormulaHidden = sal_True; + aCellProtection.IsHidden = sal_False; + aCellProtection.IsLocked = sal_False; + rValue <<= aCellProtection; + bRetval = sal_True; + } + } + else + { + aCellProtection.IsFormulaHidden = sal_False; + aCellProtection.IsHidden = sal_False; + aCellProtection.IsLocked = sal_True; + rValue <<= aCellProtection; + bRetval = sal_True; + } + } + else + { + aCellProtection.IsFormulaHidden = sal_True; + aCellProtection.IsHidden = sal_True; + aCellProtection.IsLocked = sal_True; + rValue <<= aCellProtection; + bRetval = sal_True; + } + } + else + { + aCellProtection.IsFormulaHidden = sal_False; + aCellProtection.IsHidden = sal_False; + aCellProtection.IsLocked = sal_False; + rValue <<= aCellProtection; + bRetval = sal_True; + } + } + + return bRetval; +} + +sal_Bool XmlScPropHdl_CellProtection::exportXML( + ::rtl::OUString& rStrExpValue, + const ::com::sun::star::uno::Any& rValue, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + sal_Bool bRetval(sal_False); + util::CellProtection aCellProtection; + + if(rValue >>= aCellProtection) + { + if (!(aCellProtection.IsFormulaHidden || aCellProtection.IsHidden || aCellProtection.IsLocked)) + { + rStrExpValue = GetXMLToken(XML_NONE); + bRetval = sal_True; + } + else if (aCellProtection.IsHidden) + { + // #i105964# "Hide all" implies "Protected" in the UI, so it must be saved as "hidden-and-protected" + // even if "IsLocked" is not set in the CellProtection struct. + rStrExpValue = GetXMLToken(XML_HIDDEN_AND_PROTECTED); + bRetval = sal_True; + } + else if (aCellProtection.IsLocked && !(aCellProtection.IsFormulaHidden || aCellProtection.IsHidden)) + { + rStrExpValue = GetXMLToken(XML_PROTECTED); + bRetval = sal_True; + } + else if (aCellProtection.IsFormulaHidden && !(aCellProtection.IsLocked || aCellProtection.IsHidden)) + { + rStrExpValue = GetXMLToken(XML_FORMULA_HIDDEN); + bRetval = sal_True; + } + else if (aCellProtection.IsFormulaHidden && aCellProtection.IsLocked) + { + rStrExpValue = GetXMLToken(XML_PROTECTED); + rStrExpValue += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" ")); + rStrExpValue += GetXMLToken(XML_FORMULA_HIDDEN); + bRetval = sal_True; + } + } + + return bRetval; +} + +XmlScPropHdl_PrintContent::~XmlScPropHdl_PrintContent() +{ +} + +bool XmlScPropHdl_PrintContent::equals( + const ::com::sun::star::uno::Any& r1, + const ::com::sun::star::uno::Any& r2 ) const +{ + util::CellProtection aCellProtection1, aCellProtection2; + + if((r1 >>= aCellProtection1) && (r2 >>= aCellProtection2)) + { + return (aCellProtection1.IsPrintHidden == aCellProtection2.IsPrintHidden); + } + return sal_False; +} + +sal_Bool XmlScPropHdl_PrintContent::importXML( + const ::rtl::OUString& rStrImpValue, + ::com::sun::star::uno::Any& rValue, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + sal_Bool bRetval(sal_False); + util::CellProtection aCellProtection; + sal_Bool bDefault(sal_False); + if (!rValue.hasValue()) + { + aCellProtection.IsHidden = sal_False; + aCellProtection.IsLocked = sal_True; + aCellProtection.IsFormulaHidden = sal_False; + aCellProtection.IsPrintHidden = sal_False; + bDefault = sal_True; + } + if ((rValue >>= aCellProtection) || bDefault) + { + sal_Bool bValue; + if (SvXMLUnitConverter::convertBool(bValue, rStrImpValue)) + { + aCellProtection.IsPrintHidden = !bValue; + rValue <<= aCellProtection; + bRetval = sal_True; + } + } + + return bRetval; +} + +sal_Bool XmlScPropHdl_PrintContent::exportXML( + ::rtl::OUString& rStrExpValue, + const ::com::sun::star::uno::Any& rValue, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + sal_Bool bRetval(sal_False); + + util::CellProtection aCellProtection; + if(rValue >>= aCellProtection) + { + rtl::OUStringBuffer sValue; + SvXMLUnitConverter::convertBool(sValue, !aCellProtection.IsPrintHidden); + rStrExpValue = sValue.makeStringAndClear(); + bRetval = sal_True; + } + + return bRetval; +} + +XmlScPropHdl_HoriJustify::~XmlScPropHdl_HoriJustify() +{ +} + +bool XmlScPropHdl_HoriJustify::equals( + const ::com::sun::star::uno::Any& r1, + const ::com::sun::star::uno::Any& r2 ) const +{ + table::CellHoriJustify aHoriJustify1, aHoriJustify2; + + if((r1 >>= aHoriJustify1) && (r2 >>= aHoriJustify2)) + return (aHoriJustify1 == aHoriJustify2); + return sal_False; +} + +sal_Bool XmlScPropHdl_HoriJustify::importXML( + const ::rtl::OUString& rStrImpValue, + ::com::sun::star::uno::Any& rValue, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + sal_Bool bRetval(sal_False); + + table::CellHoriJustify nValue = table::CellHoriJustify_LEFT; + rValue >>= nValue; + if (nValue != table::CellHoriJustify_REPEAT) + { + if (IsXMLToken(rStrImpValue, XML_START)) + { + nValue = table::CellHoriJustify_LEFT; + rValue <<= nValue; + bRetval = sal_True; + } + else if (IsXMLToken(rStrImpValue, XML_END)) + { + nValue = table::CellHoriJustify_RIGHT; + rValue <<= nValue; + bRetval = sal_True; + } + else if (IsXMLToken(rStrImpValue, XML_CENTER)) + { + nValue = table::CellHoriJustify_CENTER; + rValue <<= nValue; + bRetval = sal_True; + } + else if (IsXMLToken(rStrImpValue, XML_JUSTIFY)) + { + nValue = table::CellHoriJustify_BLOCK; + rValue <<= nValue; + bRetval = sal_True; + } + } + else + bRetval = sal_True; + + return bRetval; +} + +sal_Bool XmlScPropHdl_HoriJustify::exportXML( + ::rtl::OUString& rStrExpValue, + const ::com::sun::star::uno::Any& rValue, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + table::CellHoriJustify nVal; + sal_Bool bRetval(sal_False); + + if(rValue >>= nVal) + { + switch (nVal) + { + case table::CellHoriJustify_REPEAT: + case table::CellHoriJustify_LEFT: + { + rStrExpValue = GetXMLToken(XML_START); + bRetval = sal_True; + } + break; + case table::CellHoriJustify_RIGHT: + { + rStrExpValue = GetXMLToken(XML_END); + bRetval = sal_True; + } + break; + case table::CellHoriJustify_CENTER: + { + rStrExpValue = GetXMLToken(XML_CENTER); + bRetval = sal_True; + } + break; + case table::CellHoriJustify_BLOCK: + { + rStrExpValue = GetXMLToken(XML_JUSTIFY); + bRetval = sal_True; + } + break; + default: + { + // added to avoid warnings + } + } + } + + return bRetval; +} + +XmlScPropHdl_HoriJustifySource::~XmlScPropHdl_HoriJustifySource() +{ +} + +bool XmlScPropHdl_HoriJustifySource::equals( + const ::com::sun::star::uno::Any& r1, + const ::com::sun::star::uno::Any& r2 ) const +{ + table::CellHoriJustify aHoriJustify1, aHoriJustify2; + + if((r1 >>= aHoriJustify1) && (r2 >>= aHoriJustify2)) + return (aHoriJustify1 == aHoriJustify2); + return sal_False; +} + +sal_Bool XmlScPropHdl_HoriJustifySource::importXML( + const ::rtl::OUString& rStrImpValue, + ::com::sun::star::uno::Any& rValue, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + sal_Bool bRetval(sal_False); + + if (IsXMLToken(rStrImpValue, XML_FIX)) + { + bRetval = sal_True; + } + else if (IsXMLToken(rStrImpValue, XML_VALUE_TYPE)) + { + table::CellHoriJustify nValue(table::CellHoriJustify_STANDARD); + rValue <<= nValue; + bRetval = sal_True; + } + + return bRetval; +} + +sal_Bool XmlScPropHdl_HoriJustifySource::exportXML( + ::rtl::OUString& rStrExpValue, + const ::com::sun::star::uno::Any& rValue, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + table::CellHoriJustify nVal; + sal_Bool bRetval(sal_False); + + if(rValue >>= nVal) + { + if (nVal == table::CellHoriJustify_STANDARD) + { + rStrExpValue = GetXMLToken(XML_VALUE_TYPE); + bRetval = sal_True; + } + else + { + rStrExpValue = GetXMLToken(XML_FIX); + bRetval = sal_True; + } + } + + return bRetval; +} + +XmlScPropHdl_HoriJustifyRepeat::~XmlScPropHdl_HoriJustifyRepeat() +{ +} + +bool XmlScPropHdl_HoriJustifyRepeat::equals( + const ::com::sun::star::uno::Any& r1, + const ::com::sun::star::uno::Any& r2 ) const +{ + table::CellHoriJustify aHoriJustify1, aHoriJustify2; + + if((r1 >>= aHoriJustify1) && (r2 >>= aHoriJustify2)) + return (aHoriJustify1 == aHoriJustify2); + return sal_False; +} + +sal_Bool XmlScPropHdl_HoriJustifyRepeat::importXML( + const ::rtl::OUString& rStrImpValue, + ::com::sun::star::uno::Any& rValue, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + sal_Bool bRetval(sal_False); + + if (IsXMLToken(rStrImpValue, XML_FALSE)) + { + bRetval = sal_True; + } + else if (IsXMLToken(rStrImpValue, XML_TRUE)) + { + table::CellHoriJustify nValue = table::CellHoriJustify_REPEAT; + rValue <<= nValue; + bRetval = sal_True; + } + + return bRetval; +} + +sal_Bool XmlScPropHdl_HoriJustifyRepeat::exportXML( + ::rtl::OUString& rStrExpValue, + const ::com::sun::star::uno::Any& rValue, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + table::CellHoriJustify nVal; + sal_Bool bRetval(sal_False); + + if(rValue >>= nVal) + { + if (nVal == table::CellHoriJustify_REPEAT) + { + rStrExpValue = GetXMLToken(XML_TRUE); + bRetval = sal_True; + } + else + { + rStrExpValue = GetXMLToken(XML_FALSE); + bRetval = sal_True; + } + } + + return bRetval; +} + +XmlScPropHdl_Orientation::~XmlScPropHdl_Orientation() +{ +} + +bool XmlScPropHdl_Orientation::equals( + const ::com::sun::star::uno::Any& r1, + const ::com::sun::star::uno::Any& r2 ) const +{ + table::CellOrientation aOrientation1, aOrientation2; + + if((r1 >>= aOrientation1) && (r2 >>= aOrientation2)) + return (aOrientation1 == aOrientation2); + return sal_False; +} + +sal_Bool XmlScPropHdl_Orientation::importXML( + const ::rtl::OUString& rStrImpValue, + ::com::sun::star::uno::Any& rValue, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + sal_Bool bRetval(sal_False); + + table::CellOrientation nValue; + if (IsXMLToken(rStrImpValue, XML_LTR)) + { + nValue = table::CellOrientation_STANDARD; + rValue <<= nValue; + bRetval = sal_True; + } + else if (IsXMLToken(rStrImpValue, XML_TTB)) + { + nValue = table::CellOrientation_STACKED; + rValue <<= nValue; + bRetval = sal_True; + } + + return bRetval; +} + +sal_Bool XmlScPropHdl_Orientation::exportXML( + ::rtl::OUString& rStrExpValue, + const ::com::sun::star::uno::Any& rValue, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + table::CellOrientation nVal; + sal_Bool bRetval(sal_False); + + if(rValue >>= nVal) + { + switch (nVal) + { + case table::CellOrientation_STACKED : + { + rStrExpValue = GetXMLToken(XML_TTB); + bRetval = sal_True; + } + break; + default: + { + rStrExpValue = GetXMLToken(XML_LTR); + bRetval = sal_True; + } + break; + } + } + + return bRetval; +} + +XmlScPropHdl_RotateAngle::~XmlScPropHdl_RotateAngle() +{ +} + +bool XmlScPropHdl_RotateAngle::equals( + const ::com::sun::star::uno::Any& r1, + const ::com::sun::star::uno::Any& r2 ) const +{ + sal_Int32 aAngle1 = 0, aAngle2 = 0; + + if((r1 >>= aAngle1) && (r2 >>= aAngle2)) + return (aAngle1 == aAngle2); + return sal_False; +} + +sal_Bool XmlScPropHdl_RotateAngle::importXML( + const ::rtl::OUString& rStrImpValue, + ::com::sun::star::uno::Any& rValue, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + sal_Bool bRetval(sal_False); + + sal_Int32 nValue; + if (SvXMLUnitConverter::convertNumber(nValue, rStrImpValue)) + { + nValue *= 100; + rValue <<= nValue; + bRetval = sal_True; + } + + return bRetval; +} + +sal_Bool XmlScPropHdl_RotateAngle::exportXML( + ::rtl::OUString& rStrExpValue, + const ::com::sun::star::uno::Any& rValue, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + sal_Int32 nVal = 0; + sal_Bool bRetval(sal_False); + + if(rValue >>= nVal) + { + rtl::OUStringBuffer sValue; + SvXMLUnitConverter::convertNumber(sValue, sal_Int32(nVal / 100)); + rStrExpValue = sValue.makeStringAndClear(); + bRetval = sal_True; + } + + return bRetval; +} + +XmlScPropHdl_RotateReference::~XmlScPropHdl_RotateReference() +{ +} + +bool XmlScPropHdl_RotateReference::equals( + const ::com::sun::star::uno::Any& r1, + const ::com::sun::star::uno::Any& r2 ) const +{ + table::CellVertJustify aReference1, aReference2; + + if((r1 >>= aReference1) && (r2 >>= aReference2)) + return (aReference1 == aReference2); + return sal_False; +} + +sal_Bool XmlScPropHdl_RotateReference::importXML( + const ::rtl::OUString& rStrImpValue, + ::com::sun::star::uno::Any& rValue, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + sal_Bool bRetval(sal_False); + + table::CellVertJustify nValue; + if (IsXMLToken(rStrImpValue, XML_NONE)) + { + nValue = table::CellVertJustify_STANDARD; + rValue <<= nValue; + bRetval = sal_True; + } + else if (IsXMLToken(rStrImpValue, XML_BOTTOM)) + { + nValue = table::CellVertJustify_BOTTOM; + rValue <<= nValue; + bRetval = sal_True; + } + else if (IsXMLToken(rStrImpValue, XML_TOP)) + { + nValue = table::CellVertJustify_TOP; + rValue <<= nValue; + bRetval = sal_True; + } + else if (IsXMLToken(rStrImpValue, XML_CENTER)) + { + nValue = table::CellVertJustify_CENTER; + rValue <<= nValue; + bRetval = sal_True; + } + + return bRetval; +} + +sal_Bool XmlScPropHdl_RotateReference::exportXML( + ::rtl::OUString& rStrExpValue, + const ::com::sun::star::uno::Any& rValue, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + table::CellVertJustify nVal; + sal_Bool bRetval(sal_False); + + if(rValue >>= nVal) + { + switch (nVal) + { + case table::CellVertJustify_BOTTOM : + { + rStrExpValue = GetXMLToken(XML_BOTTOM); + bRetval = sal_True; + } + break; + case table::CellVertJustify_CENTER : + { + rStrExpValue = GetXMLToken(XML_CENTER); + bRetval = sal_True; + } + break; + case table::CellVertJustify_STANDARD : + { + rStrExpValue = GetXMLToken(XML_NONE); + bRetval = sal_True; + } + break; + case table::CellVertJustify_TOP : + { + rStrExpValue = GetXMLToken(XML_TOP); + bRetval = sal_True; + } + break; + default: + { + // added to avoid warnings + } + } + } + + return bRetval; +} + +XmlScPropHdl_VertJustify::~XmlScPropHdl_VertJustify() +{ +} + +bool XmlScPropHdl_VertJustify::equals( + const ::com::sun::star::uno::Any& r1, + const ::com::sun::star::uno::Any& r2 ) const +{ + table::CellVertJustify aReference1, aReference2; + + if((r1 >>= aReference1) && (r2 >>= aReference2)) + return (aReference1 == aReference2); + return sal_False; +} + +sal_Bool XmlScPropHdl_VertJustify::importXML( + const ::rtl::OUString& rStrImpValue, + ::com::sun::star::uno::Any& rValue, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + sal_Bool bRetval(sal_False); + + table::CellVertJustify nValue; + if (IsXMLToken(rStrImpValue, XML_AUTOMATIC)) + { + nValue = table::CellVertJustify_STANDARD; + rValue <<= nValue; + bRetval = sal_True; + } + else if (IsXMLToken(rStrImpValue, XML_BOTTOM)) + { + nValue = table::CellVertJustify_BOTTOM; + rValue <<= nValue; + bRetval = sal_True; + } + else if (IsXMLToken(rStrImpValue, XML_TOP)) + { + nValue = table::CellVertJustify_TOP; + rValue <<= nValue; + bRetval = sal_True; + } + else if (IsXMLToken(rStrImpValue, XML_MIDDLE)) + { + nValue = table::CellVertJustify_CENTER; + rValue <<= nValue; + bRetval = sal_True; + } + + return bRetval; +} + +sal_Bool XmlScPropHdl_VertJustify::exportXML( + ::rtl::OUString& rStrExpValue, + const ::com::sun::star::uno::Any& rValue, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + table::CellVertJustify nVal; + sal_Bool bRetval(sal_False); + + if(rValue >>= nVal) + { + switch (nVal) + { + case table::CellVertJustify_BOTTOM : + { + rStrExpValue = GetXMLToken(XML_BOTTOM); + bRetval = sal_True; + } + break; + case table::CellVertJustify_CENTER : + { + rStrExpValue = GetXMLToken(XML_MIDDLE); + bRetval = sal_True; + } + break; + case table::CellVertJustify_STANDARD : + { + rStrExpValue = GetXMLToken(XML_AUTOMATIC); + bRetval = sal_True; + } + break; + case table::CellVertJustify_TOP : + { + rStrExpValue = GetXMLToken(XML_TOP); + bRetval = sal_True; + } + break; + default: + { + // added to avoid warnings + } + } + } + + return bRetval; +} + +XmlScPropHdl_BreakBefore::~XmlScPropHdl_BreakBefore() +{ +} + +bool XmlScPropHdl_BreakBefore::equals( + const ::com::sun::star::uno::Any& r1, + const ::com::sun::star::uno::Any& r2 ) const +{ + sal_Bool aBreak1 = 0, aBreak2 = 0; + + if((r1 >>= aBreak1) && (r2 >>= aBreak2)) + return (aBreak1 == aBreak2); + return sal_False; +} + +sal_Bool XmlScPropHdl_BreakBefore::importXML( + const ::rtl::OUString& rStrImpValue, + ::com::sun::star::uno::Any& rValue, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + sal_Bool bRetval(sal_False); + + sal_Bool bValue; + if (IsXMLToken(rStrImpValue, XML_AUTO)) + { + bValue = sal_False; + rValue = ::cppu::bool2any(bValue); + bRetval = sal_True; + } + else if (IsXMLToken(rStrImpValue, XML_PAGE)) + { + bValue = sal_True; + rValue = ::cppu::bool2any(bValue); + bRetval = sal_True; + } + + return bRetval; +} + +sal_Bool XmlScPropHdl_BreakBefore::exportXML( + ::rtl::OUString& rStrExpValue, + const ::com::sun::star::uno::Any& rValue, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + sal_Bool bRetval(sal_False); + + if(::cppu::any2bool(rValue)) + { + rStrExpValue = GetXMLToken(XML_PAGE); + bRetval = sal_True; + } + else + { + rStrExpValue = GetXMLToken(XML_AUTO); + bRetval = sal_True; + } + + return bRetval; +} + +XmlScPropHdl_IsTextWrapped::~XmlScPropHdl_IsTextWrapped() +{ +} + +bool XmlScPropHdl_IsTextWrapped::equals( + const ::com::sun::star::uno::Any& r1, + const ::com::sun::star::uno::Any& r2 ) const +{ + return (::cppu::any2bool(r1) == ::cppu::any2bool(r2)); +} + +sal_Bool XmlScPropHdl_IsTextWrapped::importXML( + const ::rtl::OUString& rStrImpValue, + ::com::sun::star::uno::Any& rValue, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + sal_Bool bRetval(sal_False); + + if (IsXMLToken(rStrImpValue, XML_WRAP)) + { + rValue = ::cppu::bool2any(sal_True); + bRetval = sal_True; + } + else if (IsXMLToken(rStrImpValue, XML_NO_WRAP)) + { + rValue = ::cppu::bool2any(sal_False); + bRetval = sal_True; + } + + return bRetval; +} + +sal_Bool XmlScPropHdl_IsTextWrapped::exportXML( + ::rtl::OUString& rStrExpValue, + const ::com::sun::star::uno::Any& rValue, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + sal_Bool bRetval(sal_False); + + if (::cppu::any2bool(rValue)) + { + rStrExpValue = GetXMLToken(XML_WRAP); + bRetval = sal_True; + } + else + { + rStrExpValue = GetXMLToken(XML_NO_WRAP); + bRetval = sal_True; + } + + return bRetval; +} + +sal_Bool XmlScPropHdl_IsEqual::importXML( const ::rtl::OUString& /* rStrImpValue */, + ::com::sun::star::uno::Any& /* rValue */, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + DBG_ERROR("should never be called"); + return sal_False; +} + +sal_Bool XmlScPropHdl_IsEqual::exportXML( ::rtl::OUString& /* rStrExpValue */, + const ::com::sun::star::uno::Any& /* rValue */, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + DBG_ERROR("should never be called"); + return sal_False; +} + +XmlScPropHdl_Vertical::~XmlScPropHdl_Vertical() +{ +} + +bool XmlScPropHdl_Vertical::equals( + const ::com::sun::star::uno::Any& r1, + const ::com::sun::star::uno::Any& r2 ) const +{ + return (::cppu::any2bool(r1) == ::cppu::any2bool(r2)); +} + +sal_Bool XmlScPropHdl_Vertical::importXML( + const ::rtl::OUString& rStrImpValue, + ::com::sun::star::uno::Any& rValue, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + sal_Bool bRetval(sal_False); + + if (IsXMLToken(rStrImpValue, XML_AUTO)) + { + rValue = ::cppu::bool2any(sal_True); + bRetval = sal_True; + } + else if (IsXMLToken(rStrImpValue, XML_0)) + { + rValue = ::cppu::bool2any(sal_False); + bRetval = sal_True; + } + + return bRetval; +} + +sal_Bool XmlScPropHdl_Vertical::exportXML( + ::rtl::OUString& rStrExpValue, + const ::com::sun::star::uno::Any& rValue, + const SvXMLUnitConverter& /* rUnitConverter */ ) const +{ + sal_Bool bRetval(sal_False); + + if (::cppu::any2bool(rValue)) + { + rStrExpValue = GetXMLToken(XML_AUTO); + bRetval = sal_True; + } + else + { + rStrExpValue = GetXMLToken(XML_0); + bRetval = sal_True; + } + + return bRetval; +} diff --git a/sc/source/filter/xml/xmlstyle.hxx b/sc/source/filter/xml/xmlstyle.hxx new file mode 100644 index 000000000000..f8abf5e6443d --- /dev/null +++ b/sc/source/filter/xml/xmlstyle.hxx @@ -0,0 +1,349 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLSTYLE_HXX +#define SC_XMLSTYLE_HXX + +#include <xmloff/maptype.hxx> +#include <xmloff/xmlaustp.hxx> +#include <xmloff/xmltypes.hxx> +#include <xmloff/xmlprmap.hxx> +#include <xmloff/prhdlfac.hxx> +#include <xmloff/styleexp.hxx> +#include <xmloff/xmlexppr.hxx> +#include <xmloff/contextid.hxx> + +extern const XMLPropertyMapEntry aXMLScCellStylesProperties[]; +extern const XMLPropertyMapEntry aXMLScColumnStylesProperties[]; +extern const XMLPropertyMapEntry aXMLScRowStylesProperties[]; +extern const XMLPropertyMapEntry aXMLScRowStylesImportProperties[]; +extern const XMLPropertyMapEntry aXMLScTableStylesProperties[]; +extern const XMLPropertyMapEntry aXMLScTableStylesImportProperties[]; + +//CellStyles +#define XML_SC_TYPE_CELLPROTECTION (XML_SC_TYPES_START + 1) +#define XML_SC_TYPE_PRINTCONTENT (XML_SC_TYPES_START + 2) +#define XML_SC_TYPE_HORIJUSTIFY (XML_SC_TYPES_START + 3) +#define XML_SC_TYPE_HORIJUSTIFYSOURCE (XML_SC_TYPES_START + 4) +#define XML_SC_TYPE_HORIJUSTIFYREPEAT (XML_SC_TYPES_START + 5) +#define XML_SC_TYPE_ORIENTATION (XML_SC_TYPES_START + 6) +#define XML_SC_TYPE_ROTATEANGLE (XML_SC_TYPES_START + 7) +#define XML_SC_TYPE_ROTATEREFERENCE (XML_SC_TYPES_START + 8) +#define XML_SC_TYPE_BORDERLEFT (XML_SC_TYPES_START + 9) +#define XML_SC_TYPE_BORDERRIGHT (XML_SC_TYPES_START + 10) +#define XML_SC_TYPE_BORDERTOP (XML_SC_TYPES_START + 11) +#define XML_SC_TYPE_BORDERBOTTOM (XML_SC_TYPES_START + 12) +#define XML_SC_TYPE_VERTJUSTIFY (XML_SC_TYPES_START + 13) +#define XML_SC_ISTEXTWRAPPED (XML_SC_TYPES_START + 14) +#define XML_SC_TYPE_EQUAL (XML_SC_TYPES_START + 15) +#define XML_SC_TYPE_VERTICAL (XML_SC_TYPES_START + 16) + +#define CTF_SC_HORIJUSTIFY (XML_SC_CTF_START + 1) +#define CTF_SC_HORIJUSTIFY_SOURCE (XML_SC_CTF_START + 2) +#define CTF_SC_ALLPADDING (XML_SC_CTF_START + 3) +#define CTF_SC_BOTTOMPADDING (XML_SC_CTF_START + 4) +#define CTF_SC_LEFTPADDING (XML_SC_CTF_START + 5) +#define CTF_SC_RIGHTPADDING (XML_SC_CTF_START + 6) +#define CTF_SC_TOPPADDING (XML_SC_CTF_START + 7) +#define CTF_SC_ALLBORDER (XML_SC_CTF_START + 8) +#define CTF_SC_LEFTBORDER (XML_SC_CTF_START + 9) +#define CTF_SC_RIGHTBORDER (XML_SC_CTF_START + 10) +#define CTF_SC_TOPBORDER (XML_SC_CTF_START + 11) +#define CTF_SC_BOTTOMBORDER (XML_SC_CTF_START + 12) +#define CTF_SC_ALLBORDERWIDTH (XML_SC_CTF_START + 13) +#define CTF_SC_LEFTBORDERWIDTH (XML_SC_CTF_START + 14) +#define CTF_SC_RIGHTBORDERWIDTH (XML_SC_CTF_START + 15) +#define CTF_SC_TOPBORDERWIDTH (XML_SC_CTF_START + 16) +#define CTF_SC_BOTTOMBORDERWIDTH (XML_SC_CTF_START + 17) +#define CTF_SC_NUMBERFORMAT (XML_SC_CTF_START + 18) +#define CTF_SC_MAP (XML_SC_CTF_START + 19) +#define CTF_SC_PARAINDENT (XML_SC_CTF_START + 20) +#define CTF_SC_OLDTEXTBACKGROUND (XML_SC_CTF_START + 21) +#define CTF_SC_IMPORT_MAP (XML_SC_CTF_START + 22) +#define CTF_SC_CELLSTYLE (XML_SC_CTF_START + 23) +#define CTF_SC_VALIDATION (XML_SC_CTF_START + 24) +#define CTF_SC_DIAGONALTLBR (XML_SC_CTF_START + 25) +#define CTF_SC_DIAGONALTLBRWIDTH (XML_SC_CTF_START + 26) +#define CTF_SC_DIAGONALBLTR (XML_SC_CTF_START + 27) +#define CTF_SC_DIAGONALBLTRWIDTH (XML_SC_CTF_START + 28) +#define CTF_SC_DIAGONALTLBRWIDTHS (XML_SC_CTF_START + 29) +#define CTF_SC_DIAGONALBLTRWIDTHS (XML_SC_CTF_START + 30) + +#define CTF_SC_ROWHEIGHT (XML_SC_CTF_START + 50) +#define CTF_SC_ROWOPTIMALHEIGHT (XML_SC_CTF_START + 51) +#define CTF_SC_ROWBREAKBEFORE (XML_SC_CTF_START + 52) +#define CTF_SC_ISVISIBLE (XML_SC_CTF_START + 53) + +#define CTF_SC_MASTERPAGENAME (XML_SC_CTF_START + 53) + +//ColumnStyles +#define XML_SC_TYPE_BREAKBEFORE (XML_SC_TYPES_START + 50) + +class ScXMLExport; +class ScXMLImport; + +class ScXMLCellExportPropertyMapper : public SvXMLExportPropertyMapper +{ +protected: + /** Application-specific filter. By default do nothing. */ + virtual void ContextFilter( + ::std::vector< XMLPropertyState >& rProperties, + ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertySet > rPropSet ) const; +public: + ScXMLCellExportPropertyMapper( + const UniReference< XMLPropertySetMapper >& rMapper ); + virtual ~ScXMLCellExportPropertyMapper(); + + /** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_EXPORT flag set */ + virtual void handleSpecialItem( + SvXMLAttributeList& rAttrList, + const XMLPropertyState& rProperty, + const SvXMLUnitConverter& rUnitConverter, + const SvXMLNamespaceMap& rNamespaceMap, + const ::std::vector< XMLPropertyState > *pProperties = 0, + sal_uInt32 nIdx = 0 ) const; +}; + +class ScXMLRowExportPropertyMapper : public SvXMLExportPropertyMapper +{ +protected: + /** Application-specific filter. By default do nothing. */ + virtual void ContextFilter( + ::std::vector< XMLPropertyState >& rProperties, + ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertySet > rPropSet ) const; +public: + ScXMLRowExportPropertyMapper( + const UniReference< XMLPropertySetMapper >& rMapper ); + virtual ~ScXMLRowExportPropertyMapper(); +}; + +class ScXMLColumnExportPropertyMapper : public SvXMLExportPropertyMapper +{ +public: + ScXMLColumnExportPropertyMapper( + const UniReference< XMLPropertySetMapper >& rMapper ); + virtual ~ScXMLColumnExportPropertyMapper(); + + /** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_EXPORT flag set */ + virtual void handleSpecialItem( + SvXMLAttributeList& rAttrList, + const XMLPropertyState& rProperty, + const SvXMLUnitConverter& rUnitConverter, + const SvXMLNamespaceMap& rNamespaceMap, + const ::std::vector< XMLPropertyState > *pProperties = 0, + sal_uInt32 nIdx = 0 ) const; +}; + +class ScXMLTableExportPropertyMapper : public SvXMLExportPropertyMapper +{ +protected: +public: + ScXMLTableExportPropertyMapper( + const UniReference< XMLPropertySetMapper >& rMapper ); + virtual ~ScXMLTableExportPropertyMapper(); + + /** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_EXPORT flag set */ + virtual void handleSpecialItem( + SvXMLAttributeList& rAttrList, + const XMLPropertyState& rProperty, + const SvXMLUnitConverter& rUnitConverter, + const SvXMLNamespaceMap& rNamespaceMap, + const ::std::vector< XMLPropertyState > *pProperties = 0, + sal_uInt32 nIdx = 0 ) const; +}; + +class ScXMLAutoStylePoolP : public SvXMLAutoStylePoolP +{ + ScXMLExport& rScXMLExport; + + virtual void exportStyleAttributes( + SvXMLAttributeList& rAttrList, + sal_Int32 nFamily, + const ::std::vector< XMLPropertyState >& rProperties, + const SvXMLExportPropertyMapper& rPropExp, + const SvXMLUnitConverter& rUnitConverter, + const SvXMLNamespaceMap& rNamespaceMap + ) const; + + virtual void exportStyleContent( + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > & rHandler, + sal_Int32 nFamily, + const ::std::vector< XMLPropertyState >& rProperties, + const SvXMLExportPropertyMapper& rPropExp + , const SvXMLUnitConverter& rUnitConverter, + const SvXMLNamespaceMap& rNamespaceMap + ) const; + +public: + ScXMLAutoStylePoolP(ScXMLExport& rScXMLExport); + virtual ~ScXMLAutoStylePoolP(); +}; + +class ScXMLStyleExport : public XMLStyleExport +{ + virtual void exportStyleAttributes( + const ::com::sun::star::uno::Reference< + ::com::sun::star::style::XStyle > & rStyle ); + virtual void exportStyleContent( + const ::com::sun::star::uno::Reference< + ::com::sun::star::style::XStyle > & rStyle ); +public: + ScXMLStyleExport( + SvXMLExport& rExp, + const ::rtl::OUString& rPoolStyleName, + SvXMLAutoStylePoolP *pAutoStyleP=0 ); + virtual ~ScXMLStyleExport(); +}; + +class XMLScPropHdlFactory : public XMLPropertyHandlerFactory +{ +public: + XMLScPropHdlFactory(); + virtual ~XMLScPropHdlFactory(); + virtual const XMLPropertyHandler* GetPropertyHandler( sal_Int32 nType ) const; +}; + +class XmlScPropHdl_CellProtection : public XMLPropertyHandler +{ +public: + virtual ~XmlScPropHdl_CellProtection(); + virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const; + virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; + virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; +}; + +class XmlScPropHdl_PrintContent : public XMLPropertyHandler +{ +public: + virtual ~XmlScPropHdl_PrintContent(); + virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const; + virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; + virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; +}; + +class XmlScPropHdl_HoriJustify : public XMLPropertyHandler +{ +public: + virtual ~XmlScPropHdl_HoriJustify(); + virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const; + virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; + virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; +}; + +class XmlScPropHdl_HoriJustifySource : public XMLPropertyHandler +{ +public: + virtual ~XmlScPropHdl_HoriJustifySource(); + virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const; + virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; + virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; +}; + +class XmlScPropHdl_HoriJustifyRepeat : public XMLPropertyHandler +{ +public: + virtual ~XmlScPropHdl_HoriJustifyRepeat(); + virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const; + virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; + virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; +}; + +class XmlScPropHdl_Orientation : public XMLPropertyHandler +{ +public: + virtual ~XmlScPropHdl_Orientation(); + virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const; + virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; + virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; +}; + +class XmlScPropHdl_RotateAngle : public XMLPropertyHandler +{ +public: + virtual ~XmlScPropHdl_RotateAngle(); + virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const; + virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; + virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; +}; + +class XmlScPropHdl_RotateReference : public XMLPropertyHandler +{ +public: + virtual ~XmlScPropHdl_RotateReference(); + virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const; + virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; + virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; +}; + +class XmlScPropHdl_VertJustify : public XMLPropertyHandler +{ +public: + virtual ~XmlScPropHdl_VertJustify(); + virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const; + virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; + virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; +}; + +class XmlScPropHdl_BreakBefore : public XMLPropertyHandler +{ +public: + virtual ~XmlScPropHdl_BreakBefore(); + virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const; + virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; + virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; +}; + +class XmlScPropHdl_IsTextWrapped : public XMLPropertyHandler +{ +public: + virtual ~XmlScPropHdl_IsTextWrapped(); + virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const; + virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; + virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; +}; + +class XmlScPropHdl_IsEqual : public XMLPropertyHandler +{ +public: + virtual ~XmlScPropHdl_IsEqual() {} + virtual bool equals( const ::com::sun::star::uno::Any& /* r1 */, const ::com::sun::star::uno::Any& /* r2 */ ) const { return sal_True; } + virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; + virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; +}; + +class XmlScPropHdl_Vertical : public XMLPropertyHandler +{ +public: + virtual ~XmlScPropHdl_Vertical(); + virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const; + virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; + virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const; +}; + +#endif diff --git a/sc/source/filter/xml/xmlstyli.cxx b/sc/source/filter/xml/xmlstyli.cxx new file mode 100644 index 000000000000..3866bba63239 --- /dev/null +++ b/sc/source/filter/xml/xmlstyli.cxx @@ -0,0 +1,1087 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + +#include "xmlstyli.hxx" +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/xmlimppr.hxx> +#include <xmloff/families.hxx> +#include <xmloff/xmlnumfi.hxx> +#include <xmloff/XMLGraphicsDefaultStyle.hxx> +#include <xmloff/xmltoken.hxx> +#include <com/sun/star/style/XStyleFamiliesSupplier.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/sheet/XSheetConditionalEntries.hpp> +#include <com/sun/star/table/BorderLine.hpp> +#include <comphelper/extract.hxx> +#include <xmloff/xmlprcon.hxx> +#include <xmloff/xmluconv.hxx> +#include <tools/debug.hxx> +#include "XMLTableHeaderFooterContext.hxx" +#include "XMLConverter.hxx" +#include "XMLTableShapeImportHelper.hxx" +#include "sheetdata.hxx" +#include "xmlannoi.hxx" +#include "textuno.hxx" +#include "cellsuno.hxx" + +#include "docuno.hxx" +#include "unonames.hxx" +#include "document.hxx" + +#define XML_LINE_LEFT 0 +#define XML_LINE_RIGHT 1 +#define XML_LINE_TOP 2 +#define XML_LINE_BOTTOM 3 + +#define XML_LINE_TLBR 0 +#define XML_LINE_BLTR 1 + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::xml::sax; +using namespace ::com::sun::star::style; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::container; +using namespace xmloff::token; +//using namespace ::com::sun::star::text; +using namespace ::formula; + +ScXMLCellImportPropertyMapper::ScXMLCellImportPropertyMapper( + const UniReference< XMLPropertySetMapper >& rMapper, + SvXMLImport& rImportP) : + SvXMLImportPropertyMapper( rMapper, rImportP ) +{ +} + +ScXMLCellImportPropertyMapper::~ScXMLCellImportPropertyMapper() +{ +} + +void ScXMLCellImportPropertyMapper::finished(::std::vector< XMLPropertyState >& rProperties, sal_Int32 nStartIndex, sal_Int32 nEndIndex ) const +{ + static const sal_Int16 aPaddingCTF[4] = { CTF_SC_LEFTPADDING, CTF_SC_RIGHTPADDING, + CTF_SC_TOPPADDING, CTF_SC_BOTTOMPADDING }; + static const sal_Int16 aBorderCTF[4] = { CTF_SC_LEFTBORDER, CTF_SC_RIGHTBORDER, + CTF_SC_TOPBORDER, CTF_SC_BOTTOMBORDER }; + + SvXMLImportPropertyMapper::finished(rProperties, nStartIndex, nEndIndex); + XMLPropertyState* pAllPaddingProperty(NULL); + XMLPropertyState* pPadding[4] = { NULL, NULL, NULL, NULL }; + XMLPropertyState* pNewPadding[4] = { NULL, NULL, NULL, NULL }; + XMLPropertyState* pAllBorderProperty = NULL; + XMLPropertyState* pBorders[4] = { NULL, NULL, NULL, NULL }; + XMLPropertyState* pNewBorders[4] = { NULL, NULL, NULL, NULL }; + XMLPropertyState* pAllBorderWidthProperty = NULL; + XMLPropertyState* pBorderWidths[4] = { NULL, NULL, NULL, NULL }; + XMLPropertyState* pDiagBorders[2] = { 0 }; + XMLPropertyState* pOldDiagBorderWidths[2] = { 0 }; // old attribute names without "s" + XMLPropertyState* pDiagBorderWidths[2] = { 0 }; + + ::std::vector< XMLPropertyState >::iterator endproperty(rProperties.end()); + for (::std::vector< XMLPropertyState >::iterator aIter = rProperties.begin(); + aIter != endproperty; ++aIter) + { + XMLPropertyState*property = &(*aIter); + if (property->mnIndex != -1) + { + sal_Int16 nContextID = getPropertySetMapper()->GetEntryContextId(property->mnIndex); + switch (nContextID) + { + case CTF_SC_ALLPADDING : pAllPaddingProperty = &*property; break; + case CTF_SC_LEFTPADDING : pPadding[XML_LINE_LEFT] = &*property; break; + case CTF_SC_RIGHTPADDING : pPadding[XML_LINE_RIGHT] = &*property; break; + case CTF_SC_TOPPADDING : pPadding[XML_LINE_TOP] = &*property; break; + case CTF_SC_BOTTOMPADDING : pPadding[XML_LINE_BOTTOM] = &*property; break; + case CTF_SC_ALLBORDER : pAllBorderProperty = &*property; break; + case CTF_SC_LEFTBORDER : pBorders[XML_LINE_LEFT] = &*property; break; + case CTF_SC_RIGHTBORDER : pBorders[XML_LINE_RIGHT] = &*property; break; + case CTF_SC_TOPBORDER : pBorders[XML_LINE_TOP] = &*property; break; + case CTF_SC_BOTTOMBORDER : pBorders[XML_LINE_BOTTOM] = &*property; break; + case CTF_SC_ALLBORDERWIDTH : pAllBorderWidthProperty = &*property; break; + case CTF_SC_LEFTBORDERWIDTH : pBorderWidths[XML_LINE_LEFT] = &*property; break; + case CTF_SC_RIGHTBORDERWIDTH : pBorderWidths[XML_LINE_RIGHT] = &*property; break; + case CTF_SC_TOPBORDERWIDTH : pBorderWidths[XML_LINE_TOP] = &*property; break; + case CTF_SC_BOTTOMBORDERWIDTH : pBorderWidths[XML_LINE_BOTTOM] = &*property; break; + case CTF_SC_DIAGONALTLBR : pDiagBorders[XML_LINE_TLBR] = &*property; break; + case CTF_SC_DIAGONALBLTR : pDiagBorders[XML_LINE_BLTR] = &*property; break; + case CTF_SC_DIAGONALTLBRWIDTH : pOldDiagBorderWidths[XML_LINE_TLBR] = &*property; break; + case CTF_SC_DIAGONALTLBRWIDTHS : pDiagBorderWidths[XML_LINE_TLBR] = &*property; break; + case CTF_SC_DIAGONALBLTRWIDTH : pOldDiagBorderWidths[XML_LINE_BLTR] = &*property; break; + case CTF_SC_DIAGONALBLTRWIDTHS : pDiagBorderWidths[XML_LINE_BLTR] = &*property; break; + } + } + } + sal_uInt16 i; + + // #i27594#; copy Value, but don't insert + if (pAllBorderWidthProperty) + pAllBorderWidthProperty->mnIndex = -1; + if (pAllBorderProperty) + pAllBorderProperty->mnIndex = -1; + if (pAllPaddingProperty) + pAllPaddingProperty->mnIndex = -1; + + for (i = 0; i < 4; ++i) + { + if (pAllPaddingProperty && !pPadding[i]) + pNewPadding[i] = new XMLPropertyState(maPropMapper->FindEntryIndex(aPaddingCTF[i]), pAllPaddingProperty->maValue); + if (pAllBorderProperty && !pBorders[i]) + { + pNewBorders[i] = new XMLPropertyState(maPropMapper->FindEntryIndex(aBorderCTF[i]), pAllBorderProperty->maValue); + pBorders[i] = pNewBorders[i]; + } + if( !pBorderWidths[i] ) + pBorderWidths[i] = pAllBorderWidthProperty; + else + pBorderWidths[i]->mnIndex = -1; + if( pBorders[i] ) + { + table::BorderLine aBorderLine; + pBorders[i]->maValue >>= aBorderLine; + if( pBorderWidths[i] ) + { + table::BorderLine aBorderLineWidth; + pBorderWidths[i]->maValue >>= aBorderLineWidth; + aBorderLine.OuterLineWidth = aBorderLineWidth.OuterLineWidth; + aBorderLine.InnerLineWidth = aBorderLineWidth.InnerLineWidth; + aBorderLine.LineDistance = aBorderLineWidth.LineDistance; + pBorders[i]->maValue <<= aBorderLine; + } + } + } + for( i = 0; i < 2; ++i ) + { + if( pDiagBorders[i] && ( pDiagBorderWidths[i] || pOldDiagBorderWidths[i] ) ) + { + table::BorderLine aBorderLine; + pDiagBorders[i]->maValue >>= aBorderLine; + table::BorderLine aBorderLineWidth; + if (pDiagBorderWidths[i]) + pDiagBorderWidths[i]->maValue >>= aBorderLineWidth; // prefer new attribute + else + pOldDiagBorderWidths[i]->maValue >>= aBorderLineWidth; + aBorderLine.OuterLineWidth = aBorderLineWidth.OuterLineWidth; + aBorderLine.InnerLineWidth = aBorderLineWidth.InnerLineWidth; + aBorderLine.LineDistance = aBorderLineWidth.LineDistance; + pDiagBorders[i]->maValue <<= aBorderLine; + if (pDiagBorderWidths[i]) + pDiagBorderWidths[i]->mnIndex = -1; + if (pOldDiagBorderWidths[i]) + pOldDiagBorderWidths[i]->mnIndex = -1; // reset mnIndex for old and new attribute if both are present + } + } + + for (i = 0; i < 4; ++i) + { + if (pNewPadding[i]) + { + rProperties.push_back(*pNewPadding[i]); + delete pNewPadding[i]; + } + if (pNewBorders[i]) + { + rProperties.push_back(*pNewBorders[i]); + delete pNewBorders[i]; + } + } +} + +ScXMLRowImportPropertyMapper::ScXMLRowImportPropertyMapper( + const UniReference< XMLPropertySetMapper >& rMapper, + SvXMLImport& rImportP) : + SvXMLImportPropertyMapper( rMapper, rImportP ) +{ +} + +ScXMLRowImportPropertyMapper::~ScXMLRowImportPropertyMapper() +{ +} + +void ScXMLRowImportPropertyMapper::finished(::std::vector< XMLPropertyState >& rProperties, sal_Int32 nStartIndex, sal_Int32 nEndIndex ) const +{ + SvXMLImportPropertyMapper::finished(rProperties, nStartIndex, nEndIndex); + XMLPropertyState* pHeight(NULL); + XMLPropertyState* pOptimalHeight(NULL); + XMLPropertyState* pPageBreak(NULL); + ::std::vector< XMLPropertyState >::iterator endproperty(rProperties.end()); + for (::std::vector< XMLPropertyState >::iterator aIter = rProperties.begin(); + aIter != endproperty; ++aIter) + { + XMLPropertyState* property = &(*aIter); + if (property->mnIndex != -1) + { + sal_Int16 nContextID = getPropertySetMapper()->GetEntryContextId(property->mnIndex); + switch (nContextID) + { + case CTF_SC_ROWHEIGHT : pHeight = property; break; + case CTF_SC_ROWOPTIMALHEIGHT : pOptimalHeight = property; break; + case CTF_SC_ROWBREAKBEFORE : pPageBreak = property; break; + } + } + } + if (pPageBreak) + { + if(!(::cppu::any2bool(pPageBreak->maValue))) + pPageBreak->mnIndex = -1; + } + if (pOptimalHeight) + { + if (::cppu::any2bool(pOptimalHeight->maValue)) + { + if (pHeight) + { + // set the stored height, but keep "optimal" flag: + // pass the height value as OptimalHeight property (only allowed while loading!) + pOptimalHeight->maValue = pHeight->maValue; + pHeight->mnIndex = -1; + } + else + pOptimalHeight->mnIndex = -1; + } + } + else if (pHeight) + { + rProperties.push_back(XMLPropertyState(maPropMapper->FindEntryIndex(CTF_SC_ROWOPTIMALHEIGHT), ::cppu::bool2any( sal_False ))); + } + // don't access pointers to rProperties elements after push_back! +} + +class ScXMLMapContext : public SvXMLImportContext +{ + rtl::OUString sApplyStyle; + rtl::OUString sCondition; + rtl::OUString sBaseCell; +public: + + ScXMLMapContext( + SvXMLImport& rImport, sal_uInt16 nPrfx, + const rtl::OUString& rLName, + const uno::Reference< xml::sax::XAttributeList > & xAttrList ); + virtual ~ScXMLMapContext(); + + const rtl::OUString& GetApplyStyle() const { return sApplyStyle; } + const rtl::OUString& GetCondition() const { return sCondition; } + const rtl::OUString& GetBaseCell() const { return sBaseCell; } +}; + +ScXMLMapContext::ScXMLMapContext(SvXMLImport& rImport, sal_uInt16 nPrfx, + const OUString& rLName, const uno::Reference< xml::sax::XAttributeList > & xAttrList ) + : SvXMLImportContext( rImport, nPrfx, rLName ) +{ + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const OUString& rAttrName(xAttrList->getNameByIndex( i )); + OUString aLocalName; + sal_uInt16 nPrefix(GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName )); + const OUString& rValue(xAttrList->getValueByIndex( i )); + + // TODO: use a map here + if( XML_NAMESPACE_STYLE == nPrefix ) + { + if( IsXMLToken(aLocalName, XML_CONDITION ) ) + sCondition = rValue; + else if( IsXMLToken(aLocalName, XML_APPLY_STYLE_NAME ) ) + sApplyStyle = GetImport().GetStyleDisplayName( XML_STYLE_FAMILY_TABLE_CELL, rValue); + else if ( IsXMLToken(aLocalName, XML_BASE_CELL_ADDRESS ) ) + sBaseCell = rValue; + } + } +} + +ScXMLMapContext::~ScXMLMapContext() +{ +} + +namespace { + +template< typename Type > +inline void lclAppendProperty( uno::Sequence< beans::PropertyValue >& rProps, const OUString& rPropName, const Type& rValue ) +{ + sal_Int32 nLength = rProps.getLength(); + rProps.realloc( nLength + 1 ); + rProps[ nLength ].Name = rPropName; + rProps[ nLength ].Value <<= rValue; +} + +} // namespace + +void XMLTableStyleContext::SetOperator( uno::Sequence< beans::PropertyValue >& rProps, sheet::ConditionOperator eOp ) const +{ + lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_OPERATOR ) ), eOp ); +} + +void XMLTableStyleContext::SetBaseCellAddress( uno::Sequence< beans::PropertyValue >& rProps, const OUString& rBaseCell ) const +{ + /* #b4974740# Source position must be set as string, because it may refer + to a sheet that hasn't been loaded yet. */ + lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_SOURCESTR ) ), rBaseCell ); +} + +void XMLTableStyleContext::SetStyle( uno::Sequence<beans::PropertyValue>& rProps, const OUString& rApplyStyle ) const +{ + lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_STYLENAME ) ), rApplyStyle ); +} + +void XMLTableStyleContext::SetFormula( uno::Sequence< beans::PropertyValue >& rProps, + sal_Int32 nFormulaIdx, const OUString& rFormula, const OUString& rFormulaNmsp, + FormulaGrammar::Grammar eGrammar, bool bHasNmsp ) const +{ + OUString aFormula, aFormulaNmsp; + FormulaGrammar::Grammar eNewGrammar = FormulaGrammar::GRAM_UNSPECIFIED; + if( bHasNmsp ) + { + // the entire attribute contains a namespace: internal namespace not allowed + aFormula = rFormula; + aFormulaNmsp = rFormulaNmsp; + eNewGrammar = eGrammar; + } + else + { + // the attribute does not contain a namespace: try to find a namespace of an external grammar + GetScImport().ExtractFormulaNamespaceGrammar( aFormula, aFormulaNmsp, eNewGrammar, rFormula, true ); + if( eNewGrammar != FormulaGrammar::GRAM_EXTERNAL ) + eNewGrammar = eGrammar; + } + + // add formula, formula namespace, and grammar with appropriate property names + sal_Int32 nGrammar = static_cast< sal_Int32 >( eNewGrammar ); + switch( nFormulaIdx ) + { + case 1: + lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FORMULA1 ) ), aFormula ); + lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FORMULANMSP1 ) ), aFormulaNmsp ); + lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_GRAMMAR1 ) ), nGrammar ); + break; + case 2: + lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FORMULA2 ) ), aFormula ); + lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_FORMULANMSP2 ) ), aFormulaNmsp ); + lclAppendProperty( rProps, OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_GRAMMAR2 ) ), nGrammar ); + break; + default: + OSL_ENSURE( false, "XMLTableStyleContext::SetFormula - invalid formula index" ); + } +} + +void XMLTableStyleContext::GetConditionalFormat(uno::Any& aAny, + const rtl::OUString& sTempCondition, + const rtl::OUString& sApplyStyle, const rtl::OUString& sBaseCell) const +{ + if (sTempCondition.getLength() && sApplyStyle.getLength()) + { + uno::Reference<sheet::XSheetConditionalEntries> xConditionalEntries(aAny, uno::UNO_QUERY); + if (xConditionalEntries.is()) + { + uno::Sequence<beans::PropertyValue> aProps; + if (sBaseCell.getLength()) + SetBaseCellAddress(aProps, sBaseCell); + SetStyle(aProps, sApplyStyle); + + // extract leading namespace from condition string + OUString aCondition, aConditionNmsp; + FormulaGrammar::Grammar eGrammar = FormulaGrammar::GRAM_UNSPECIFIED; + GetScImport().ExtractFormulaNamespaceGrammar( aCondition, aConditionNmsp, eGrammar, sTempCondition ); + bool bHasNmsp = aCondition.getLength() < sTempCondition.getLength(); + + // parse a condition from the attribute string + ScXMLConditionParseResult aParseResult; + ScXMLConditionHelper::parseCondition( aParseResult, aCondition, 0 ); + + /* Check the result. A valid value in aParseResult.meToken implies + that the other members of aParseResult are filled with valid + data for that token. */ + switch( aParseResult.meToken ) + { + case XML_COND_CELLCONTENT: // condition is 'cell-content()<operator><expression>' + case XML_COND_ISTRUEFORMULA: // condition is 'is-true-formula(<expression>)' + case XML_COND_ISBETWEEN: // condition is 'cell-content-is-between(<expression1>,<expression2>)' + case XML_COND_ISNOTBETWEEN: // condition is 'cell-content-is-not-between(<expression1>,<expression2>)' + SetOperator( aProps, aParseResult.meOperator ); + SetFormula( aProps, 1, aParseResult.maOperand1, aConditionNmsp, eGrammar, bHasNmsp ); + SetFormula( aProps, 2, aParseResult.maOperand2, aConditionNmsp, eGrammar, bHasNmsp ); + break; + + default:; // unacceptable or unknown condition + } + + xConditionalEntries->addNew( aProps ); + aAny <<= xConditionalEntries; + } + } +} + +void XMLTableStyleContext::SetAttribute( sal_uInt16 nPrefixKey, + const OUString& rLocalName, + const OUString& rValue ) +{ + // TODO: use a map here + if( IsXMLToken(rLocalName, XML_DATA_STYLE_NAME ) ) + sDataStyleName = rValue; + else if ( IsXMLToken(rLocalName, XML_MASTER_PAGE_NAME ) ) + sPageStyle = rValue; + else + XMLPropStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue ); +} + +struct ScXMLMapContent +{ + rtl::OUString sCondition; + rtl::OUString sApplyStyle; + rtl::OUString sBaseCell; +}; + +TYPEINIT1( XMLTableStyleContext, XMLPropStyleContext ); + +XMLTableStyleContext::XMLTableStyleContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, const OUString& rLName, + const uno::Reference< XAttributeList > & xAttrList, + SvXMLStylesContext& rStyles, sal_uInt16 nFamily, sal_Bool bDefaultStyle ) : + XMLPropStyleContext( rImport, nPrfx, rLName, xAttrList, rStyles, nFamily, bDefaultStyle ), + sDataStyleName(), + sNumberFormat(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NumberFormat"))), + pStyles(&rStyles), + nNumberFormat(-1), + nLastSheet(-1), + bConditionalFormatCreated(sal_False), + bParentSet(sal_False) +{ +} + +XMLTableStyleContext::~XMLTableStyleContext() +{ +} + +SvXMLImportContext *XMLTableStyleContext::CreateChildContext( + sal_uInt16 nPrefix, + const OUString& rLocalName, + const uno::Reference< XAttributeList > & xAttrList ) +{ + SvXMLImportContext *pContext(NULL); + + if( (XML_NAMESPACE_STYLE == nPrefix) && + IsXMLToken(rLocalName, XML_MAP ) ) + { + pContext = new ScXMLMapContext(GetImport(), nPrefix, rLocalName, xAttrList); + + ScXMLMapContent aMap; + aMap.sCondition = ((ScXMLMapContext*)pContext)->GetCondition(); + aMap.sApplyStyle = ((ScXMLMapContext*)pContext)->GetApplyStyle(); + aMap.sBaseCell = ((ScXMLMapContext*)pContext)->GetBaseCell(); + aMaps.push_back(aMap); + } + if (!pContext) + pContext = XMLPropStyleContext::CreateChildContext( nPrefix, rLocalName, + xAttrList ); + return pContext; +} + +void XMLTableStyleContext::FillPropertySet( + const uno::Reference< XPropertySet > & rPropSet ) +{ + if (!IsDefaultStyle()) + { + if (GetFamily() == XML_STYLE_FAMILY_TABLE_CELL) + { + if (!bParentSet) + { + AddProperty(CTF_SC_CELLSTYLE, uno::makeAny(GetImport().GetStyleDisplayName( XML_STYLE_FAMILY_TABLE_CELL, GetParentName() ))); + bParentSet = sal_True; + } + sal_Int32 nNumFmt = GetNumberFormat(); + if (nNumFmt >= 0) + AddProperty(CTF_SC_NUMBERFORMAT, uno::makeAny(nNumFmt)); + if (!bConditionalFormatCreated && (aMaps.size() > 0)) + { + aConditionalFormat = rPropSet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CONDXML))); + std::vector<ScXMLMapContent>::iterator aItr(aMaps.begin()); + std::vector<ScXMLMapContent>::iterator aEndItr(aMaps.end()); + while(aItr != aEndItr) + { + //rPropSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_CONDITIONALFORMAT)), + GetConditionalFormat(aConditionalFormat, aItr->sCondition, aItr->sApplyStyle, aItr->sBaseCell); + + ++aItr; + } + AddProperty(CTF_SC_IMPORT_MAP, aConditionalFormat); + bConditionalFormatCreated = sal_True; + } + } + else if (GetFamily() == XML_STYLE_FAMILY_TABLE_TABLE) + { + if (sPageStyle.getLength()) + AddProperty(CTF_SC_MASTERPAGENAME, uno::makeAny(GetImport().GetStyleDisplayName( XML_STYLE_FAMILY_MASTER_PAGE, sPageStyle ))); + } + } + XMLPropStyleContext::FillPropertySet(rPropSet); +} + +void XMLTableStyleContext::SetDefaults() +{ + if ((GetFamily() == XML_STYLE_FAMILY_TABLE_CELL) && GetImport().GetModel().is()) + { + uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetImport().GetModel(), uno::UNO_QUERY); + if (xMultiServiceFactory.is()) + { + uno::Reference <beans::XPropertySet> xProperties(xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.Defaults"))), uno::UNO_QUERY); + if (xProperties.is()) + FillPropertySet(xProperties); + } + } +} + +void XMLTableStyleContext::AddProperty(const sal_Int16 nContextID, const uno::Any& rValue) +{ + XMLPropertyState* property = FindProperty(nContextID); + if (property) + property->mnIndex = -1; // #i46996# remove old property, so it isn't double + sal_Int32 nIndex(static_cast<XMLTableStylesContext *>(pStyles)->GetIndex(nContextID)); + DBG_ASSERT(nIndex != -1, "Property not found in Map"); + XMLPropertyState aPropState(nIndex, rValue); + GetProperties().push_back(aPropState); // has to be insertes in a sort order later +} + +XMLPropertyState* XMLTableStyleContext::FindProperty(const sal_Int16 nContextID) +{ + XMLPropertyState* pRet = NULL; + UniReference < XMLPropertySetMapper > xPrMap; + UniReference < SvXMLImportPropertyMapper > xImpPrMap = + pStyles->GetImportPropertyMapper( GetFamily() ); + DBG_ASSERT( xImpPrMap.is(), "There is the import prop mapper" ); + if( xImpPrMap.is() ) + xPrMap = xImpPrMap->getPropertySetMapper(); + if( xPrMap.is() ) + { + ::std::vector< XMLPropertyState >::iterator endproperty(GetProperties().end()); + ::std::vector< XMLPropertyState >::iterator aIter(GetProperties().begin()); + while(!pRet && aIter != endproperty) + { + XMLPropertyState* property = &(*aIter); + if (property->mnIndex != -1 && xPrMap->GetEntryContextId(property->mnIndex) == nContextID) + { + pRet = property; + } + else + ++aIter; + } + } + return pRet; +} + +sal_Int32 XMLTableStyleContext::GetNumberFormat() +{ + if (nNumberFormat < 0 && sDataStyleName.getLength()) + { + const SvXMLNumFormatContext* pStyle = static_cast<const SvXMLNumFormatContext*>( + pStyles->FindStyleChildContext(XML_STYLE_FAMILY_DATA_STYLE, sDataStyleName, sal_True)); + + if (!pStyle) + { + XMLTableStylesContext* pMyStyles = static_cast<XMLTableStylesContext*>(GetScImport().GetStyles()); + if (pMyStyles) + pStyle = static_cast<const SvXMLNumFormatContext*>( + pMyStyles->FindStyleChildContext(XML_STYLE_FAMILY_DATA_STYLE, sDataStyleName, sal_True)); + else + { + DBG_ERROR("not possible to get style"); + } + } + if (pStyle) + nNumberFormat = const_cast<SvXMLNumFormatContext*>(pStyle)->GetKey(); + } + return nNumberFormat; +} + +// ---------------------------------------------------------------------------- + +SvXMLStyleContext *XMLTableStylesContext::CreateStyleStyleChildContext( + sal_uInt16 nFamily, sal_uInt16 nPrefix, const OUString& rLocalName, + const uno::Reference< xml::sax::XAttributeList > & xAttrList ) +{ + SvXMLStyleContext *pStyle; + // use own wrapper for text and paragraph, to record style usage + if (nFamily == XML_STYLE_FAMILY_TEXT_PARAGRAPH || nFamily == XML_STYLE_FAMILY_TEXT_TEXT) + pStyle = new ScCellTextStyleContext( GetImport(), nPrefix, rLocalName, + xAttrList, *this, nFamily ); + else + pStyle = SvXMLStylesContext::CreateStyleStyleChildContext( + nFamily, nPrefix, rLocalName, xAttrList ); + + if (!pStyle) + { + switch( nFamily ) + { + case XML_STYLE_FAMILY_TABLE_CELL: + case XML_STYLE_FAMILY_TABLE_COLUMN: + case XML_STYLE_FAMILY_TABLE_ROW: + case XML_STYLE_FAMILY_TABLE_TABLE: + pStyle = new XMLTableStyleContext( GetScImport(), nPrefix, rLocalName, + xAttrList, *this, nFamily ); + break; + } + } + + return pStyle; +} + +SvXMLStyleContext *XMLTableStylesContext::CreateDefaultStyleStyleChildContext( + sal_uInt16 nFamily, sal_uInt16 nPrefix, const OUString& rLocalName, + const uno::Reference< xml::sax::XAttributeList > & xAttrList ) +{ + SvXMLStyleContext *pStyle(SvXMLStylesContext::CreateDefaultStyleStyleChildContext( nFamily, nPrefix, + rLocalName, + xAttrList )); + if (!pStyle) + { + switch( nFamily ) + { + case XML_STYLE_FAMILY_TABLE_CELL: + pStyle = new XMLTableStyleContext( GetScImport(), nPrefix, rLocalName, + xAttrList, *this, nFamily, sal_True); + break; + case XML_STYLE_FAMILY_SD_GRAPHICS_ID: + pStyle = new XMLGraphicsDefaultStyle( GetScImport(), nPrefix, rLocalName, + xAttrList, *this); + break; + } + } + + return pStyle; +} + +XMLTableStylesContext::XMLTableStylesContext( SvXMLImport& rImport, + sal_uInt16 nPrfx , + const OUString& rLName , + const uno::Reference< XAttributeList > & xAttrList, + const sal_Bool bTempAutoStyles ) : + SvXMLStylesContext( rImport, nPrfx, rLName, xAttrList ), + sCellStyleServiceName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.style.CellStyle" ) )), + sColumnStyleServiceName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_NAME ))), + sRowStyleServiceName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( XML_STYLE_FAMILY_TABLE_ROW_STYLES_NAME ))), + sTableStyleServiceName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( XML_STYLE_FAMILY_TABLE_TABLE_STYLES_NAME ))), + nNumberFormatIndex(-1), + nConditionalFormatIndex(-1), + nCellStyleIndex(-1), + nMasterPageNameIndex(-1), + bAutoStyles(bTempAutoStyles) +{ +} + +XMLTableStylesContext::~XMLTableStylesContext() +{ +} + +void XMLTableStylesContext::EndElement() +{ + SvXMLStylesContext::EndElement(); + if (bAutoStyles) + GetImport().GetTextImport()->SetAutoStyles( this ); + else + ((ScXMLImport&)GetImport()).InsertStyles(); +} + +UniReference < SvXMLImportPropertyMapper > + XMLTableStylesContext::GetImportPropertyMapper( + sal_uInt16 nFamily ) const +{ + UniReference < SvXMLImportPropertyMapper > xMapper(SvXMLStylesContext::GetImportPropertyMapper(nFamily)); + + if (!xMapper.is()) + { + switch( nFamily ) + { + case XML_STYLE_FAMILY_TABLE_CELL: + { + if( !xCellImpPropMapper.is() ) + { + ((XMLTableStylesContext *)this)->xCellImpPropMapper = + new ScXMLCellImportPropertyMapper( GetScImport().GetCellStylesPropertySetMapper(), const_cast<SvXMLImport&>(GetImport()) ); + xCellImpPropMapper->ChainImportMapper(XMLTextImportHelper::CreateParaExtPropMapper(const_cast<SvXMLImport&>(GetImport()), const_cast<XMLFontStylesContext*>(GetScImport().GetFontDecls()))); + } + xMapper = xCellImpPropMapper; + } + break; + case XML_STYLE_FAMILY_TABLE_COLUMN: + { + if( !xColumnImpPropMapper.is() ) + ((XMLTableStylesContext *)this)->xColumnImpPropMapper = + new SvXMLImportPropertyMapper( GetScImport().GetColumnStylesPropertySetMapper(), const_cast<SvXMLImport&>(GetImport()) ); + xMapper = xColumnImpPropMapper; + } + break; + case XML_STYLE_FAMILY_TABLE_ROW: + { + if( !xRowImpPropMapper.is() ) + ((XMLTableStylesContext *)this)->xRowImpPropMapper = + new ScXMLRowImportPropertyMapper( GetScImport().GetRowStylesPropertySetMapper(), const_cast<SvXMLImport&>(GetImport()) ); + xMapper = xRowImpPropMapper; + } + break; + case XML_STYLE_FAMILY_TABLE_TABLE: + { + if( !xTableImpPropMapper.is() ) + ((XMLTableStylesContext *)this)->xTableImpPropMapper = + new SvXMLImportPropertyMapper( GetScImport().GetTableStylesPropertySetMapper(), const_cast<SvXMLImport&>(GetImport()) ); + xMapper = xTableImpPropMapper; + } + break; + } + } + + return xMapper; +} + +uno::Reference < XNameContainer > + XMLTableStylesContext::GetStylesContainer( sal_uInt16 nFamily ) const +{ + uno::Reference < XNameContainer > xStyles(SvXMLStylesContext::GetStylesContainer(nFamily)); + if (!xStyles.is()) + { + OUString sName; + switch( nFamily ) + { + case XML_STYLE_FAMILY_TABLE_TABLE: + { + if( xTableStyles.is() ) + xStyles.set(xTableStyles); + else + sName = + OUString( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "TableStyles" ) )); + } + break; + case XML_STYLE_FAMILY_TABLE_CELL: + { + if( xCellStyles.is() ) + xStyles.set(xCellStyles); + else + sName = + OUString( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "CellStyles" ) )); + } + break; + case XML_STYLE_FAMILY_TABLE_COLUMN: + { + if( xColumnStyles.is() ) + xStyles.set(xColumnStyles); + else + sName = + OUString( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ColumnStyles" ) )); + } + break; + case XML_STYLE_FAMILY_TABLE_ROW: + { + if( xRowStyles.is() ) + xStyles.set(xRowStyles); + else + sName = + OUString( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "RowStyles" ) )); + } + break; + } + if( !xStyles.is() && sName.getLength() && GetScImport().GetModel().is() ) + { + uno::Reference< XStyleFamiliesSupplier > xFamiliesSupp( + GetScImport().GetModel(), UNO_QUERY ); + if (xFamiliesSupp.is()) + { + uno::Reference< XNameAccess > xFamilies(xFamiliesSupp->getStyleFamilies()); + + try + { + xStyles.set(xFamilies->getByName( sName ), uno::UNO_QUERY); + } + catch ( uno::Exception& ) + { + // #i97680# Named table/column/row styles aren't supported, getByName will throw an exception. + // For better interoperability, these styles should then be handled as automatic styles. + // For now, NULL is returned (and the style is ignored). + } + switch( nFamily ) + { + case XML_STYLE_FAMILY_TABLE_TABLE: + ((XMLTableStylesContext *)this)->xTableStyles.set(xStyles); + break; + case XML_STYLE_FAMILY_TABLE_CELL: + ((XMLTableStylesContext *)this)->xCellStyles.set(xStyles); + break; + case XML_STYLE_FAMILY_TABLE_COLUMN: + ((XMLTableStylesContext *)this)->xColumnStyles.set(xStyles); + break; + case XML_STYLE_FAMILY_TABLE_ROW: + ((XMLTableStylesContext *)this)->xRowStyles.set(xStyles); + break; + } + } + } + } + + return xStyles; +} + +OUString XMLTableStylesContext::GetServiceName( sal_uInt16 nFamily ) const +{ + rtl::OUString sServiceName(SvXMLStylesContext::GetServiceName(nFamily)); + if (!sServiceName.getLength()) + { + switch( nFamily ) + { + case XML_STYLE_FAMILY_TABLE_COLUMN: + sServiceName = sColumnStyleServiceName; + break; + case XML_STYLE_FAMILY_TABLE_ROW: + sServiceName = sRowStyleServiceName; + break; + case XML_STYLE_FAMILY_TABLE_CELL: + sServiceName = sCellStyleServiceName; + break; + case XML_STYLE_FAMILY_TABLE_TABLE: + sServiceName = sTableStyleServiceName; + break; + } + } + return sServiceName; +} + +sal_Int32 XMLTableStylesContext::GetIndex(const sal_Int16 nContextID) +{ + if (nContextID == CTF_SC_CELLSTYLE) + { + if (nCellStyleIndex == -1) + nCellStyleIndex = + GetImportPropertyMapper(XML_STYLE_FAMILY_TABLE_CELL)->getPropertySetMapper()->FindEntryIndex(nContextID); + return nCellStyleIndex; + } + else if (nContextID == CTF_SC_NUMBERFORMAT) + { + if (nNumberFormatIndex == -1) + nNumberFormatIndex = + GetImportPropertyMapper(XML_STYLE_FAMILY_TABLE_CELL)->getPropertySetMapper()->FindEntryIndex(nContextID); + return nNumberFormatIndex; + } + else if (nContextID == CTF_SC_IMPORT_MAP) + { + if (nConditionalFormatIndex == -1) + nConditionalFormatIndex = + GetImportPropertyMapper(XML_STYLE_FAMILY_TABLE_CELL)->getPropertySetMapper()->FindEntryIndex(nContextID); + return nConditionalFormatIndex; + } + else if (nContextID == CTF_SC_MASTERPAGENAME) + { + if (nMasterPageNameIndex == -1) + nMasterPageNameIndex = + GetImportPropertyMapper(XML_STYLE_FAMILY_TABLE_TABLE)->getPropertySetMapper()->FindEntryIndex(nContextID); + return nMasterPageNameIndex; + } + else + return -1; +} + +// --------------------------------------------------------------------------- +TYPEINIT1( ScXMLMasterStylesContext, SvXMLStylesContext ); + +sal_Bool ScXMLMasterStylesContext::InsertStyleFamily( sal_uInt16 ) const +{ + return sal_True; +} + +ScXMLMasterStylesContext::ScXMLMasterStylesContext( + SvXMLImport& rImport, + sal_uInt16 nPrfx, const OUString& rLName, + const uno::Reference< XAttributeList > & xAttrList ) : + SvXMLStylesContext( rImport, nPrfx, rLName, xAttrList ) +{ +} + +ScXMLMasterStylesContext::~ScXMLMasterStylesContext() +{ +} + +SvXMLStyleContext *ScXMLMasterStylesContext::CreateStyleChildContext( + sal_uInt16 nPrefix, + const OUString& rLocalName, + const uno::Reference< XAttributeList > & xAttrList ) +{ + SvXMLStyleContext *pContext(0); + + if( (XML_NAMESPACE_STYLE == nPrefix) && + IsXMLToken(rLocalName, XML_MASTER_PAGE) && + InsertStyleFamily( XML_STYLE_FAMILY_MASTER_PAGE ) ) + pContext = new ScMasterPageContext( + GetImport(), nPrefix, rLocalName, xAttrList, + !GetImport().GetTextImport()->IsInsertMode() ); + + // any other style will be ignored here! + + return pContext; +} + +SvXMLStyleContext *ScXMLMasterStylesContext::CreateStyleStyleChildContext( + sal_uInt16 /* nFamily */, + sal_uInt16 /* nPrefix */, + const OUString& /* rLocalName */, + const uno::Reference< XAttributeList > & /* xAttrList */ ) +{ + return 0; +} + +void ScXMLMasterStylesContext::EndElement() +{ + FinishStyles(sal_True); +} + +TYPEINIT1( ScMasterPageContext, XMLTextMasterPageContext ); + +ScMasterPageContext::ScMasterPageContext( SvXMLImport& rImport, + sal_uInt16 nPrfx, const OUString& rLName, + const uno::Reference< XAttributeList > & xAttrList, + sal_Bool bOverwrite ) : + XMLTextMasterPageContext( rImport, nPrfx, rLName, xAttrList, bOverwrite ), + bContainsRightHeader(sal_False), + bContainsRightFooter(sal_False) +{ +} + +ScMasterPageContext::~ScMasterPageContext() +{ +} + +SvXMLImportContext *ScMasterPageContext::CreateChildContext( + sal_uInt16 nPrefix, + const OUString& rLocalName, + const uno::Reference< XAttributeList > & xAttrList ) +{ + return XMLTextMasterPageContext::CreateChildContext( nPrefix, rLocalName, xAttrList ); +} + +SvXMLImportContext *ScMasterPageContext::CreateHeaderFooterContext( + sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList, + const sal_Bool bFooter, + const sal_Bool bLeft ) +{ + if (!bLeft) + { + if (bFooter) + bContainsRightFooter = sal_True; + else + bContainsRightHeader = sal_True; + } + if (!xPropSet.is()) + xPropSet.set(GetStyle(), UNO_QUERY ); + return new XMLTableHeaderFooterContext( GetImport(), + nPrefix, rLocalName, + xAttrList, + xPropSet, + bFooter, bLeft ); +} + +void ScMasterPageContext::ClearContent(const rtl::OUString& rContent) +{ + if (!xPropSet.is()) + xPropSet.set(GetStyle(), UNO_QUERY ); + + if (xPropSet.is()) + { + uno::Reference < sheet::XHeaderFooterContent > xHeaderFooterContent(xPropSet->getPropertyValue( rContent ), uno::UNO_QUERY); + if (xHeaderFooterContent.is()) + { + xHeaderFooterContent->getLeftText()->setString(sEmpty); + xHeaderFooterContent->getCenterText()->setString(sEmpty); + xHeaderFooterContent->getRightText()->setString(sEmpty); + xPropSet->setPropertyValue( rContent, uno::makeAny(xHeaderFooterContent) ); + } + } +} + +void ScMasterPageContext::Finish( sal_Bool bOverwrite ) +{ + XMLTextMasterPageContext::Finish(bOverwrite); + if (!bContainsRightFooter) + ClearContent(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_PAGE_RIGHTFTRCON))); + if (!bContainsRightHeader) + ClearContent(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_PAGE_RIGHTHDRCON))); +} + +// --------------------------------------------------------------------------- + +ScCellTextStyleContext::ScCellTextStyleContext( SvXMLImport& rImport, sal_uInt16 nPrfx, + const rtl::OUString& rLName, const uno::Reference<xml::sax::XAttributeList> & xAttrList, + SvXMLStylesContext& rStyles, sal_uInt16 nFamily, sal_Bool bDefaultStyle ) : + XMLTextStyleContext( rImport, nPrfx, rLName, xAttrList, rStyles, nFamily, bDefaultStyle ), + nLastSheet(-1) +{ +} + +ScCellTextStyleContext::~ScCellTextStyleContext() +{ +} + +void ScCellTextStyleContext::FillPropertySet( const uno::Reference<beans::XPropertySet>& xPropSet ) +{ + XMLTextStyleContext::FillPropertySet( xPropSet ); + + ScXMLImport& rXMLImport = GetScImport(); + + ScCellTextCursor* pCellImp = ScCellTextCursor::getImplementation( xPropSet ); + if (pCellImp) + { + ScAddress aPos = pCellImp->GetCellObj().GetPosition(); + if ( static_cast<sal_Int32>(aPos.Tab()) != nLastSheet ) + { + ESelection aSel = pCellImp->GetSelection(); + + ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetImport().GetModel())->GetSheetSaveData(); + pSheetData->AddTextStyle( GetName(), aPos, aSel ); + + nLastSheet = static_cast<sal_Int32>(aPos.Tab()); + } + } + else if ( rXMLImport.GetTables().GetCurrentSheet() != nLastSheet ) + { + ScDrawTextCursor* pDrawImp = ScDrawTextCursor::getImplementation( xPropSet ); + if (pDrawImp) + { + XMLTableShapeImportHelper* pTableShapeImport = (XMLTableShapeImportHelper*)GetScImport().GetShapeImport().get(); + ScXMLAnnotationContext* pAnnotationContext = pTableShapeImport->GetAnnotationContext(); + if (pAnnotationContext) + { + pAnnotationContext->AddContentStyle( GetFamily(), GetName(), pDrawImp->GetSelection() ); + nLastSheet = rXMLImport.GetTables().GetCurrentSheet(); + } + } + + // if it's a different shape, BlockSheet is called from XMLTableShapeImportHelper::finishShape + // formatted text in page headers/footers can be ignored + } +} + diff --git a/sc/source/filter/xml/xmlstyli.hxx b/sc/source/filter/xml/xmlstyli.hxx new file mode 100644 index 000000000000..b2a8589f5524 --- /dev/null +++ b/sc/source/filter/xml/xmlstyli.hxx @@ -0,0 +1,329 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLSTYLI_HXX +#define SC_XMLSTYLI_HXX + +#include <rtl/ustring.hxx> +#include <vector> +#include <xmloff/xmlimp.hxx> +#include <xmloff/xmlictxt.hxx> +#include <xmloff/maptype.hxx> +#include <xmloff/prstylei.hxx> +#include <xmloff/xmlimppr.hxx> +#include <xmloff/XMLTextMasterPageContext.hxx> +#include <xmloff/XMLTextMasterStylesContext.hxx> +#include <xmloff/txtstyli.hxx> +#include <com/sun/star/sheet/ConditionOperator.hpp> +#include "xmlimprt.hxx" + +class ScSheetSaveData; + +class ScXMLCellImportPropertyMapper : public SvXMLImportPropertyMapper +{ +protected: + +public: + + ScXMLCellImportPropertyMapper( + const UniReference< XMLPropertySetMapper >& rMapper, + SvXMLImport& rImport); + virtual ~ScXMLCellImportPropertyMapper(); + + /** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_IMPORT flag set */ +/* virtual sal_Bool handleSpecialItem( + XMLPropertyState& rProperty, + ::std::vector< XMLPropertyState >& rProperties, + const ::rtl::OUString& rValue, + const SvXMLUnitConverter& rUnitConverter, + const SvXMLNamespaceMap& rNamespaceMap ) const;*/ + + /** this method is called for every item that has the MID_FLAG_NO_ITEM_IMPORT flag set */ +/* virtual sal_Bool handleNoItem( + sal_Int32 nIndex, + ::std::vector< XMLPropertyState >& rProperties, + const ::rtl::OUString& rValue, + const SvXMLUnitConverter& rUnitConverter, + const SvXMLNamespaceMap& rNamespaceMap ) const;*/ + + /** This method is called when all attributes have been processed. It may be used to remove items that are incomplete */ + virtual void finished( + ::std::vector< XMLPropertyState >& rProperties, sal_Int32 nStartIndex, sal_Int32 nEndIndex ) const; +}; + +class ScXMLRowImportPropertyMapper : public SvXMLImportPropertyMapper +{ +protected: + +public: + + ScXMLRowImportPropertyMapper( + const UniReference< XMLPropertySetMapper >& rMapper, + SvXMLImport& rImport); + virtual ~ScXMLRowImportPropertyMapper(); + + /** This method is called when all attributes have been processed. It may be used to remove items that are incomplete */ + virtual void finished( + ::std::vector< XMLPropertyState >& rProperties, sal_Int32 nStartIndex, sal_Int32 nEndIndex ) const; +}; +struct ScXMLMapContent; + +class XMLTableStyleContext : public XMLPropStyleContext +{ + ::rtl::OUString sDataStyleName; + rtl::OUString sPageStyle; + const rtl::OUString sNumberFormat; + SvXMLStylesContext* pStyles; + std::vector<ScXMLMapContent> aMaps; + com::sun::star::uno::Any aConditionalFormat; + sal_Int32 nNumberFormat; + sal_Int32 nLastSheet; + sal_Bool bConditionalFormatCreated; + sal_Bool bParentSet; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + + void SetOperator( + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rProps, + ::com::sun::star::sheet::ConditionOperator eOp ) const; + + void SetBaseCellAddress( + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rProps, + const ::rtl::OUString& rBaseCell ) const; + + void SetStyle( + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rProps, + const ::rtl::OUString& rApplyStyle ) const; + + void SetFormula( + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rProps, + sal_Int32 nFormulaIdx, const ::rtl::OUString& rFormula, + const ::rtl::OUString& rFormulaNmsp, ::formula::FormulaGrammar::Grammar eGrammar, bool bHasNmsp ) const; + + void GetConditionalFormat( + ::com::sun::star::uno::Any& aAny, const rtl::OUString& sCondition, + const rtl::OUString& sApplyStyle, const rtl::OUString& sBaseCell) const; +protected: + + virtual void SetAttribute( sal_uInt16 nPrefixKey, + const ::rtl::OUString& rLocalName, + const ::rtl::OUString& rValue ); + +public: + + TYPEINFO(); + + XMLTableStyleContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList, + SvXMLStylesContext& rStyles, sal_uInt16 nFamily, sal_Bool bDefaultStyle = sal_False ); + virtual ~XMLTableStyleContext(); + + virtual SvXMLImportContext *CreateChildContext( + sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList ); + + virtual void FillPropertySet(const ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertySet > & rPropSet ); + + virtual void SetDefaults(); + + void AddProperty(sal_Int16 nContextID, const com::sun::star::uno::Any& aValue); + XMLPropertyState* FindProperty(const sal_Int16 nContextID); + + sal_Int32 GetNumberFormat();// { return nNumberFormat; } + + sal_Int32 GetLastSheet() const { return nLastSheet; } + void SetLastSheet(sal_Int32 nNew) { nLastSheet = nNew; } + +private: + using XMLPropStyleContext::SetStyle; +}; + +class XMLTableStylesContext : public SvXMLStylesContext +{ + ::com::sun::star::uno::Reference < + ::com::sun::star::container::XNameContainer > xCellStyles; + ::com::sun::star::uno::Reference < + ::com::sun::star::container::XNameContainer > xColumnStyles; + ::com::sun::star::uno::Reference < + ::com::sun::star::container::XNameContainer > xRowStyles; + ::com::sun::star::uno::Reference < + ::com::sun::star::container::XNameContainer > xTableStyles; + const ::rtl::OUString sCellStyleServiceName; + const ::rtl::OUString sColumnStyleServiceName; + const ::rtl::OUString sRowStyleServiceName; + const ::rtl::OUString sTableStyleServiceName; + sal_Int32 nNumberFormatIndex; + sal_Int32 nConditionalFormatIndex; + sal_Int32 nCellStyleIndex; + sal_Int32 nMasterPageNameIndex; + sal_Bool bAutoStyles; + + UniReference < SvXMLImportPropertyMapper > xCellImpPropMapper; + UniReference < SvXMLImportPropertyMapper > xColumnImpPropMapper; + UniReference < SvXMLImportPropertyMapper > xRowImpPropMapper; + UniReference < SvXMLImportPropertyMapper > xTableImpPropMapper; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +protected: + + // Create a style context. + virtual SvXMLStyleContext *CreateStyleStyleChildContext( + sal_uInt16 nFamily, + sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList ); + + virtual SvXMLStyleContext *CreateDefaultStyleStyleChildContext( + sal_uInt16 nFamily, sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList > & xAttrList ); + +// virtual SvXMLImportPropertyMapper *GetImpPropMapper(); + +public: + + XMLTableStylesContext( SvXMLImport& rImport, sal_uInt16 nPrfx , + const ::rtl::OUString& rLName , + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList, + const sal_Bool bAutoStyles ); + virtual ~XMLTableStylesContext(); + + // Create child element. +/* virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList > & xAttrList );*/ + + virtual void EndElement(); + + virtual UniReference < SvXMLImportPropertyMapper > GetImportPropertyMapper( + sal_uInt16 nFamily ) const; + virtual ::com::sun::star::uno::Reference < + ::com::sun::star::container::XNameContainer > + GetStylesContainer( sal_uInt16 nFamily ) const; + virtual ::rtl::OUString GetServiceName( sal_uInt16 nFamily ) const; + + sal_Int32 GetIndex(const sal_Int16 nContextID); +}; + +class ScXMLMasterStylesContext : public SvXMLStylesContext +{ +protected: + virtual SvXMLStyleContext *CreateStyleChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList > & xAttrList ); + + virtual SvXMLStyleContext *CreateStyleStyleChildContext( sal_uInt16 nFamily, + sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList > & xAttrList ); + + virtual sal_Bool InsertStyleFamily( sal_uInt16 nFamily ) const; + +public: + TYPEINFO(); + + ScXMLMasterStylesContext( SvXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList > & xAttrList); + + virtual ~ScXMLMasterStylesContext(); + virtual void EndElement(); +}; + +namespace com { namespace sun { namespace star { + namespace style { class XStyle; } +} } } + +class ScMasterPageContext : public XMLTextMasterPageContext +{ + com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> xPropSet; + const rtl::OUString sEmpty; + sal_Bool bContainsRightHeader; + sal_Bool bContainsRightFooter; + + void ClearContent(const rtl::OUString& rContent); +public: + + TYPEINFO(); + + ScMasterPageContext( SvXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList > & xAttrList, + sal_Bool bOverwrite ); + virtual ~ScMasterPageContext(); + + virtual SvXMLImportContext *CreateChildContext( + sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList ); + + virtual SvXMLImportContext *CreateHeaderFooterContext( + sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList, + const sal_Bool bFooter, + const sal_Bool bLeft ); + + virtual void Finish( sal_Bool bOverwrite ); +}; + +class ScCellTextStyleContext : public XMLTextStyleContext +{ + sal_Int32 nLastSheet; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + ScCellTextStyleContext( SvXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList > & xAttrList, + SvXMLStylesContext& rStyles, sal_uInt16 nFamily, + sal_Bool bDefaultStyle = sal_False ); + virtual ~ScCellTextStyleContext(); + + // overload FillPropertySet to store style information + virtual void FillPropertySet( + const ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertySet > & rPropSet ); +}; + + +#endif + diff --git a/sc/source/filter/xml/xmlsubti.cxx b/sc/source/filter/xml/xmlsubti.cxx new file mode 100644 index 000000000000..e6cc7b853764 --- /dev/null +++ b/sc/source/filter/xml/xmlsubti.cxx @@ -0,0 +1,833 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + +// INCLUDE --------------------------------------------------------------- +#include "xmlsubti.hxx" +#include "global.hxx" +#include "xmlstyli.hxx" +#include "xmlimprt.hxx" +#include "document.hxx" +#include "markdata.hxx" +#include "XMLConverter.hxx" +#include "docuno.hxx" +#include "cellsuno.hxx" +#include "XMLStylesImportHelper.hxx" +#include "sheetdata.hxx" +#include "tabprotection.hxx" +#include <svx/svdpage.hxx> + +#include <xmloff/xmltkmap.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmluconv.hxx> +#include <xmloff/xmlerror.hxx> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include <com/sun/star/util/XMergeable.hpp> +#include <com/sun/star/sheet/XSheetCellRange.hpp> +#include <com/sun/star/sheet/XCellRangeAddressable.hpp> +#include <com/sun/star/sheet/CellInsertMode.hpp> +#include <com/sun/star/sheet/XCellRangeMovement.hpp> +#include <com/sun/star/drawing/XDrawPageSupplier.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/util/XProtectable.hpp> +#include <com/sun/star/sheet/XArrayFormulaRange.hpp> + +#include <memory> + +using ::std::auto_ptr; + +//------------------------------------------------------------------ + +using namespace com::sun::star; + +ScMyTableData::ScMyTableData(sal_Int32 nSheet, sal_Int32 nCol, sal_Int32 nRow) + : nColsPerCol(nDefaultColCount, 1), + nRealCols(nDefaultColCount + 1, 0), + nRowsPerRow(nDefaultRowCount, 1), + nRealRows(nDefaultRowCount + 1, 0), + nChangedCols() +{ + aTableCellPos.Sheet = sal::static_int_cast<sal_Int16>( nSheet ); + aTableCellPos.Column = nCol; + aTableCellPos.Row = nRow; + + for (sal_Int32 i = 0; i < 3; ++i) + nRealCols[i] = i; + for (sal_Int32 j = 0; j < 3; ++j) + nRealRows[j] = j; + + nSpannedCols = 1; + nColCount = 0; + nSubTableSpanned = 1; +} + +ScMyTableData::~ScMyTableData() +{ +} + +void ScMyTableData::AddRow() +{ + ++aTableCellPos.Row; + if (static_cast<sal_uInt32>(aTableCellPos.Row) >= nRowsPerRow.size()) + { + nRowsPerRow.resize(nRowsPerRow.size() + nDefaultRowCount, 1); + nRealRows.resize(nRowsPerRow.size() + nDefaultRowCount + 1, 0); + } + nRealRows[aTableCellPos.Row + 1] = nRealRows[aTableCellPos.Row] + nRowsPerRow[aTableCellPos.Row]; +} + +void ScMyTableData::AddColumn() +{ + ++aTableCellPos.Column; + if (static_cast<sal_uInt32>(aTableCellPos.Column) >= nColsPerCol.size()) + { + nColsPerCol.resize(nColsPerCol.size() + nDefaultColCount, 1); + nRealCols.resize(nColsPerCol.size() + nDefaultColCount + 1, 0); + } + nRealCols[aTableCellPos.Column + 1] = nRealCols[aTableCellPos.Column] + nColsPerCol[aTableCellPos.Column]; +} + +sal_Int32 ScMyTableData::GetRealCols(const sal_Int32 nIndex, const sal_Bool /* bIsNormal */) const +{ + return (nIndex < 0) ? 0 : nRealCols[nIndex]; +} + +sal_Int32 ScMyTableData::GetChangedCols(const sal_Int32 nFromIndex, const sal_Int32 nToIndex) const +{ + ScMysalIntList::const_iterator i(nChangedCols.begin()); + ScMysalIntList::const_iterator endi(nChangedCols.end()); + while ((i != endi) && ((*i < nToIndex) && !(*i >= nFromIndex))) + ++i; + if (i == endi) + return -1; + else + if ((*i >= nFromIndex) && (*i < nToIndex)) + return *i; + else + return -1; +} + +void ScMyTableData::SetChangedCols(const sal_Int32 nValue) +{ + ScMysalIntList::iterator i(nChangedCols.begin()); + ScMysalIntList::iterator endi(nChangedCols.end()); + while ((i != endi) && (*i < nValue)) + { + ++i; + } + if ((i == endi) || (*i != nValue)) + nChangedCols.insert(i, nValue); +} + +/*******************************************************************************************************************************/ + +ScMyTables::ScMyTables(ScXMLImport& rTempImport) + : rImport(rTempImport), + aResizeShapes(rTempImport), + nCurrentColStylePos(0), + nCurrentDrawPage( -1 ), + nCurrentXShapes( -1 ), + nTableCount( 0 ), + nCurrentSheet( -1 ) +{ + aTableVec.resize(nDefaultTabCount, NULL); +} + +ScMyTables::~ScMyTables() +{ + ScMyTableData* pTable; + while (nTableCount > 0) + { + pTable = aTableVec[nTableCount - 1]; + delete pTable; + aTableVec[nTableCount - 1] = NULL; + --nTableCount; + } +} + +void ScMyTables::NewSheet(const rtl::OUString& sTableName, const rtl::OUString& sStyleName, + const sal_Bool bTempProtection, const rtl::OUString& sTempPassword) +{ + if (rImport.GetModel().is()) + { + nCurrentColStylePos = 0; + sCurrentSheetName = sTableName; + ScMyTableData* aTable; + while (nTableCount > 0) + { + aTable = aTableVec[nTableCount - 1]; + delete aTable; + aTableVec[nTableCount - 1] = NULL; + --nTableCount; + } + ++nCurrentSheet; + + bProtection = bTempProtection; + sPassword = sTempPassword; + uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( rImport.GetModel(), uno::UNO_QUERY ); + if ( xSpreadDoc.is() ) + { + uno::Reference <sheet::XSpreadsheets> xSheets(xSpreadDoc->getSheets()); + if (xSheets.is()) + { + if (nCurrentSheet > 0) + { + try + { + xSheets->insertNewByName(sTableName, sal::static_int_cast<sal_Int16>(nCurrentSheet)); + } + catch ( uno::RuntimeException& ) + { + ScDocument *pDoc = ScXMLConverter::GetScDocument(rImport.GetModel()); + if (pDoc) + { + rImport.LockSolarMutex(); + String sTabName(String::CreateFromAscii("Table")); + pDoc->CreateValidTabName(sTabName); + rtl::OUString sOUTabName(sTabName); + xSheets->insertNewByName(sOUTabName, sal::static_int_cast<sal_Int16>(nCurrentSheet)); + rImport.UnlockSolarMutex(); + } + } + } + uno::Reference <container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY ); + if ( xIndex.is() ) + { + xCurrentSheet.set(xIndex->getByIndex(nCurrentSheet), uno::UNO_QUERY); + if ( xCurrentSheet.is() ) + { + xCurrentCellRange.set(xCurrentSheet, uno::UNO_QUERY); + if (!(nCurrentSheet > 0)) + { + uno::Reference < container::XNamed > xNamed(xCurrentSheet, uno::UNO_QUERY ); + if ( xNamed.is() ) + try + { + xNamed->setName(sTableName); + } + catch ( uno::RuntimeException& ) + { + ScDocument *pDoc = ScXMLConverter::GetScDocument(rImport.GetModel()); + if (pDoc) + { + rImport.LockSolarMutex(); + String sTabName(String::CreateFromAscii("Table")); + pDoc->CreateValidTabName(sTabName); + rtl::OUString sOUTabName(sTabName); + xNamed->setName(sOUTabName); + rImport.UnlockSolarMutex(); + } + } + } + rImport.SetTableStyle(sStyleName); + + if ( sStyleName.getLength() ) + { + // #i57869# All table style properties for all sheets are now applied here, + // before importing the contents. + // This is needed for the background color. + // Sheet visibility has special handling in ScDocFunc::SetTableVisible to + // allow hiding the first sheet. + // RTL layout is only remembered, not actually applied, so the shapes can + // be loaded before mirroring. + + uno::Reference <beans::XPropertySet> xProperties(xCurrentSheet, uno::UNO_QUERY); + if (xProperties.is()) + { + XMLTableStylesContext *pStyles = (XMLTableStylesContext *)rImport.GetAutoStyles(); + if (pStyles) + { + XMLTableStyleContext* pStyle = (XMLTableStyleContext *)pStyles->FindStyleChildContext( + XML_STYLE_FAMILY_TABLE_TABLE, sStyleName, sal_True); + if (pStyle) + { + pStyle->FillPropertySet(xProperties); + + ScSheetSaveData* pSheetData = ScModelObj::getImplementation(rImport.GetModel())->GetSheetSaveData(); + pSheetData->AddTableStyle( sStyleName, ScAddress( 0, 0, (SCTAB)nCurrentSheet ) ); + } + } + } + } + } + + } + } + } + } + + NewTable(1); +} + +sal_Bool ScMyTables::IsMerged (const uno::Reference <table::XCellRange>& xCellRange, const sal_Int32 nCol, const sal_Int32 nRow, + table::CellRangeAddress& aCellAddress) const +{ + uno::Reference <util::XMergeable> xMergeable (xCellRange->getCellRangeByPosition(nCol,nRow,nCol,nRow), uno::UNO_QUERY); + if (xMergeable.is()) + { + uno::Reference<sheet::XSheetCellRange> xMergeSheetCellRange (xMergeable, uno::UNO_QUERY); + uno::Reference<sheet::XSpreadsheet> xTable(xMergeSheetCellRange->getSpreadsheet()); + uno::Reference<sheet::XSheetCellCursor> xMergeSheetCursor(xTable->createCursorByRange(xMergeSheetCellRange)); + if (xMergeSheetCursor.is()) + { + xMergeSheetCursor->collapseToMergedArea(); + uno::Reference<sheet::XCellRangeAddressable> xMergeCellAddress (xMergeSheetCursor, uno::UNO_QUERY); + if (xMergeCellAddress.is()) + { + aCellAddress = xMergeCellAddress->getRangeAddress(); + if (aCellAddress.StartColumn == nCol && aCellAddress.EndColumn == nCol && + aCellAddress.StartRow == nRow && aCellAddress.EndRow == nRow) + return sal_False; + else + return sal_True; + } + } + } + return sal_False; +} + +void ScMyTables::UnMerge() +{ + if ( xCurrentCellRange.is() ) + { + table::CellRangeAddress aCellAddress; + if (IsMerged(xCurrentCellRange, GetRealCellPos().Column, GetRealCellPos().Row, aCellAddress)) + { + //unmerge + uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow, + aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY); + if (xMergeable.is()) + xMergeable->merge(sal_False); + } + } +} + +void ScMyTables::DoMerge(sal_Int32 nCount) +{ + if ( xCurrentCellRange.is() ) + { + table::CellRangeAddress aCellAddress; + if (IsMerged(xCurrentCellRange, GetRealCellPos().Column, GetRealCellPos().Row, aCellAddress)) + { + //unmerge + uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow, + aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY); + if (xMergeable.is()) + xMergeable->merge(sal_False); + } + + //merge + uno::Reference <table::XCellRange> xMergeCellRange; + if (nCount == -1) + xMergeCellRange.set(xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow, + aCellAddress.EndColumn + + aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn()) - 1, + aCellAddress.EndRow + + aTableVec[nTableCount - 1]->GetRowsPerRow(aTableVec[nTableCount - 1]->GetRow()) - 1)); + else + xMergeCellRange.set(xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow, + aCellAddress.StartColumn + + nCount - 1, + aCellAddress.EndRow)); + uno::Reference <util::XMergeable> xMergeable (xMergeCellRange, uno::UNO_QUERY); + if (xMergeable.is()) + xMergeable->merge(sal_True); + } +} + +void ScMyTables::InsertRow() +{ + if ( xCurrentCellRange.is() ) + { + table::CellRangeAddress aCellAddress; + sal_Int32 nRow(GetRealCellPos().Row); + for (sal_Int32 j = 0; j < GetRealCellPos().Column - aTableVec[nTableCount - 1]->GetColumn() - 1; ++j) + { + if (IsMerged(xCurrentCellRange, j, nRow - 1, aCellAddress)) + { + //unmerge + uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow, + aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY); + if (xMergeable.is()) + xMergeable->merge(sal_False); + } + + //merge + uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow, + aCellAddress.EndColumn, aCellAddress.EndRow + 1), uno::UNO_QUERY); + if (xMergeable.is()) + xMergeable->merge(sal_True); + j += aCellAddress.EndColumn - aCellAddress.StartColumn; + } + rImport.GetStylesImportHelper()->InsertRow(nRow, nCurrentSheet, rImport.GetDocument()); + } +} + +void ScMyTables::NewRow() +{ + if (nTableCount > 1) + if (aTableVec[nTableCount - 1]->GetRealRows(aTableVec[nTableCount - 1]->GetRow()) > + aTableVec[nTableCount - 2]->GetRowsPerRow(aTableVec[nTableCount - 2]->GetRow()) - 1) + { + if (GetRealCellPos().Column > 0) + InsertRow(); + for (sal_Int16 i = sal::static_int_cast<sal_Int16>(nTableCount - 1); i > 0; i--) + { + sal_Int32 nRow = aTableVec[i - 1]->GetRow(); + aTableVec[i - 1]->SetRowsPerRow(nRow, + aTableVec[i - 1]->GetRowsPerRow(nRow) + 1); + aTableVec[i - 1]->SetRealRows(nRow + 1, + aTableVec[i - 1]->GetRealRows(nRow) + + aTableVec[i - 1]->GetRowsPerRow(nRow)); + } + } +} + +void ScMyTables::AddRow() +{ + aTableVec[nTableCount - 1]->AddRow(); + aTableVec[nTableCount - 1]->SetFirstColumn(); + sal_Int32 nRow = aTableVec[nTableCount - 1]->GetRow(); + if (nRow > 0) + NewRow(); + aTableVec[nTableCount - 1]->SetRealRows(nRow + 1, + aTableVec[nTableCount - 1]->GetRealRows(nRow) + + aTableVec[nTableCount - 1]->GetRowsPerRow(nRow)); +} + +void ScMyTables::SetRowStyle(const rtl::OUString& rCellStyleName) +{ + rImport.GetStylesImportHelper()->SetRowStyle(rCellStyleName); +} + +void ScMyTables::InsertColumn() +{ + if ( xCurrentCellRange.is() ) + { + table::CellRangeAddress aCellAddress; + sal_Int32 nCol(GetRealCellPos().Column); + for (sal_Int32 j = 0; j <= GetRealCellPos().Row - aTableVec[nTableCount - 1]->GetRow() - 1; ++j) + { + table::CellRangeAddress aTempCellAddress; + if (IsMerged(xCurrentCellRange, nCol - 1, j, aCellAddress)) + { + //unmerge + uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow, + aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY); + if (xMergeable.is()) + xMergeable->merge(sal_False); + aTempCellAddress = aCellAddress; + aTempCellAddress.StartColumn = aTempCellAddress.EndColumn + 1; + aTempCellAddress.EndColumn = aTempCellAddress.StartColumn; + } + else + { + aTempCellAddress = aCellAddress; + aTempCellAddress.StartColumn += 1; + aTempCellAddress.EndColumn = aTempCellAddress.StartColumn; + } + + //insert Cell + sheet::CellInsertMode aCellInsertMode(sheet::CellInsertMode_RIGHT); + uno::Reference <sheet::XCellRangeMovement> xCellRangeMovement (xCurrentSheet, uno::UNO_QUERY); + xCellRangeMovement->insertCells(aTempCellAddress, aCellInsertMode); + + //merge + uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow, + aCellAddress.EndColumn + 1, aCellAddress.EndRow), uno::UNO_QUERY); + if (xMergeable.is()) + xMergeable->merge(sal_True); + j += aCellAddress.EndRow - aCellAddress.StartRow; + } + rImport.GetStylesImportHelper()->InsertCol(nCol, nCurrentSheet, rImport.GetDocument()); + } +} + +void ScMyTables::NewColumn(sal_Bool bIsCovered) +{ + if (!bIsCovered) + { + sal_Int32 nColCount(aTableVec[nTableCount - 1]->GetColCount()); + sal_Int32 nSpannedCols(aTableVec[nTableCount - 1]->GetSpannedCols()); + if ( (nSpannedCols > nColCount) && + (aTableVec[nTableCount - 1]->GetRow() == 0) && + (aTableVec[nTableCount - 1]->GetColumn() == 0) ) + { + if (nColCount > 0) + { + sal_Int32 FirstColsSpanned(nSpannedCols / nColCount); + sal_Int32 LastColSpanned(FirstColsSpanned + + (nSpannedCols % nColCount)); + for (sal_Int32 i = 0; i < nColCount - 1; ++i) + { + aTableVec[nTableCount - 1]->SetColsPerCol(i, FirstColsSpanned); + aTableVec[nTableCount - 1]->SetRealCols(i + 1, + aTableVec[nTableCount - 1]->GetRealCols(i) + + FirstColsSpanned); + } + aTableVec[nTableCount - 1]->SetColsPerCol(nColCount - 1, LastColSpanned); + aTableVec[nTableCount - 1]->SetRealCols(nColCount - 1 + 1, + aTableVec[nTableCount - 1]->GetRealCols(nColCount - 1) + + LastColSpanned); + } + } + if (aTableVec[nTableCount - 1]->GetRealCols(aTableVec[nTableCount - 1]->GetColumn()) > nSpannedCols - 1) + { + if ( aTableVec[nTableCount - 1]->GetRow() == 0) + { + InsertColumn(); + for (sal_Int16 i = sal::static_int_cast<sal_Int16>(nTableCount - 1); i > 0; i--) + { + sal_Int32 nColPos = aTableVec[i - 1]->GetColumn() + + aTableVec[i]->GetSpannedCols() - 1; + aTableVec[i - 1]->SetColsPerCol(nColPos, + aTableVec[i - 1]->GetColsPerCol(nColPos) + + aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn())); + aTableVec[i - 1]->SetRealCols(nColPos + 1, + aTableVec[i - 1]->GetRealCols(nColPos) + + aTableVec[i - 1]->GetColsPerCol(nColPos)); + aTableVec[i - 1]->SetChangedCols(nColPos); + } + } + } + } +} + +void ScMyTables::AddColumn(sal_Bool bIsCovered) +{ + aTableVec[nTableCount - 1]->AddColumn(); + if (aTableVec[nTableCount - 1]->GetSubTableSpanned() > 1) + aTableVec[nTableCount - 1]->SetSubTableSpanned(aTableVec[nTableCount - 1]->GetSubTableSpanned() - 1); + else + { + NewColumn(bIsCovered); + // if (!bIsCovered) + aTableVec[nTableCount - 1]->SetRealCols(aTableVec[nTableCount - 1]->GetColumn() + 1, + aTableVec[nTableCount - 1]->GetRealCols(aTableVec[nTableCount - 1]->GetColumn()) + + aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn())); + if ((!bIsCovered) || (bIsCovered && + (aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn()) > 1))) + { + if ((aTableVec[nTableCount - 1]->GetRowsPerRow(aTableVec[nTableCount - 1]->GetRow()) > 1) || + (aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn()) > 1)) + DoMerge(); + } + } +} + +void ScMyTables::NewTable(sal_Int32 nTempSpannedCols) +{ + ++nTableCount; + if (static_cast<sal_uInt32>(nTableCount) >= aTableVec.size()) + aTableVec.resize(aTableVec.size() + nDefaultTabCount); + ScMyTableData* aTable(new ScMyTableData(nCurrentSheet)); + if (nTableCount > 1) + { + ScMyTableData* pTableData = aTableVec[nTableCount - 2]; + const sal_Int32 nCol(pTableData->GetColumn()); + const sal_Int32 nColCount(pTableData->GetColCount()); + const sal_Int32 nColsPerCol(pTableData->GetColsPerCol(nCol)); + sal_Int32 nSpannedCols(pTableData->GetSpannedCols()); + sal_Int32 nTemp(nSpannedCols - nColCount); + sal_Int32 nTemp2(nCol - (nColCount - 1)); + if ((nTemp > 0) && (nTemp2 == 0)) + nTempSpannedCols *= (nTemp + 1); + else + if (nColsPerCol > 1) + nTempSpannedCols *= nColsPerCol; + + sal_Int32 nToMerge; + if (nSpannedCols > nColCount) + nToMerge = pTableData->GetChangedCols(nCol, nCol + nColsPerCol + nSpannedCols - nColCount); + else + nToMerge = pTableData->GetChangedCols(nCol, nCol + nColsPerCol); + if (nToMerge > nCol) + nTempSpannedCols += nToMerge; + } + aTable->SetSpannedCols(nTempSpannedCols); + aTableVec[nTableCount - 1] = aTable; + if (nTableCount > 1) + { + aTableVec[nTableCount - 2]->SetSubTableSpanned(aTable->GetSpannedCols()); + UnMerge(); + } +} + +void ScMyTables::UpdateRowHeights() +{ + if (rImport.GetModel().is()) + { + rImport.LockSolarMutex(); + // update automatic row heights + + // For sheets with any kind of shapes (including notes), + // update row heights immediately (before setting the positions). + // For sheets without shapes, set "pending" flag + // and update row heights when a sheet is shown. + // The current sheet (from view settings) is always updated immediately. + + ScDocument* pDoc = ScXMLConverter::GetScDocument(rImport.GetModel()); + if (pDoc) + { + SCTAB nCount = pDoc->GetTableCount(); + ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); + + SCTAB nVisible = static_cast<SCTAB>( rImport.GetVisibleSheet() ); + + ScMarkData aUpdateSheets; + for (SCTAB nTab=0; nTab<nCount; ++nTab) + { + const SdrPage* pPage = pDrawLayer ? pDrawLayer->GetPage(nTab) : NULL; + if ( nTab == nVisible || ( pPage && pPage->GetObjCount() != 0 ) ) + aUpdateSheets.SelectTable( nTab, sal_True ); + else + pDoc->SetPendingRowHeights( nTab, sal_True ); + } + + if (aUpdateSheets.GetSelectCount()) + { + pDoc->LockStreamValid( true ); // ignore draw page size (but not formula results) + ScModelObj::getImplementation(rImport.GetModel())->UpdateAllRowHeights(&aUpdateSheets); + pDoc->LockStreamValid( false ); + } + } + + rImport.UnlockSolarMutex(); + } +} + +void ScMyTables::DeleteTable() +{ + rImport.LockSolarMutex(); + + nCurrentColStylePos = 0; + if (nTableCount > 0) + { + ScMyTableData* aTable = aTableVec[nTableCount - 1]; + delete aTable; + aTableVec[nTableCount - 1] = NULL; + nTableCount--; + } + if (nTableCount == 0) // only set the styles if all subtables are importet and the table is finished + { + rImport.GetStylesImportHelper()->SetStylesToRanges(); + rImport.SetStylesToRangesFinished(); + } + + //#i48793#; has to be set before protection + if (!aMatrixRangeList.empty()) + { + ScMyMatrixRangeList::iterator aItr = aMatrixRangeList.begin(); + ScMyMatrixRangeList::iterator aEndItr = aMatrixRangeList.end(); + while(aItr != aEndItr) + { + SetMatrix(aItr->aRange, aItr->sFormula, aItr->sFormulaNmsp, aItr->eGrammar); + ++aItr; + } + aMatrixRangeList.clear(); + } + + if (rImport.GetDocument() && bProtection) + { + uno::Sequence<sal_Int8> aPass; + SvXMLUnitConverter::decodeBase64(aPass, sPassword); + auto_ptr<ScTableProtection> pProtect(new ScTableProtection); + pProtect->setProtected(bProtection); + pProtect->setPasswordHash(aPass, PASSHASH_OOO); + rImport.GetDocument()->SetTabProtection(static_cast<SCTAB>(nCurrentSheet), pProtect.get()); + } + + rImport.UnlockSolarMutex(); + + //#95582#; find out whether it was possible to set the sheet name + // test it here, because if it is a linked table the name is changed by importing + // the linking informations + uno::Reference < container::XNamed > xNamed(xCurrentSheet, uno::UNO_QUERY ); + if ( xNamed.is() ) + { + rtl::OUString sCurrentName(xNamed->getName()); + if (sCurrentName != sCurrentSheetName && rImport.GetDocument()) + { + rImport.GetDocument()->RenameTab( static_cast<SCTAB>(nCurrentSheet), + sCurrentSheetName, sal_False, sal_True); + +/* rtl::OUString sErrorMessage(RTL_CONSTASCII_USTRINGPARAM("Could not create a table with the name ")); + sErrorMessage += sCurrentSheetName; + sErrorMessage += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(". The new name is ")); + sErrorMessage += sCurrentName; + uno::Sequence<rtl::OUString> aSeq(1); + aSeq[0] = sErrorMessage; + uno::Reference<xml::sax::XLocator> xLocator; + rImport.SetError(XMLERROR_API | XMLERROR_FLAG_ERROR, aSeq, rtl::OUString(), xLocator);*/ + } + } +} + +table::CellAddress ScMyTables::GetRealCellPos() +{ + sal_Int32 nRow(0); + sal_Int32 nCol(0); + for (sal_Int32 i = 0; i < nTableCount; ++i) + { + ScMyTableData* pTableData = aTableVec[i]; + nCol += pTableData->GetRealCols(pTableData->GetColumn()); + nRow += pTableData->GetRealRows(pTableData->GetRow()); + } + aRealCellPos.Row = nRow; + aRealCellPos.Column = nCol; + aRealCellPos.Sheet = sal::static_int_cast<sal_Int16>(nCurrentSheet); + return aRealCellPos; +} + +void ScMyTables::AddColCount(sal_Int32 nTempColCount) +{ + aTableVec[nTableCount - 1]->SetColCount(aTableVec[nTableCount - 1]->GetColCount() + nTempColCount); +} + +void ScMyTables::AddColStyle(const sal_Int32 nRepeat, const rtl::OUString& rCellStyleName) +{ + DBG_ASSERT(nTableCount == 1, "not possible to use default styles on columns in subtables"); + rImport.GetStylesImportHelper()->AddColumnStyle(rCellStyleName, nCurrentColStylePos, nRepeat); + nCurrentColStylePos += nRepeat; +} + +uno::Reference< drawing::XDrawPage > ScMyTables::GetCurrentXDrawPage() +{ + if( (nCurrentSheet != nCurrentDrawPage) || !xDrawPage.is() ) + { + uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier( xCurrentSheet, uno::UNO_QUERY ); + if( xDrawPageSupplier.is() ) + xDrawPage.set(xDrawPageSupplier->getDrawPage()); + nCurrentDrawPage = sal::static_int_cast<sal_Int16>(nCurrentSheet); + } + return xDrawPage; +} + +uno::Reference< drawing::XShapes > ScMyTables::GetCurrentXShapes() +{ + if( (nCurrentSheet != nCurrentXShapes) || !xShapes.is() ) + { + xShapes.set(GetCurrentXDrawPage(), uno::UNO_QUERY); + rImport.GetShapeImport()->startPage(xShapes); + rImport.GetShapeImport()->pushGroupForSorting ( xShapes ); + nCurrentXShapes = sal::static_int_cast<sal_Int16>(nCurrentSheet); + return xShapes; + } + else + return xShapes; +} + +sal_Bool ScMyTables::HasDrawPage() +{ + return !((nCurrentSheet != nCurrentDrawPage) || !xDrawPage.is()); +} + +sal_Bool ScMyTables::HasXShapes() +{ + return !((nCurrentSheet != nCurrentXShapes) || !xShapes.is()); +} + +void ScMyTables::AddShape(uno::Reference <drawing::XShape>& rShape, + rtl::OUString* pRangeList, + table::CellAddress& rStartAddress, table::CellAddress& rEndAddress, + sal_Int32 nEndX, sal_Int32 nEndY) +{ + aResizeShapes.AddShape(rShape, pRangeList, rStartAddress, rEndAddress, nEndX, nEndY); +} + +void ScMyTables::AddMatrixRange( + sal_Int32 nStartColumn, sal_Int32 nStartRow, sal_Int32 nEndColumn, sal_Int32 nEndRow, + const rtl::OUString& rFormula, const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar) +{ + DBG_ASSERT(nEndRow >= nStartRow, "wrong row order"); + DBG_ASSERT(nEndColumn >= nStartColumn, "wrong column order"); + table::CellRangeAddress aRange; + aRange.StartColumn = nStartColumn; + aRange.StartRow = nStartRow; + aRange.EndColumn = nEndColumn; + aRange.EndRow = nEndRow; + aRange.Sheet = sal::static_int_cast<sal_Int16>(nCurrentSheet); + ScMatrixRange aMRange(aRange, rFormula, rFormulaNmsp, eGrammar); + aMatrixRangeList.push_back(aMRange); +} + +sal_Bool ScMyTables::IsPartOfMatrix(sal_Int32 nColumn, sal_Int32 nRow) +{ + sal_Bool bResult(sal_False); + if (!aMatrixRangeList.empty()) + { + ScMyMatrixRangeList::iterator aItr(aMatrixRangeList.begin()); + ScMyMatrixRangeList::iterator aEndItr(aMatrixRangeList.end()); + sal_Bool bReady(sal_False); + while(!bReady && aItr != aEndItr) + { + if (nCurrentSheet > aItr->aRange.Sheet) + { + DBG_ERROR("should never hapen, because the list should be cleared in DeleteTable"); + aItr = aMatrixRangeList.erase(aItr); + } + else if ((nRow > aItr->aRange.EndRow) && (nColumn > aItr->aRange.EndColumn)) + { + SetMatrix(aItr->aRange, aItr->sFormula, aItr->sFormulaNmsp, aItr->eGrammar); + aItr = aMatrixRangeList.erase(aItr); + } + else if (nColumn < aItr->aRange.StartColumn) + bReady = sal_True; + else if (nColumn >= aItr->aRange.StartColumn && nColumn <= aItr->aRange.EndColumn && nRow >= aItr->aRange.StartRow && nRow <= aItr->aRange.EndRow) + { + bReady = sal_True; + bResult = sal_True; + } + else + ++aItr; + } + } + return bResult; +} + +void ScMyTables::SetMatrix(const table::CellRangeAddress& rRange, const rtl::OUString& rFormula, + const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar) +{ + uno::Reference <table::XCellRange> xMatrixCellRange( + GetCurrentXCellRange()->getCellRangeByPosition(rRange.StartColumn, rRange.StartRow, + rRange.EndColumn, rRange.EndRow)); + if (xMatrixCellRange.is()) + { + uno::Reference <sheet::XArrayFormulaRange> xArrayFormulaRange(xMatrixCellRange, uno::UNO_QUERY); + if (xArrayFormulaRange.is()) + { + ScCellRangeObj* pCellRangeObj = + static_cast<ScCellRangeObj*>(ScCellRangesBase::getImplementation( + xMatrixCellRange)); + if (pCellRangeObj) + pCellRangeObj->SetArrayFormulaWithGrammar( rFormula, rFormulaNmsp, eGrammar); + } + } +} diff --git a/sc/source/filter/xml/xmlsubti.hxx b/sc/source/filter/xml/xmlsubti.hxx new file mode 100644 index 000000000000..6e39844b5b8f --- /dev/null +++ b/sc/source/filter/xml/xmlsubti.hxx @@ -0,0 +1,193 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef SC_XMLSUBTI_HXX +#define SC_XMLSUBTI_HXX + +#include <xmloff/xmlictxt.hxx> +#include <xmloff/xmlimp.hxx> +#include <com/sun/star/sheet/XSpreadsheet.hpp> +#include <com/sun/star/drawing/XDrawPage.hpp> +#include <com/sun/star/table/CellAddress.hpp> +#include <com/sun/star/table/XCellRange.hpp> +#include <com/sun/star/table/CellRangeAddress.hpp> +#include <com/sun/star/frame/XModel.hpp> + +#include <vector> +#include <list> +#include "XMLTableShapeResizer.hxx" +#include "formula/grammar.hxx" + +class ScXMLImport; + +typedef std::vector<sal_Int32> ScMysalIntVec; +typedef std::list<sal_Int32> ScMysalIntList; + +const ScMysalIntVec::size_type nDefaultRowCount = 20; +const ScMysalIntVec::size_type nDefaultColCount = 20; +const ScMysalIntVec::size_type nDefaultTabCount = 10; + +class ScMyTableData +{ +private: + com::sun::star::table::CellAddress aTableCellPos; + ScMysalIntVec nColsPerCol; + ScMysalIntVec nRealCols; + ScMysalIntVec nRowsPerRow; + ScMysalIntVec nRealRows; + sal_Int32 nSpannedCols; + sal_Int32 nColCount; + sal_Int32 nSubTableSpanned; + ScMysalIntList nChangedCols; +public: + ScMyTableData(sal_Int32 nSheet = -1, sal_Int32 nCol = -1, sal_Int32 nRow = -1); + ~ScMyTableData(); + com::sun::star::table::CellAddress GetCellPos() const { return aTableCellPos; } + sal_Int32 GetRow() const { return aTableCellPos.Row; } + sal_Int32 GetColumn() const { return aTableCellPos.Column; } + void AddRow(); + void AddColumn(); + void SetFirstColumn() { aTableCellPos.Column = -1; } + sal_Int32 GetColsPerCol(const sal_Int32 nIndex) const { return nColsPerCol[nIndex]; } + void SetColsPerCol(const sal_Int32 nIndex, sal_Int32 nValue = 1) { nColsPerCol[nIndex] = nValue; } + sal_Int32 GetRealCols(const sal_Int32 nIndex, const sal_Bool bIsNormal = sal_True) const; + void SetRealCols(const sal_Int32 nIndex, const sal_Int32 nValue) { nRealCols[nIndex] = nValue; } + sal_Int32 GetRowsPerRow(const sal_Int32 nIndex) const { return nRowsPerRow[nIndex]; } + void SetRowsPerRow(const sal_Int32 nIndex, const sal_Int32 nValue = 1) { nRowsPerRow[nIndex] = nValue; } + sal_Int32 GetRealRows(const sal_Int32 nIndex) const { return nIndex < 0 ? 0 : nRealRows[nIndex]; } + void SetRealRows(const sal_Int32 nIndex, const sal_Int32 nValue) { nRealRows[nIndex] = nValue; } + sal_Int32 GetSpannedCols() const { return nSpannedCols; } + void SetSpannedCols(const sal_Int32 nTempSpannedCols) { nSpannedCols = nTempSpannedCols; } + sal_Int32 GetColCount() const { return nColCount; } + void SetColCount(const sal_Int32 nTempColCount) { nColCount = nTempColCount; } + sal_Int32 GetSubTableSpanned() const { return nSubTableSpanned; } + void SetSubTableSpanned(const sal_Int32 nValue) { nSubTableSpanned = nValue; } + sal_Int32 GetChangedCols(const sal_Int32 nFromIndex, const sal_Int32 nToIndex) const; + void SetChangedCols(const sal_Int32 nValue); +}; + +//******************************************************************************************************************************* + +struct ScMatrixRange +{ + rtl::OUString sFormula; + rtl::OUString sFormulaNmsp; + formula::FormulaGrammar::Grammar eGrammar; + com::sun::star::table::CellRangeAddress aRange; + ScMatrixRange(const com::sun::star::table::CellRangeAddress& rRange, const rtl::OUString& rFormula, const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammarP) : + sFormula(rFormula), + sFormulaNmsp(rFormulaNmsp), + eGrammar(eGrammarP), + aRange(rRange) + { + } +}; + +class ScMyTables +{ +private: + typedef std::list<ScMatrixRange> ScMyMatrixRangeList; + + ScXMLImport& rImport; + + ScMyShapeResizer aResizeShapes; + + ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheet > xCurrentSheet; + ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange > xCurrentCellRange; + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage > xDrawPage; + ::com::sun::star::uno::Reference < ::com::sun::star::drawing::XShapes > xShapes; + rtl::OUString sCurrentSheetName; + rtl::OUString sPassword; + std::vector<ScMyTableData*> aTableVec; + ScMyMatrixRangeList aMatrixRangeList; + com::sun::star::table::CellAddress aRealCellPos; + sal_Int32 nCurrentColStylePos; + sal_Int16 nCurrentDrawPage; + sal_Int16 nCurrentXShapes; + sal_Int32 nTableCount; + sal_Int32 nCurrentSheet; + sal_Bool bProtection; + + sal_Bool IsMerged (const com::sun::star::uno::Reference <com::sun::star::table::XCellRange>& xCellRange, + const sal_Int32 nCol, const sal_Int32 nRow, + com::sun::star::table::CellRangeAddress& aCellAddress) const; + void UnMerge(); + void DoMerge(sal_Int32 nCount = -1); + void InsertRow(); + void NewRow(); + void InsertColumn(); + void NewColumn(sal_Bool bIsCovered); +public: + ScMyTables(ScXMLImport& rImport); + ~ScMyTables(); + void NewSheet(const rtl::OUString& sTableName, const rtl::OUString& sStyleName, + const sal_Bool bProtection, const rtl::OUString& sPassword); + void AddRow(); + void SetRowStyle(const rtl::OUString& rCellStyleName); + void AddColumn(sal_Bool bIsCovered); + void NewTable(sal_Int32 nTempSpannedCols); + void UpdateRowHeights(); + void ResizeShapes() { aResizeShapes.ResizeShapes(); } + void DeleteTable(); + com::sun::star::table::CellAddress GetRealCellPos(); + void AddColCount(sal_Int32 nTempColCount); + void AddColStyle(const sal_Int32 nRepeat, const rtl::OUString& rCellStyleName); + rtl::OUString GetCurrentSheetName() const { return sCurrentSheetName; } + sal_Int32 GetCurrentSheet() const { return nCurrentSheet; } + sal_Int32 GetCurrentColumn() const { return aTableVec[nTableCount - 1]->GetColCount(); } + sal_Int32 GetCurrentRow() const { return aTableVec[nTableCount - 1]->GetRow(); } + ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheet > + GetCurrentXSheet() { return xCurrentSheet; } + ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange > + GetCurrentXCellRange() { return xCurrentCellRange; } + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage > + GetCurrentXDrawPage(); + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes > + GetCurrentXShapes(); + sal_Bool HasDrawPage(); + sal_Bool HasXShapes(); + void AddShape(com::sun::star::uno::Reference <com::sun::star::drawing::XShape>& rShape, + rtl::OUString* pRangeList, + com::sun::star::table::CellAddress& rStartAddress, + com::sun::star::table::CellAddress& rEndAddress, + sal_Int32 nEndX, sal_Int32 nEndY); + + void AddMatrixRange( sal_Int32 nStartColumn, + sal_Int32 nStartRow, + sal_Int32 nEndColumn, + sal_Int32 nEndRow, + const rtl::OUString& rFormula, + const rtl::OUString& rFormulaNmsp, + const formula::FormulaGrammar::Grammar ); + + sal_Bool IsPartOfMatrix(sal_Int32 nColumn, sal_Int32 nRow); + void SetMatrix( const com::sun::star::table::CellRangeAddress& rRange, + const rtl::OUString& rFormula, + const rtl::OUString& rFormulaNmsp, + const formula::FormulaGrammar::Grammar ); +}; + +#endif diff --git a/sc/source/filter/xml/xmltabi.cxx b/sc/source/filter/xml/xmltabi.cxx new file mode 100644 index 000000000000..1644ad7e7ffe --- /dev/null +++ b/sc/source/filter/xml/xmltabi.cxx @@ -0,0 +1,422 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- + +#include "xmltabi.hxx" +#include "xmlimprt.hxx" +#include "xmlrowi.hxx" +#include "xmlcoli.hxx" +#include "xmlsceni.hxx" +#include "xmlexternaltabi.hxx" +#include "document.hxx" +#include "docuno.hxx" +#include "olinetab.hxx" +#include "XMLConverter.hxx" +#include "XMLTableShapesContext.hxx" +#include "XMLTableSourceContext.hxx" +#include "XMLStylesImportHelper.hxx" +#include "rangeutl.hxx" +#include "externalrefmgr.hxx" +#include "sheetdata.hxx" + +#include <xmloff/xmltkmap.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/formsimp.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/XMLEventsImportContext.hxx> + +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include <com/sun/star/sheet/XSpreadsheets.hpp> +#include <com/sun/star/sheet/XSpreadsheet.hpp> +#include <com/sun/star/sheet/XPrintAreas.hpp> +#include <com/sun/star/table/CellAddress.hpp> + +using namespace com::sun::star; +using namespace xmloff::token; + +/** + * Determine whether this table is an external reference cache from its + * name. There is currently no way of determining whether a table is a + * regular table or an external reference cache other than examining the + * name itself. We should probably introduce a new boolean value for + * table:table element and use it instead of doing this, to make it more + * reliable and future-proof. + * + * @param rName + * + * @return + */ +static bool lcl_isExternalRefCache(const rtl::OUString& rName, rtl::OUString& rUrl, rtl::OUString& rExtTabName) +{ + // 'file:///path/to/file.ods'#MySheet + // 'file:///path/to/file.ods'#MySheet with space + // 'file:///path/to/file's.ods'#Sheet (Notice the quote in the file name. + // That's allowed.) + + static const sal_Unicode aPrefix[] = { + '\'', 'f', 'i', 'l', 'e', ':', '/', '/' + }; + + rtl::OUStringBuffer aUrlBuf, aTabNameBuf; + aUrlBuf.appendAscii("file://"); + sal_Int32 n = rName.getLength(); + const sal_Unicode* p = rName.getStr(); + + bool bInUrl = true; + sal_Unicode cPrev = 0; + for (sal_Int32 i = 0; i < n; ++i) + { + const sal_Unicode c = p[i]; + if (i <= 7) + { + // Checking the prefix 'file://'. + if (c != aPrefix[i]) + return false; + } + else if (bInUrl) + { + // parsing file URL + if (c == '#') + { + if (cPrev != '\'') + return false; + + rUrl = aUrlBuf.makeStringAndClear(); + rUrl = rUrl.copy(0, rUrl.getLength()-1); // remove the trailing single-quote. + bInUrl = false; + } + else + aUrlBuf.append(c); + } + else + // parsing sheet name. + aTabNameBuf.append(c); + + cPrev = c; + } + + if (bInUrl) + return false; + + if (aTabNameBuf.getLength() == 0) + return false; + + rExtTabName = aTabNameBuf.makeStringAndClear(); + + return true; +} + +ScXMLExternalTabData::ScXMLExternalTabData() : + mpCacheTable(), mnRow(0), mnCol(0), mnFileId(0) +{ +} + +//------------------------------------------------------------------ + +ScXMLTableContext::ScXMLTableContext( ScXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + const sal_Bool bTempIsSubTable, + const sal_Int32 nSpannedCols) : + SvXMLImportContext( rImport, nPrfx, rLName ), + pExternalRefInfo(NULL), + nStartOffset(-1), + bStartFormPage(sal_False), + bPrintEntireSheet(sal_True) +{ + // get start offset in file (if available) + nStartOffset = GetScImport().GetByteOffset(); + + if (!bTempIsSubTable) + { + sal_Bool bProtection(sal_False); + rtl::OUString sName; + rtl::OUString sStyleName; + rtl::OUString sPassword; + sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0); + const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetTableAttrTokenMap(); + for( sal_Int16 i=0; i < nAttrCount; ++i ) + { + const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i )); + rtl::OUString aLocalName; + sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName( + sAttrName, &aLocalName )); + const rtl::OUString& sValue(xAttrList->getValueByIndex( i )); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName ) ) + { + case XML_TOK_TABLE_NAME: + sName = sValue; + break; + case XML_TOK_TABLE_STYLE_NAME: + sStyleName = sValue; + break; + case XML_TOK_TABLE_PROTECTION: + bProtection = IsXMLToken(sValue, XML_TRUE); + break; + case XML_TOK_TABLE_PRINT_RANGES: + sPrintRanges = sValue; + break; + case XML_TOK_TABLE_PASSWORD: + sPassword = sValue; + break; + case XML_TOK_TABLE_PRINT: + { + if (IsXMLToken(sValue, XML_FALSE)) + bPrintEntireSheet = sal_False; + } + break; + } + } + + rtl::OUString aExtUrl, aExtTabName; + if (lcl_isExternalRefCache(sName, aExtUrl, aExtTabName)) + { + // This is an external ref cache table. + pExternalRefInfo.reset(new ScXMLExternalTabData); + pExternalRefInfo->maFileUrl = aExtUrl; + ScDocument* pDoc = GetScImport().GetDocument(); + if (pDoc) + { + ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager(); + pExternalRefInfo->mnFileId = pRefMgr->getExternalFileId(aExtUrl); + pExternalRefInfo->mpCacheTable = pRefMgr->getCacheTable(pExternalRefInfo->mnFileId, aExtTabName, true); + pExternalRefInfo->mpCacheTable->setWholeTableCached(); + } + } + else + { + // This is a regular table. + GetScImport().GetTables().NewSheet(sName, sStyleName, bProtection, sPassword); + } + } + else + { + GetScImport().GetTables().NewTable(nSpannedCols); + } +} + +ScXMLTableContext::~ScXMLTableContext() +{ +} + +SvXMLImportContext *ScXMLTableContext::CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + const SvXMLTokenMap& rTokenMap(GetScImport().GetTableElemTokenMap()); + sal_uInt16 nToken = rTokenMap.Get(nPrefix, rLName); + if (pExternalRefInfo.get()) + { + // We only care about the table-row and table-source elements for + // external cache data. + switch (nToken) + { + case XML_TOK_TABLE_ROW_GROUP: + case XML_TOK_TABLE_HEADER_ROWS: + case XML_TOK_TABLE_ROWS: + // #i101319# don't discard rows in groups or header (repeat range) + return new ScXMLExternalRefRowsContext( + GetScImport(), nPrefix, rLName, xAttrList, *pExternalRefInfo); + case XML_TOK_TABLE_ROW: + return new ScXMLExternalRefRowContext( + GetScImport(), nPrefix, rLName, xAttrList, *pExternalRefInfo); + case XML_TOK_TABLE_SOURCE: + return new ScXMLExternalRefTabSourceContext( + GetScImport(), nPrefix, rLName, xAttrList, *pExternalRefInfo); + default: + ; + } + + return new SvXMLImportContext(GetImport(), nPrefix, rLName); + } + + SvXMLImportContext *pContext(0); + + switch (nToken) + { + case XML_TOK_TABLE_COL_GROUP: + pContext = new ScXMLTableColsContext( GetScImport(), nPrefix, + rLName, xAttrList, + sal_False, sal_True ); + break; + case XML_TOK_TABLE_HEADER_COLS: + pContext = new ScXMLTableColsContext( GetScImport(), nPrefix, + rLName, xAttrList, + sal_True, sal_False ); + break; + case XML_TOK_TABLE_COLS: + pContext = new ScXMLTableColsContext( GetScImport(), nPrefix, + rLName, xAttrList, + sal_False, sal_False ); + break; + case XML_TOK_TABLE_COL: + pContext = new ScXMLTableColContext( GetScImport(), nPrefix, + rLName, xAttrList ); + break; + case XML_TOK_TABLE_ROW_GROUP: + pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix, + rLName, xAttrList, + sal_False, sal_True ); + break; + case XML_TOK_TABLE_HEADER_ROWS: + pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix, + rLName, xAttrList, + sal_True, sal_False ); + break; + case XML_TOK_TABLE_ROWS: + pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix, + rLName, xAttrList, + sal_False, sal_False ); + break; + case XML_TOK_TABLE_ROW: + pContext = new ScXMLTableRowContext( GetScImport(), nPrefix, + rLName, xAttrList//, + //this + ); + break; + case XML_TOK_TABLE_SOURCE: + pContext = new ScXMLTableSourceContext( GetScImport(), nPrefix, rLName, xAttrList); + break; + case XML_TOK_TABLE_SCENARIO: + pContext = new ScXMLTableScenarioContext( GetScImport(), nPrefix, rLName, xAttrList); + break; + case XML_TOK_TABLE_SHAPES: + pContext = new ScXMLTableShapesContext( GetScImport(), nPrefix, rLName, xAttrList); + break; + case XML_TOK_TABLE_FORMS: + { + GetScImport().GetFormImport()->startPage(GetScImport().GetTables().GetCurrentXDrawPage()); + bStartFormPage = sal_True; + pContext = GetScImport().GetFormImport()->createOfficeFormsContext( GetScImport(), nPrefix, rLName ); + } + break; + case XML_TOK_TABLE_EVENT_LISTENERS: + case XML_TOK_TABLE_EVENT_LISTENERS_EXT: + { + // use XEventsSupplier interface of the sheet + uno::Reference<document::XEventsSupplier> xSupplier( GetScImport().GetTables().GetCurrentXSheet(), uno::UNO_QUERY ); + pContext = new XMLEventsImportContext( GetImport(), nPrefix, rLName, xSupplier ); + } + break; + default: + ; + } + + if( !pContext ) + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); + + return pContext; +} + +void ScXMLTableContext::EndElement() +{ + // get end offset in file (if available) +// sal_Int32 nEndOffset = GetScImport().GetByteOffset(); + + GetScImport().LockSolarMutex(); + GetScImport().GetStylesImportHelper()->EndTable(); + ScDocument* pDoc(GetScImport().GetDocument()); + if (pDoc) + { + if (sPrintRanges.getLength()) + { + uno::Reference< sheet::XPrintAreas > xPrintAreas( GetScImport().GetTables().GetCurrentXSheet(), uno::UNO_QUERY ); + if( xPrintAreas.is() ) + { + uno::Sequence< table::CellRangeAddress > aRangeList; + ScRangeStringConverter::GetRangeListFromString( aRangeList, sPrintRanges, pDoc, ::formula::FormulaGrammar::CONV_OOO ); + xPrintAreas->setPrintAreas( aRangeList ); + } + } + else if (bPrintEntireSheet) pDoc->SetPrintEntireSheet(static_cast<SCTAB>(GetScImport().GetTables().GetCurrentSheet())); + + ScOutlineTable* pOutlineTable(pDoc->GetOutlineTable(static_cast<SCTAB>(GetScImport().GetTables().GetCurrentSheet()), sal_False)); + if (pOutlineTable) + { + ScOutlineArray* pColArray(pOutlineTable->GetColArray()); + sal_Int32 nDepth(pColArray->GetDepth()); + sal_Int32 i; + for (i = 0; i < nDepth; ++i) + { + sal_Int32 nCount(pColArray->GetCount(static_cast<sal_uInt16>(i))); + for (sal_Int32 j = 0; j < nCount; ++j) + { + ScOutlineEntry* pEntry(pColArray->GetEntry(static_cast<sal_uInt16>(i), static_cast<sal_uInt16>(j))); + if (pEntry->IsHidden()) + pColArray->SetVisibleBelow(static_cast<sal_uInt16>(i), static_cast<sal_uInt16>(j), sal_False); + } + } + ScOutlineArray* pRowArray(pOutlineTable->GetRowArray()); + nDepth = pRowArray->GetDepth(); + for (i = 0; i < nDepth; ++i) + { + sal_Int32 nCount(pRowArray->GetCount(static_cast<sal_uInt16>(i))); + for (sal_Int32 j = 0; j < nCount; ++j) + { + ScOutlineEntry* pEntry(pRowArray->GetEntry(static_cast<sal_uInt16>(i), static_cast<sal_uInt16>(j))); + if (pEntry->IsHidden()) + pRowArray->SetVisibleBelow(static_cast<sal_uInt16>(i), static_cast<sal_uInt16>(j), sal_False); + } + } + } + if (GetScImport().GetTables().HasDrawPage()) + { + if (GetScImport().GetTables().HasXShapes()) + { + GetScImport().GetShapeImport()->popGroupAndSort(); + uno::Reference < drawing::XShapes > xTempShapes(GetScImport().GetTables().GetCurrentXShapes()); + GetScImport().GetShapeImport()->endPage(xTempShapes); + } + if (bStartFormPage) + GetScImport().GetFormImport()->endPage(); + } + + GetScImport().GetTables().DeleteTable(); + GetScImport().ProgressBarIncrement(sal_False); + + // store stream positions + if (!pExternalRefInfo.get() && nStartOffset >= 0 /* && nEndOffset >= 0 */) + { + ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData(); + sal_Int32 nTab = GetScImport().GetTables().GetCurrentSheet(); + // pSheetData->AddStreamPos( nTab, nStartOffset, nEndOffset ); + pSheetData->StartStreamPos( nTab, nStartOffset ); + } + } + GetScImport().UnlockSolarMutex(); +} + diff --git a/sc/source/filter/xml/xmltabi.hxx b/sc/source/filter/xml/xmltabi.hxx new file mode 100644 index 000000000000..9a60f4fcc170 --- /dev/null +++ b/sc/source/filter/xml/xmltabi.hxx @@ -0,0 +1,78 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef SC_XMLTABI_HXX +#define SC_XMLTABI_HXX + +#include "externalrefmgr.hxx" + +#include <xmloff/xmlictxt.hxx> +#include <memory> + +class ScXMLImport; + +struct ScXMLExternalTabData +{ + String maFileUrl; + ScExternalRefCache::TableTypeRef mpCacheTable; + sal_Int32 mnRow; + sal_Int32 mnCol; + sal_uInt16 mnFileId; + + ScXMLExternalTabData(); +}; + +class ScXMLTableContext : public SvXMLImportContext +{ + rtl::OUString sPrintRanges; + ::std::auto_ptr<ScXMLExternalTabData> pExternalRefInfo; + sal_Int32 nStartOffset; + sal_Bool bStartFormPage; + sal_Bool bPrintEntireSheet; + + const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); } + ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); } + +public: + + ScXMLTableContext( ScXMLImport& rImport, sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList, + const sal_Bool bTempIsSubTable = sal_False, + const sal_Int32 nSpannedCols = 0); + + virtual ~ScXMLTableContext(); + + virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + virtual void EndElement(); +}; + +#endif diff --git a/sc/source/filter/xml/xmlwrap.cxx b/sc/source/filter/xml/xmlwrap.cxx new file mode 100644 index 000000000000..9e721b7e9b1a --- /dev/null +++ b/sc/source/filter/xml/xmlwrap.cxx @@ -0,0 +1,1044 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- + +#include <rsc/rscsfx.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/objsh.hxx> +#include <tools/debug.hxx> +#include <vos/xception.hxx> +#include <comphelper/processfactory.hxx> +#include <unotools/streamwrap.hxx> +#include <svx/xmlgrhlp.hxx> +#include <svtools/sfxecode.hxx> +#include <sfx2/frame.hxx> +#include <svl/itemset.hxx> +#include <svl/stritem.hxx> +#include <sfx2/sfxsids.hrc> +#include <tools/urlobj.hxx> +#include <com/sun/star/container/XChild.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <com/sun/star/xml/sax/XErrorHandler.hpp> +#include <com/sun/star/xml/sax/XEntityResolver.hpp> +#include <com/sun/star/xml/sax/InputSource.hpp> +#include <com/sun/star/xml/sax/XDTDHandler.hpp> +#include <com/sun/star/xml/sax/XParser.hpp> +#include <com/sun/star/io/XActiveDataSource.hpp> +#include <com/sun/star/io/XActiveDataControl.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/task/XStatusIndicatorFactory.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <comphelper/extract.hxx> +#include <comphelper/propertysetinfo.hxx> +#include <comphelper/genericpropertyset.hxx> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/packages/zip/ZipIOException.hpp> +#include <com/sun/star/embed/ElementModes.hpp> +#include <com/sun/star/script/vba/XVBACompatibility.hpp> + +#include <svx/xmleohlp.hxx> +#include <rtl/logfile.hxx> +#include <unotools/saveopt.hxx> + +#include "document.hxx" +#include "xmlwrap.hxx" +#include "xmlimprt.hxx" +#include "xmlexprt.hxx" +#include "global.hxx" +#include "globstr.hrc" +#include "scerrors.hxx" +#include "XMLExportSharedData.hxx" +#include "docuno.hxx" +#include "sheetdata.hxx" +#include "XMLCodeNameProvider.hxx" + +#define MAP_LEN(x) x, sizeof(x) - 1 + +using namespace com::sun::star; +using ::rtl::OUString; + +// ----------------------------------------------------------------------- + +ScXMLImportWrapper::ScXMLImportWrapper(ScDocument& rD, SfxMedium* pM, const uno::Reference < embed::XStorage >& xStor ) : + rDoc(rD), + pMedium(pM), + xStorage(xStor) +{ + DBG_ASSERT( pMedium || xStorage.is(), "ScXMLImportWrapper: Medium or Storage must be set" ); +} + +//UNUSED2008-05 uno::Reference <task::XStatusIndicator> ScXMLImportWrapper::GetStatusIndicator( +//UNUSED2008-05 uno::Reference < frame::XModel> & rModel) +//UNUSED2008-05 { +//UNUSED2008-05 DBG_ERROR( "The status indicator from medium must be used!" ); +//UNUSED2008-05 +//UNUSED2008-05 uno::Reference<task::XStatusIndicator> xStatusIndicator; +//UNUSED2008-05 +//UNUSED2008-05 if (rModel.is()) +//UNUSED2008-05 { +//UNUSED2008-05 uno::Reference<frame::XController> xController( rModel->getCurrentController()); +//UNUSED2008-05 if ( xController.is()) +//UNUSED2008-05 { +//UNUSED2008-05 uno::Reference<task::XStatusIndicatorFactory> xFactory( xController->getFrame(), uno::UNO_QUERY ); +//UNUSED2008-05 if ( xFactory.is()) +//UNUSED2008-05 { +//UNUSED2008-05 try +//UNUSED2008-05 { +//UNUSED2008-05 xStatusIndicator.set(xFactory->createStatusIndicator()); +//UNUSED2008-05 } +//UNUSED2008-05 catch ( lang::DisposedException e ) +//UNUSED2008-05 { +//UNUSED2008-05 DBG_ERROR("Exception while trying to get a Status Indicator"); +//UNUSED2008-05 } +//UNUSED2008-05 } +//UNUSED2008-05 } +//UNUSED2008-05 } +//UNUSED2008-05 return xStatusIndicator; +//UNUSED2008-05 } + +uno::Reference <task::XStatusIndicator> ScXMLImportWrapper::GetStatusIndicator() +{ + uno::Reference<task::XStatusIndicator> xStatusIndicator; + if (pMedium) + { + SfxItemSet* pSet = pMedium->GetItemSet(); + if (pSet) + { + const SfxUnoAnyItem* pItem = static_cast<const SfxUnoAnyItem*>(pSet->GetItem(SID_PROGRESS_STATUSBAR_CONTROL)); + if (pItem) + xStatusIndicator.set(pItem->GetValue(), uno::UNO_QUERY); + } + } + return xStatusIndicator; +} + +sal_uInt32 ScXMLImportWrapper::ImportFromComponent(uno::Reference<lang::XMultiServiceFactory>& xServiceFactory, + uno::Reference<frame::XModel>& xModel, uno::Reference<uno::XInterface>& xXMLParser, + xml::sax::InputSource& aParserInput, + const rtl::OUString& sComponentName, const rtl::OUString& sDocName, + const rtl::OUString& sOldDocName, uno::Sequence<uno::Any>& aArgs, + sal_Bool bMustBeSuccessfull) +{ + uno::Reference < io::XStream > xDocStream; + if ( !xStorage.is() && pMedium ) + xStorage = pMedium->GetStorage(); + + // Get data source ... + +// uno::Reference< uno::XInterface > xPipe; +// uno::Reference< io::XActiveDataSource > xSource; + + sal_Bool bEncrypted = sal_False; + rtl::OUString sStream(sDocName); + if( xStorage.is() ) + { + try + { + uno::Reference < container::XNameAccess > xAccess( xStorage, uno::UNO_QUERY ); + if ( xAccess->hasByName(sDocName) && xStorage->isStreamElement( sDocName) ) + xDocStream = xStorage->openStreamElement( sDocName, embed::ElementModes::READ ); + else if (sOldDocName.getLength() && xAccess->hasByName(sOldDocName) && xStorage->isStreamElement( sOldDocName) ) + { + xDocStream = xStorage->openStreamElement( sOldDocName, embed::ElementModes::READ ); + sStream = sOldDocName; + } + else + return sal_False; + + aParserInput.aInputStream = xDocStream->getInputStream(); + uno::Reference < beans::XPropertySet > xSet( xDocStream, uno::UNO_QUERY ); + + uno::Any aAny = xSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("Encrypted") ) ); + aAny >>= bEncrypted; + } + catch( packages::WrongPasswordException& ) + { + return ERRCODE_SFX_WRONGPASSWORD; + } + catch( packages::zip::ZipIOException& ) + { + return ERRCODE_IO_BROKENPACKAGE; + } + catch( uno::Exception& ) + { + return SCERR_IMPORT_UNKNOWN; + } + } + // #99667#; no longer necessary +/* else if ( pMedium ) + { + // if there is a medium and if this medium has a load environment, + // we get an active data source from the medium. + pMedium->GetInStream()->Seek( 0 ); + xSource = pMedium->GetDataSource(); + DBG_ASSERT( xSource.is(), "got no data source from medium" ); + if( !xSource.is() ) + return sal_False; + + // get a pipe for connecting the data source to the parser + xPipe = xServiceFactory->createInstance( + OUString::createFromAscii("com.sun.star.io.Pipe") ); + DBG_ASSERT( xPipe.is(), + "XMLReader::Read: com.sun.star.io.Pipe service missing" ); + if( !xPipe.is() ) + return sal_False; + + // connect pipe's output stream to the data source + uno::Reference<io::XOutputStream> xPipeOutput( xPipe, uno::UNO_QUERY ); + xSource->setOutputStream( xPipeOutput ); + + aParserInput.aInputStream = + uno::Reference< io::XInputStream >( xPipe, uno::UNO_QUERY ); + }*/ + else + return SCERR_IMPORT_UNKNOWN; + + // set Base URL + uno::Reference< beans::XPropertySet > xInfoSet; + if( aArgs.getLength() > 0 ) + aArgs.getConstArray()[0] >>= xInfoSet; + DBG_ASSERT( xInfoSet.is(), "missing property set" ); + if( xInfoSet.is() ) + { + rtl::OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamName") ); + xInfoSet->setPropertyValue( sPropName, uno::makeAny( sStream ) ); + } + + sal_uInt32 nReturn(0); + rDoc.SetRangeOverflowType(0); // is modified by the importer if limits are exceeded + + uno::Reference<xml::sax::XDocumentHandler> xDocHandler( + xServiceFactory->createInstanceWithArguments( + sComponentName, aArgs ), + uno::UNO_QUERY ); + DBG_ASSERT( xDocHandler.is(), "can't get Calc importer" ); + uno::Reference<document::XImporter> xImporter( xDocHandler, uno::UNO_QUERY ); + uno::Reference<lang::XComponent> xComponent( xModel, uno::UNO_QUERY ); + if (xImporter.is()) + xImporter->setTargetDocument( xComponent ); + + // connect parser and filter + uno::Reference<xml::sax::XParser> xParser( xXMLParser, uno::UNO_QUERY ); + xParser->setDocumentHandler( xDocHandler ); + + // parse +/* if( xSource.is() ) + { + uno::Reference<io::XActiveDataControl> xSourceControl( xSource, uno::UNO_QUERY ); + if( xSourceControl.is() ) + xSourceControl->start(); + }*/ + + try + { + xParser->parseStream( aParserInput ); + } + catch( xml::sax::SAXParseException& r ) + { + // sax parser sends wrapped exceptions, + // try to find the original one + xml::sax::SAXException aSaxEx = *(xml::sax::SAXException*)(&r); + sal_Bool bTryChild = sal_True; + + while( bTryChild ) + { + xml::sax::SAXException aTmp; + if ( aSaxEx.WrappedException >>= aTmp ) + aSaxEx = aTmp; + else + bTryChild = sal_False; + } + + packages::zip::ZipIOException aBrokenPackage; + if ( aSaxEx.WrappedException >>= aBrokenPackage ) + return ERRCODE_IO_BROKENPACKAGE; + else if( bEncrypted ) + nReturn = ERRCODE_SFX_WRONGPASSWORD; + else + { + +#ifdef DBG_UTIL + ByteString aError( "SAX parse exception catched while importing:\n" ); + aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US ); + DBG_ERROR( aError.GetBuffer() ); +#endif + + String sErr( String::CreateFromInt32( r.LineNumber )); + sErr += ','; + sErr += String::CreateFromInt32( r.ColumnNumber ); + + if( sDocName.getLength() ) + { + nReturn = *new TwoStringErrorInfo( + (bMustBeSuccessfull ? SCERR_IMPORT_FILE_ROWCOL + : SCWARN_IMPORT_FILE_ROWCOL), + sDocName, sErr, + ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR ); + } + else + { + DBG_ASSERT( bMustBeSuccessfull, "Warnings are not supported" ); + nReturn = *new StringErrorInfo( SCERR_IMPORT_FORMAT_ROWCOL, sErr, + ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR ); + } + } + } + catch( xml::sax::SAXException& r ) + { + packages::zip::ZipIOException aBrokenPackage; + if ( r.WrappedException >>= aBrokenPackage ) + return ERRCODE_IO_BROKENPACKAGE; + else if( bEncrypted ) + nReturn = ERRCODE_SFX_WRONGPASSWORD; + else + { + +#ifdef DBG_UTIL + ByteString aError( "SAX exception catched while importing:\n" ); + aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US ); + DBG_ERROR( aError.GetBuffer() ); +#endif + (void)r; // avoid warning in product version + + nReturn = SCERR_IMPORT_FORMAT; + } + } + catch( packages::zip::ZipIOException& r ) + { +#ifdef DBG_UTIL + ByteString aError( "Zip exception catched while importing:\n" ); + aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US ); + DBG_ERROR( aError.GetBuffer() ); +#endif + (void)r; // avoid warning in product version + + nReturn = ERRCODE_IO_BROKENPACKAGE; + } + catch( io::IOException& r ) + { +#ifdef DBG_UTIL + ByteString aError( "IO exception catched while importing:\n" ); + aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US ); + DBG_ERROR( aError.GetBuffer() ); +#endif + (void)r; // avoid warning in product version + + nReturn = SCERR_IMPORT_OPEN; + } + catch( uno::Exception& r ) + { +#ifdef DBG_UTIL + ByteString aError( "uno exception catched while importing:\n" ); + aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US ); + DBG_ERROR( aError.GetBuffer() ); +#endif + (void)r; // avoid warning in product version + + nReturn = SCERR_IMPORT_UNKNOWN; + } + + // #i31130# Can't use getImplementation here to get the ScXMLImport from xDocHandler, + // because when OOo 1.x files are loaded, xDocHandler is the OOo2OasisTransformer. + // So the overflow warning ErrorCode is now stored in the document. + // Export works differently, there getImplementation still works. + + if (rDoc.HasRangeOverflow() && !nReturn) + nReturn = rDoc.GetRangeOverflowType(); + + // free the component + xParser->setDocumentHandler( NULL ); + + // success! + return nReturn; +} + +sal_Bool ScXMLImportWrapper::Import(sal_Bool bStylesOnly, ErrCode& nError) +{ + RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "sb99857", "ScXMLImportWrapper::Import" ); + + uno::Reference<lang::XMultiServiceFactory> xServiceFactory = + comphelper::getProcessServiceFactory(); + DBG_ASSERT( xServiceFactory.is(), "got no service manager" ); + if( !xServiceFactory.is() ) + return sal_False; + + xml::sax::InputSource aParserInput; + if (pMedium) + aParserInput.sSystemId = OUString(pMedium->GetName()); + + if ( !xStorage.is() && pMedium ) + xStorage = pMedium->GetStorage(); + + // get parser + uno::Reference<uno::XInterface> xXMLParser( + xServiceFactory->createInstance( + OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Parser" )) )); + DBG_ASSERT( xXMLParser.is(), "com.sun.star.xml.sax.Parser service missing" ); + if( !xXMLParser.is() ) + return sal_False; + + // get filter + SfxObjectShell* pObjSh = rDoc.GetDocumentShell(); + if ( pObjSh ) + { + rtl::OUString sEmpty; + uno::Reference<frame::XModel> xModel(pObjSh->GetModel()); + + /** property map for export info set */ + comphelper::PropertyMapEntry aImportInfoMap[] = + { + { MAP_LEN( "ProgressRange" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, + { MAP_LEN( "ProgressMax" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, + { MAP_LEN( "ProgressCurrent" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, + { MAP_LEN( "NumberStyles" ), 0, &::getCppuType((uno::Reference<container::XNameAccess> *)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, + { MAP_LEN( "PrivateData" ), 0, &::getCppuType( (uno::Reference<uno::XInterface> *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { MAP_LEN( "BaseURI" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { MAP_LEN( "StreamRelPath" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { MAP_LEN( "StreamName" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { MAP_LEN( "BuildId" ), 0, &::getCppuType( (OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { MAP_LEN( "VBACompatibilityMode" ), 0, &::getBooleanCppuType(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { MAP_LEN( "ScriptConfiguration" ), 0, &::getCppuType((uno::Reference<container::XNameAccess> *)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, + + { NULL, 0, 0, NULL, 0, 0 } + }; + uno::Reference< beans::XPropertySet > xInfoSet( comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aImportInfoMap ) ) ); + + // ---- get BuildId from parent container if available + + uno::Reference< container::XChild > xChild( xModel, uno::UNO_QUERY ); + if( xChild.is() ) + { + uno::Reference< beans::XPropertySet > xParentSet( xChild->getParent(), uno::UNO_QUERY ); + if( xParentSet.is() ) + { + uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xParentSet->getPropertySetInfo() ); + OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("BuildId" ) ); + if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(sPropName) ) + { + xInfoSet->setPropertyValue( sPropName, xParentSet->getPropertyValue(sPropName) ); + } + } + } + + // ------------------------------------- + + uno::Reference<task::XStatusIndicator> xStatusIndicator(GetStatusIndicator()); + if (xStatusIndicator.is()) + { + sal_Int32 nProgressRange(1000000); + xStatusIndicator->start(rtl::OUString(ScGlobal::GetRscString(STR_LOAD_DOC)), nProgressRange); + xInfoSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ProgressRange")), uno::makeAny(nProgressRange)); + } + + // Set base URI + OSL_ENSURE( pMedium, "There is no medium to get MediaDescriptor from!\n" ); + ::rtl::OUString aBaseURL = pMedium ? pMedium->GetBaseURL() : ::rtl::OUString(); + rtl::OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") ); + xInfoSet->setPropertyValue( sPropName, uno::makeAny( aBaseURL ) ); + + // TODO/LATER: do not do it for embedded links + if( SFX_CREATE_MODE_EMBEDDED == pObjSh->GetCreateMode() ) + { + OUString aName; + if ( pMedium && pMedium->GetItemSet() ) + { + const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>( + pMedium->GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) ); + if ( pDocHierarchItem ) + aName = pDocHierarchItem->GetValue(); + } + else + aName = ::rtl::OUString::createFromAscii( "dummyObjectName" ); + + if( aName.getLength() ) + { + sPropName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath")); + xInfoSet->setPropertyValue( sPropName, uno::makeAny( aName ) ); + } + } + + sal_Bool bOasis = ( SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_60 ); + + sal_uInt32 nMetaRetval(0); + if(!bStylesOnly) + { + uno::Sequence<uno::Any> aMetaArgs(1); + uno::Any* pMetaArgs = aMetaArgs.getArray(); + pMetaArgs[0] <<= xInfoSet; + + RTL_LOGFILE_CONTEXT_TRACE( aLog, "meta import start" ); + + nMetaRetval = ImportFromComponent(xServiceFactory, xModel, xXMLParser, aParserInput, + bOasis ? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisMetaImporter")) + : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLMetaImporter")), + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("meta.xml")), + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Meta.xml")), aMetaArgs, + sal_False); + + RTL_LOGFILE_CONTEXT_TRACE( aLog, "meta import end" ); + } + + SvXMLGraphicHelper* pGraphicHelper = NULL; + uno::Reference< document::XGraphicObjectResolver > xGrfContainer; + + uno::Reference< document::XEmbeddedObjectResolver > xObjectResolver; + SvXMLEmbeddedObjectHelper *pObjectHelper = NULL; + + if( xStorage.is() ) + { + pGraphicHelper = SvXMLGraphicHelper::Create( xStorage, GRAPHICHELPER_MODE_READ ); + xGrfContainer = pGraphicHelper; + + if( pObjSh ) + { + pObjectHelper = SvXMLEmbeddedObjectHelper::Create(xStorage, *pObjSh, EMBEDDEDOBJECTHELPER_MODE_READ, sal_False ); + xObjectResolver = pObjectHelper; + } + } + uno::Sequence<uno::Any> aStylesArgs(4); + uno::Any* pStylesArgs = aStylesArgs.getArray(); + pStylesArgs[0] <<= xInfoSet; + pStylesArgs[1] <<= xGrfContainer; + pStylesArgs[2] <<= xStatusIndicator; + pStylesArgs[3] <<= xObjectResolver; + + sal_uInt32 nSettingsRetval(0); + if (!bStylesOnly) + { + // Settings must be loaded first because of the printer setting, + // which is needed in the page styles (paper tray). + + uno::Sequence<uno::Any> aSettingsArgs(1); + uno::Any* pSettingsArgs = aSettingsArgs.getArray(); + pSettingsArgs[0] <<= xInfoSet; + + RTL_LOGFILE_CONTEXT_TRACE( aLog, "settings import start" ); + + nSettingsRetval = ImportFromComponent(xServiceFactory, xModel, xXMLParser, aParserInput, + bOasis ? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisSettingsImporter")) + : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLSettingsImporter")), + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("settings.xml")), + sEmpty, aSettingsArgs, sal_False); + + RTL_LOGFILE_CONTEXT_TRACE( aLog, "settings import end" ); + } + + sal_uInt32 nStylesRetval(0); + { + RTL_LOGFILE_CONTEXT_TRACE( aLog, "styles import start" ); + + nStylesRetval = ImportFromComponent(xServiceFactory, xModel, xXMLParser, aParserInput, + bOasis ? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisStylesImporter")) + : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLStylesImporter")), + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("styles.xml")), + sEmpty, aStylesArgs, sal_True); + + RTL_LOGFILE_CONTEXT_TRACE( aLog, "styles import end" ); + } + + sal_uInt32 nDocRetval(0); + if (!bStylesOnly) + { + uno::Sequence<uno::Any> aDocArgs(4); + uno::Any* pDocArgs = aDocArgs.getArray(); + pDocArgs[0] <<= xInfoSet; + pDocArgs[1] <<= xGrfContainer; + pDocArgs[2] <<= xStatusIndicator; + pDocArgs[3] <<= xObjectResolver; + + RTL_LOGFILE_CONTEXT_TRACE( aLog, "content import start" ); + + nDocRetval = ImportFromComponent(xServiceFactory, xModel, xXMLParser, aParserInput, + bOasis ? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisContentImporter")) + : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLContentImporter")), + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("content.xml")), + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Content.xml")), aDocArgs, + sal_True); + + RTL_LOGFILE_CONTEXT_TRACE( aLog, "content import end" ); + } + if( pGraphicHelper ) + SvXMLGraphicHelper::Destroy( pGraphicHelper ); + + if( pObjectHelper ) + SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper ); + + if (xStatusIndicator.is()) + xStatusIndicator->end(); + + sal_Bool bRet(sal_False); + if (bStylesOnly) + { + if (nStylesRetval) + nError = nStylesRetval; + else + bRet = sal_True; + } + else + { + if (nDocRetval) + { + nError = nDocRetval; + if (nDocRetval == SCWARN_IMPORT_RANGE_OVERFLOW || + nDocRetval == SCWARN_IMPORT_ROW_OVERFLOW || + nDocRetval == SCWARN_IMPORT_COLUMN_OVERFLOW || + nDocRetval == SCWARN_IMPORT_SHEET_OVERFLOW) + bRet = sal_True; + } + else if (nStylesRetval) + nError = nStylesRetval; + else if (nMetaRetval) + nError = nMetaRetval; + else if (nSettingsRetval) + nError = nSettingsRetval; + else + bRet = sal_True; + } + + // set BuildId on XModel for later OLE object loading + if( xInfoSet.is() ) + { + uno::Reference< beans::XPropertySet > xModelSet( xModel, uno::UNO_QUERY ); + if( xModelSet.is() ) + { + uno::Reference< beans::XPropertySetInfo > xModelSetInfo( xModelSet->getPropertySetInfo() ); + OUString sBuildPropName( RTL_CONSTASCII_USTRINGPARAM("BuildId" ) ); + if( xModelSetInfo.is() && xModelSetInfo->hasPropertyByName(sBuildPropName) ) + { + xModelSet->setPropertyValue( sBuildPropName, xInfoSet->getPropertyValue(sBuildPropName) ); + } + } + + // Set Code Names + uno::Any aAny = xInfoSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("ScriptConfiguration") )); + uno::Reference <container::XNameAccess> xCodeNameAccess; + if( aAny >>= xCodeNameAccess ) + XMLCodeNameProvider::set( xCodeNameAccess, &rDoc ); + + // VBA compatibility + bool bVBACompat = false; + if ( (xInfoSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("VBACompatibilityMode"))) >>= bVBACompat) && bVBACompat ) + { + /* Set library container to VBA compatibility mode, this + forces loading the Basic project, which in turn creates the + VBA Globals object and does all related initialization. */ + if ( xModelSet.is() ) try + { + uno::Reference< script::vba::XVBACompatibility > xVBACompat( xModelSet->getPropertyValue( + OUString( RTL_CONSTASCII_USTRINGPARAM( "BasicLibraries" ) ) ), uno::UNO_QUERY_THROW ); + xVBACompat->setVBACompatibilityMode( sal_True ); + } + catch( uno::Exception& ) + { + } + } + } + + // Don't test bStylesRetval and bMetaRetval, because it could be an older file which not contain such streams + return bRet;//!bStylesOnly ? bDocRetval : bStylesRetval; + } + return sal_False; +} + +bool lcl_HasValidStream(ScDocument& rDoc) +{ + SfxObjectShell* pObjSh = rDoc.GetDocumentShell(); + if ( pObjSh->IsDocShared() ) + return false; // never copy stream from shared file + + // don't read remote file again + // (could instead re-use medium directly in that case) + SfxMedium* pSrcMed = rDoc.GetDocumentShell()->GetMedium(); + if ( !pSrcMed || pSrcMed->IsRemote() ) + return false; + + SCTAB nTabCount = rDoc.GetTableCount(); + for (SCTAB nTab=0; nTab<nTabCount; ++nTab) + if (rDoc.IsStreamValid(nTab)) + return true; + return false; +} + +sal_Bool ScXMLImportWrapper::ExportToComponent(uno::Reference<lang::XMultiServiceFactory>& xServiceFactory, + uno::Reference<frame::XModel>& xModel, uno::Reference<uno::XInterface>& xWriter, + uno::Sequence<beans::PropertyValue>& aDescriptor, const rtl::OUString& sName, + const rtl::OUString& sMediaType, const rtl::OUString& sComponentName, + const sal_Bool bPlainText, uno::Sequence<uno::Any>& aArgs, ScMySharedData*& pSharedData) +{ + sal_Bool bRet(sal_False); + uno::Reference<io::XOutputStream> xOut; + uno::Reference<io::XStream> xStream; + + if ( !xStorage.is() && pMedium ) + xStorage = pMedium->GetOutputStorage(); + + if( xStorage.is() ) + { + // #96807#; trunc stream before use, because it could be an existing stream + // and the new content could be shorter than the old content. In this case + // would not all be over written by the new content and the xml file + // would not be valid. + xStream = xStorage->openStreamElement( sName, embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE ); + uno::Reference < beans::XPropertySet > xSet( xStream, uno::UNO_QUERY ); + if (xSet.is()) + { + xSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MediaType")), uno::makeAny(sMediaType)); + OUString aUseCommonPassPropName( RTL_CONSTASCII_USTRINGPARAM("UseCommonStoragePasswordEncryption") ); + if (bPlainText) + xSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Compressed")), uno::makeAny(sal_False)); + + // even plain stream should be encrypted in encrypted documents + xSet->setPropertyValue( aUseCommonPassPropName, uno::makeAny(sal_True) ); + } + + xOut = xStream->getOutputStream(); + } + // #99667#; no longer necessary +/* else if ( pMedium ) + { + xOut = pMedium->GetDataSink(); + }*/ + + // set Base URL + uno::Reference< beans::XPropertySet > xInfoSet; + if( aArgs.getLength() > 0 ) + aArgs.getConstArray()[0] >>= xInfoSet; + DBG_ASSERT( xInfoSet.is(), "missing property set" ); + if( xInfoSet.is() ) + { + rtl::OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamName") ); + xInfoSet->setPropertyValue( sPropName, uno::makeAny( sName ) ); + } + + uno::Reference<io::XActiveDataSource> xSrc( xWriter, uno::UNO_QUERY ); + xSrc->setOutputStream( xOut ); + + uno::Reference<document::XFilter> xFilter( + xServiceFactory->createInstanceWithArguments( sComponentName , aArgs ), + uno::UNO_QUERY ); + DBG_ASSERT( xFilter.is(), "can't get exporter" ); + uno::Reference<document::XExporter> xExporter( xFilter, uno::UNO_QUERY ); + uno::Reference<lang::XComponent> xComponent( xModel, uno::UNO_QUERY ); + if (xExporter.is()) + xExporter->setSourceDocument( xComponent ); + + if ( xFilter.is() ) + { + ScXMLExport* pExport = static_cast<ScXMLExport*>(SvXMLExport::getImplementation(xFilter)); + pExport->SetSharedData(pSharedData); + + // if there are sheets to copy, get the source stream + if ( sName.equalsAscii("content.xml") && lcl_HasValidStream(rDoc) && + ( pExport->getExportFlags() & EXPORT_OASIS ) ) + { + // old stream is still in this file's storage - open read-only + + // #i106854# use the document's storage directly, without a temporary SfxMedium + uno::Reference<embed::XStorage> xTmpStorage = rDoc.GetDocumentShell()->GetStorage(); + uno::Reference<io::XStream> xSrcStream; + uno::Reference<io::XInputStream> xSrcInput; + + // #i108978# If an embedded object is saved and no events are notified, don't use the stream + // because without the ...DONE events, stream positions aren't updated. + ScSheetSaveData* pSheetData = ScModelObj::getImplementation(xModel)->GetSheetSaveData(); + if (pSheetData && pSheetData->IsInSupportedSave()) + { + try + { + if (xTmpStorage.is()) + xSrcStream = xTmpStorage->openStreamElement( sName, embed::ElementModes::READ ); + if (xSrcStream.is()) + xSrcInput = xSrcStream->getInputStream(); + } + catch (uno::Exception&) + { + // stream not available (for example, password protected) - save normally (xSrcInput is null) + } + } + + pExport->SetSourceStream( xSrcInput ); + bRet = xFilter->filter( aDescriptor ); + pExport->SetSourceStream( uno::Reference<io::XInputStream>() ); + + // If there was an error, reset all stream flags, so the next save attempt will use normal saving. + // #i110692# For embedded objects, the stream may be unavailable for one save operation (m_pAntiImpl) + // and become available again later. But after saving normally once, the stream positions aren't + // valid anymore, so the flags also have to be reset if the stream wasn't available. + if ( !bRet || !xSrcInput.is() ) + { + SCTAB nTabCount = rDoc.GetTableCount(); + for (SCTAB nTab=0; nTab<nTabCount; nTab++) + if (rDoc.IsStreamValid(nTab)) + rDoc.SetStreamValid(nTab, sal_False); + } + } + else + bRet = xFilter->filter( aDescriptor ); + + pSharedData = pExport->GetSharedData(); + + //stream is closed by SAX parser + //if (xOut.is()) + // xOut->closeOutput(); + } + return bRet; +} + +sal_Bool ScXMLImportWrapper::Export(sal_Bool bStylesOnly) +{ + RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "sb99857", "ScXMLImportWrapper::Export" ); + + uno::Reference<lang::XMultiServiceFactory> xServiceFactory(comphelper::getProcessServiceFactory()); + DBG_ASSERT( xServiceFactory.is(), "got no service manager" ); + if( !xServiceFactory.is() ) + return sal_False; + + uno::Reference<uno::XInterface> xWriter(xServiceFactory->createInstance( + OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Writer" )) )); + DBG_ASSERT( xWriter.is(), "com.sun.star.xml.sax.Writer service missing" ); + if(!xWriter.is()) + return sal_False; + + if ( !xStorage.is() && pMedium ) + xStorage = pMedium->GetOutputStorage(); + + uno::Reference<xml::sax::XDocumentHandler> xHandler( xWriter, uno::UNO_QUERY ); + + OUString sFileName; + OUString sTextMediaType(RTL_CONSTASCII_USTRINGPARAM("text/xml")); + if (pMedium) + sFileName = pMedium->GetName(); + SfxObjectShell* pObjSh = rDoc.GetDocumentShell(); + uno::Sequence<beans::PropertyValue> aDescriptor(1); + beans::PropertyValue* pProps = aDescriptor.getArray(); + pProps[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "FileName" ) ); + pProps[0].Value <<= sFileName; + + /** property map for export info set */ + comphelper::PropertyMapEntry aExportInfoMap[] = + { + { MAP_LEN( "ProgressRange" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, + { MAP_LEN( "ProgressMax" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, + { MAP_LEN( "ProgressCurrent" ), 0, &::getCppuType((sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, + { MAP_LEN( "WrittenNumberStyles" ), 0, &::getCppuType((uno::Sequence<sal_Int32>*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, + { MAP_LEN( "UsePrettyPrinting" ), 0, &::getCppuType((sal_Bool*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, + { MAP_LEN( "BaseURI" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { MAP_LEN( "StreamRelPath" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { MAP_LEN( "StreamName" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { MAP_LEN( "StyleNames" ), 0, &::getCppuType( (uno::Sequence<rtl::OUString>*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { MAP_LEN( "StyleFamilies" ), 0, &::getCppuType( (uno::Sequence<sal_Int32>*)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { MAP_LEN( "TargetStorage" ), 0, &embed::XStorage::static_type(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { NULL, 0, 0, NULL, 0, 0 } + }; + uno::Reference< beans::XPropertySet > xInfoSet( comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aExportInfoMap ) ) ); + + if ( pObjSh && xStorage.is() ) + { + pObjSh->UpdateDocInfoForSave(); // update information + + uno::Reference<frame::XModel> xModel(pObjSh->GetModel()); + uno::Reference<task::XStatusIndicator> xStatusIndicator(GetStatusIndicator()); + sal_Int32 nProgressRange(1000000); + if(xStatusIndicator.is()) + xStatusIndicator->start(rtl::OUString(ScGlobal::GetRscString(STR_SAVE_DOC)), nProgressRange); + xInfoSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ProgressRange")), uno::makeAny(nProgressRange)); + + SvtSaveOptions aSaveOpt; + sal_Bool bUsePrettyPrinting(aSaveOpt.IsPrettyPrinting()); + xInfoSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UsePrettyPrinting")), uno::makeAny(bUsePrettyPrinting)); + + const OUString sTargetStorage( RTL_CONSTASCII_USTRINGPARAM("TargetStorage") ); + xInfoSet->setPropertyValue( sTargetStorage, uno::Any( xStorage ) ); + + OSL_ENSURE( pMedium, "There is no medium to get MediaDescriptor from!\n" ); + ::rtl::OUString aBaseURL = pMedium ? pMedium->GetBaseURL( true ) : ::rtl::OUString(); + rtl::OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") ); + xInfoSet->setPropertyValue( sPropName, uno::makeAny( aBaseURL ) ); + + // TODO/LATER: do not do it for embedded links + if( SFX_CREATE_MODE_EMBEDDED == pObjSh->GetCreateMode() ) + { + OUString aName = ::rtl::OUString::createFromAscii( "dummyObjectName" ); + if ( pMedium && pMedium->GetItemSet() ) + { + const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>( + pMedium->GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) ); + if ( pDocHierarchItem ) + aName = pDocHierarchItem->GetValue(); + } + + if( aName.getLength() ) + { + sPropName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath")); + xInfoSet->setPropertyValue( sPropName, uno::makeAny( aName ) ); + } + } + + sal_Bool bMetaRet(pObjSh->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED); + sal_Bool bStylesRet (sal_False); + sal_Bool bDocRet(sal_False); + sal_Bool bSettingsRet(sal_False); + ScMySharedData* pSharedData = NULL; + + sal_Bool bOasis = ( SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_60 ); + + // meta export + if (!bStylesOnly && !bMetaRet) + { + uno::Sequence<uno::Any> aMetaArgs(3); + uno::Any* pMetaArgs = aMetaArgs.getArray(); + pMetaArgs[0] <<= xInfoSet; + pMetaArgs[1] <<= xHandler; + pMetaArgs[2] <<= xStatusIndicator; + + RTL_LOGFILE_CONTEXT_TRACE( aLog, "meta export start" ); + + bMetaRet = ExportToComponent(xServiceFactory, xModel, xWriter, aDescriptor, + rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("meta.xml")), + sTextMediaType, + bOasis ? rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisMetaExporter")) + : rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLMetaExporter")), + sal_True, aMetaArgs, pSharedData); + + RTL_LOGFILE_CONTEXT_TRACE( aLog, "meta export end" ); + } + + uno::Reference< document::XEmbeddedObjectResolver > xObjectResolver; + SvXMLEmbeddedObjectHelper *pObjectHelper = 0; + + uno::Reference< document::XGraphicObjectResolver > xGrfContainer; + SvXMLGraphicHelper* pGraphicHelper = 0; + + if( xStorage.is() ) + { + pGraphicHelper = SvXMLGraphicHelper::Create( xStorage, GRAPHICHELPER_MODE_WRITE, sal_False ); + xGrfContainer = pGraphicHelper; + } + + if( pObjSh ) + { + pObjectHelper = SvXMLEmbeddedObjectHelper::Create( xStorage, *pObjSh, EMBEDDEDOBJECTHELPER_MODE_WRITE, sal_False ); + xObjectResolver = pObjectHelper; + } + + // styles export + + { + uno::Sequence<uno::Any> aStylesArgs(5); + uno::Any* pStylesArgs = aStylesArgs.getArray(); + pStylesArgs[0] <<= xInfoSet; + pStylesArgs[1] <<= xGrfContainer; + pStylesArgs[2] <<= xStatusIndicator; + pStylesArgs[3] <<= xHandler; + pStylesArgs[4] <<= xObjectResolver; + + RTL_LOGFILE_CONTEXT_TRACE( aLog, "styles export start" ); + + bStylesRet = ExportToComponent(xServiceFactory, xModel, xWriter, aDescriptor, + rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("styles.xml")), + sTextMediaType, + bOasis ? rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisStylesExporter")) + : rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLStylesExporter")), + sal_False, aStylesArgs, pSharedData); + + RTL_LOGFILE_CONTEXT_TRACE( aLog, "styles export end" ); + } + + // content export + + if (!bStylesOnly) + { + uno::Sequence<uno::Any> aDocArgs(5); + uno::Any* pDocArgs = aDocArgs.getArray(); + pDocArgs[0] <<= xInfoSet; + pDocArgs[1] <<= xGrfContainer; + pDocArgs[2] <<= xStatusIndicator; + pDocArgs[3] <<= xHandler; + pDocArgs[4] <<= xObjectResolver; + + RTL_LOGFILE_CONTEXT_TRACE( aLog, "content export start" ); + + bDocRet = ExportToComponent(xServiceFactory, xModel, xWriter, aDescriptor, + rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("content.xml")), + sTextMediaType, + bOasis ? rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisContentExporter")) + : rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLContentExporter")), + sal_False, aDocArgs, pSharedData); + + RTL_LOGFILE_CONTEXT_TRACE( aLog, "content export end" ); + } + + if( pGraphicHelper ) + SvXMLGraphicHelper::Destroy( pGraphicHelper ); + + if( pObjectHelper ) + SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper ); + + // settings export + + if (!bStylesOnly) + { + uno::Sequence<uno::Any> aSettingsArgs(3); + uno::Any* pSettingsArgs = aSettingsArgs.getArray(); + pSettingsArgs[0] <<= xInfoSet; + pSettingsArgs[1] <<= xHandler; + pSettingsArgs[2] <<= xStatusIndicator; + + RTL_LOGFILE_CONTEXT_TRACE( aLog, "settings export start" ); + + bSettingsRet = ExportToComponent(xServiceFactory, xModel, xWriter, aDescriptor, + rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("settings.xml")), + sTextMediaType, + bOasis ? rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisSettingsExporter")) + : rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLSettingsExporter")), + sal_False, aSettingsArgs, pSharedData); + + RTL_LOGFILE_CONTEXT_TRACE( aLog, "settings export end" ); + } + + if (pSharedData) + delete pSharedData; + + if (xStatusIndicator.is()) + xStatusIndicator->end(); + return bStylesRet && ((!bStylesOnly && bDocRet && bMetaRet && bSettingsRet) || bStylesOnly); + } + + // later: give string descriptor as parameter for doc type + + return sal_False; +} + + + |