diff options
Diffstat (limited to 'xmloff/source/core')
34 files changed, 15151 insertions, 0 deletions
diff --git a/xmloff/source/core/DocumentSettingsContext.cxx b/xmloff/source/core/DocumentSettingsContext.cxx new file mode 100644 index 000000000..0a114ab0d --- /dev/null +++ b/xmloff/source/core/DocumentSettingsContext.cxx @@ -0,0 +1,762 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <officecfg/Office/Common.hxx> +#include <sax/tools/converter.hxx> + +#include <com/sun/star/util/PathSubstitution.hpp> +#include <com/sun/star/util/XStringSubstitution.hpp> +#include <xmloff/DocumentSettingsContext.hxx> +#include <xmloff/xmlimp.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/nmspmap.hxx> +#include <comphelper/base64.hxx> + +#include <vector> +#include <com/sun/star/i18n/XForbiddenCharacters.hpp> +#include <com/sun/star/container/XIndexContainer.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/formula/SymbolDescriptor.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/util/DateTime.hpp> +#include <com/sun/star/document/XViewDataSupplier.hpp> +#include <com/sun/star/document/PrinterIndependentLayout.hpp> +#include <com/sun/star/document/IndexedPropertyValues.hpp> +#include <com/sun/star/document/NamedPropertyValues.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <sal/log.hxx> +#include <osl/diagnose.h> +#include <tools/diagnose_ex.h> +#include <unotools/configmgr.hxx> +#include "xmlenums.hxx" + +using namespace com::sun::star; +using namespace ::xmloff::token; + +namespace { + +class XMLMyList +{ + std::vector<beans::PropertyValue> aProps; + sal_uInt32 nCount; + + css::uno::Reference< css::uno::XComponentContext > m_xContext; + +public: + explicit XMLMyList(const uno::Reference<uno::XComponentContext>& rxContext); + + void push_back(beans::PropertyValue const & aProp) { aProps.push_back(aProp); nCount++; } + uno::Sequence<beans::PropertyValue> GetSequence(); + uno::Reference<container::XNameContainer> GetNameContainer(); + uno::Reference<container::XIndexContainer> GetIndexContainer(); +}; + +} + +XMLMyList::XMLMyList(const uno::Reference<uno::XComponentContext>& rxContext) +: nCount(0), + m_xContext(rxContext) +{ + assert(m_xContext.is()); +} + +uno::Sequence<beans::PropertyValue> XMLMyList::GetSequence() +{ + uno::Sequence<beans::PropertyValue> aSeq; + if(nCount) + { + assert(nCount == aProps.size()); + aSeq.realloc(nCount); + beans::PropertyValue* pProps = aSeq.getArray(); + for (auto const& prop : aProps) + { + *pProps = prop; + ++pProps; + } + } + return aSeq; +} + +uno::Reference<container::XNameContainer> XMLMyList::GetNameContainer() +{ + uno::Reference<container::XNameContainer> xNameContainer = document::NamedPropertyValues::create(m_xContext); + for (auto const& prop : aProps) + { + xNameContainer->insertByName(prop.Name, prop.Value); + } + + return xNameContainer; +} + +uno::Reference<container::XIndexContainer> XMLMyList::GetIndexContainer() +{ + uno::Reference<container::XIndexContainer> xIndexContainer = document::IndexedPropertyValues::create(m_xContext); + sal_uInt32 i(0); + for (auto const& prop : aProps) + { + xIndexContainer->insertByIndex(i, prop.Value); + ++i; + } + + return xIndexContainer; +} + +namespace { + +class XMLConfigBaseContext : public SvXMLImportContext +{ +protected: + XMLMyList maProps; + beans::PropertyValue maProp; + css::uno::Any& mrAny; + XMLConfigBaseContext* mpBaseContext; +public: + XMLConfigBaseContext(SvXMLImport& rImport, + css::uno::Any& rAny, + XMLConfigBaseContext* pBaseContext); + + void AddPropertyValue() { maProps.push_back(maProp); } + + virtual void SAL_CALL startFastElement( sal_Int32 /*nElement*/, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& ) override {} +}; + +class XMLConfigItemContext : public SvXMLImportContext +{ + OUString msType; + css::uno::Any& mrAny; + const OUString mrItemName; + XMLConfigBaseContext* mpBaseContext; + OUStringBuffer maCharBuffer; + +public: + XMLConfigItemContext(SvXMLImport& rImport, + const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList, + css::uno::Any& rAny, + const OUString& rItemName, + XMLConfigBaseContext* pBaseContext); + + virtual void SAL_CALL startFastElement( sal_Int32 /*nElement*/, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& ) override {} + + virtual void SAL_CALL characters( const OUString& rChars ) override; + + virtual void SAL_CALL endFastElement(sal_Int32 nElement) override; + + void ManipulateConfigItem(); +}; + +class XMLConfigItemSetContext : public XMLConfigBaseContext +{ +public: + XMLConfigItemSetContext(SvXMLImport& rImport, + css::uno::Any& rAny, + XMLConfigBaseContext* pBaseContext); + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override; + + virtual void SAL_CALL endFastElement(sal_Int32 nElement) override; +}; + +class XMLConfigItemMapNamedContext : public XMLConfigBaseContext +{ +public: + XMLConfigItemMapNamedContext(SvXMLImport& rImport, + css::uno::Any& rAny, + XMLConfigBaseContext* pBaseContext); + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override; + + virtual void SAL_CALL endFastElement(sal_Int32 nElement) override; +}; + +class XMLConfigItemMapIndexedContext : public XMLConfigBaseContext +{ +private: + OUString maConfigItemName; + +public: + XMLConfigItemMapIndexedContext(SvXMLImport& rImport, + css::uno::Any& rAny, + const OUString& rConfigItemName, + XMLConfigBaseContext* pBaseContext); + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override; + + virtual void SAL_CALL endFastElement(sal_Int32 nElement) override; +}; + +} + +static SvXMLImportContext *CreateSettingsContext(SvXMLImport& rImport, sal_Int32 nElement, + const uno::Reference<xml::sax::XFastAttributeList>& xAttrList, + beans::PropertyValue& rProp, XMLConfigBaseContext* pBaseContext) +{ + SvXMLImportContext *pContext = nullptr; + + rProp.Name.clear(); + for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList )) + { + if (aIter.getToken() == XML_ELEMENT(CONFIG, XML_NAME)) + rProp.Name = aIter.toString(); + } + + if (nElement == XML_ELEMENT(CONFIG, XML_CONFIG_ITEM)) + pContext = new XMLConfigItemContext(rImport, xAttrList, rProp.Value, rProp.Name, pBaseContext); + else if(nElement == XML_ELEMENT(CONFIG, XML_CONFIG_ITEM_SET) || + nElement == XML_ELEMENT(CONFIG, XML_CONFIG_ITEM_MAP_ENTRY) ) + pContext = new XMLConfigItemSetContext(rImport, rProp.Value, pBaseContext); + else if(nElement == XML_ELEMENT(CONFIG, XML_CONFIG_ITEM_MAP_NAMED)) + pContext = new XMLConfigItemMapNamedContext(rImport, rProp.Value, pBaseContext); + else if(nElement == XML_ELEMENT(CONFIG, XML_CONFIG_ITEM_MAP_INDEXED)) + pContext = new XMLConfigItemMapIndexedContext(rImport, rProp.Value, rProp.Name, pBaseContext); + + return pContext; +} + +XMLDocumentSettingsContext::XMLDocumentSettingsContext(SvXMLImport& rImport) + : SvXMLImportContext( rImport ) +{ + // here are no attributes +} + +XMLDocumentSettingsContext::~XMLDocumentSettingsContext() +{ +} + +css::uno::Reference< css::xml::sax::XFastContextHandler > XMLDocumentSettingsContext::createFastChildContext( + sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) +{ + SvXMLImportContext *pContext = nullptr; + OUString sName; + + for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList )) + { + if (aIter.getToken() == XML_ELEMENT(CONFIG, XML_NAME)) + sName = aIter.toString(); + } + + if (nElement == XML_ELEMENT(CONFIG, XML_CONFIG_ITEM_SET)) + { + OUString aLocalConfigName; + sal_uInt16 nConfigPrefix = + GetImport().GetNamespaceMap().GetKeyByAttrValueQName( + sName, &aLocalConfigName ); + + if( XML_NAMESPACE_OOO == nConfigPrefix ) + { + if (IsXMLToken(aLocalConfigName, XML_VIEW_SETTINGS)) + pContext = new XMLConfigItemSetContext(GetImport(), + maViewProps, nullptr); + else if (IsXMLToken(aLocalConfigName, + XML_CONFIGURATION_SETTINGS)) + pContext = new XMLConfigItemSetContext(GetImport(), + maConfigProps, nullptr); + else + { + maDocSpecificSettings.push_back( {aLocalConfigName, uno::Any()} ); + + pContext = new XMLConfigItemSetContext(GetImport(), + maDocSpecificSettings.back().aSettings, nullptr); + } + } + } + + return pContext; +} + +void XMLDocumentSettingsContext::endFastElement(sal_Int32 ) +{ + uno::Sequence<beans::PropertyValue> aSeqViewProps; + if (maViewProps >>= aSeqViewProps) + { + GetImport().SetViewSettings(aSeqViewProps); + sal_Int32 i(aSeqViewProps.getLength() - 1); + bool bFound(false); + while((i >= 0) && !bFound) + { + if (aSeqViewProps[i].Name == "Views") + { + bFound = true; + uno::Reference<container::XIndexAccess> xIndexAccess; + if (aSeqViewProps[i].Value >>= xIndexAccess) + { + uno::Reference<document::XViewDataSupplier> xViewDataSupplier(GetImport().GetModel(), uno::UNO_QUERY); + if (xViewDataSupplier.is()) + xViewDataSupplier->setViewData(xIndexAccess); + } + } + else + i--; + } + } + + uno::Sequence<beans::PropertyValue> aSeqConfigProps; + if ( maConfigProps >>= aSeqConfigProps ) + { + if (!utl::ConfigManager::IsFuzzing() && !officecfg::Office::Common::Save::Document::LoadPrinter::get()) + { + sal_Int32 i = aSeqConfigProps.getLength() - 1; + int nFound = 0; + + while ( ( i >= 0 ) && nFound < 2 ) + { + OUString sProp( aSeqConfigProps[i].Name ); + + if ( sProp == "PrinterName" ) + { + aSeqConfigProps[i].Value <<= OUString(); + nFound++; + } + else if ( sProp == "PrinterSetup" ) + { + uno::Sequence< sal_Int8 > aEmpty; + aSeqConfigProps[i].Value <<= aEmpty; + nFound++; + } + + i--; + } + } + + GetImport().SetConfigurationSettings( aSeqConfigProps ); + } + + for (auto const& settings : maDocSpecificSettings) + { + uno::Sequence< beans::PropertyValue > aDocSettings; + OSL_VERIFY( settings.aSettings >>= aDocSettings ); + GetImport().SetDocumentSpecificSettings( settings.sGroupName, aDocSettings ); + } +} + +XMLConfigBaseContext::XMLConfigBaseContext(SvXMLImport& rImport, + css::uno::Any& rTempAny, + XMLConfigBaseContext* pTempBaseContext) + : SvXMLImportContext( rImport ), + maProps( rImport.GetComponentContext() ), + maProp(), + mrAny(rTempAny), + mpBaseContext(pTempBaseContext) +{ +} + +XMLConfigItemSetContext::XMLConfigItemSetContext(SvXMLImport& rImport, + css::uno::Any& rAny, + XMLConfigBaseContext* pBaseContext) + : XMLConfigBaseContext( rImport, rAny, pBaseContext ) +{ + // here are no attributes +} + +css::uno::Reference< css::xml::sax::XFastContextHandler > XMLConfigItemSetContext::createFastChildContext( + sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) +{ + return CreateSettingsContext(GetImport(), nElement, xAttrList, maProp, this); +} + +void XMLConfigItemSetContext::endFastElement(sal_Int32 ) +{ + mrAny <<= maProps.GetSequence(); + if (mpBaseContext) + mpBaseContext->AddPropertyValue(); +} + +XMLConfigItemContext::XMLConfigItemContext(SvXMLImport& rImport, + const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList, + css::uno::Any& rTempAny, + const OUString& rTempItemName, + XMLConfigBaseContext* pTempBaseContext) + : SvXMLImportContext(rImport), + mrAny(rTempAny), + mrItemName(rTempItemName), + mpBaseContext(pTempBaseContext) +{ + for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList )) + { + if (aIter.getToken() == XML_ELEMENT(CONFIG, XML_TYPE)) + msType = aIter.toString(); + } +} + +void XMLConfigItemContext::characters( const OUString& rChars ) +{ + maCharBuffer.append(rChars); +} + +void XMLConfigItemContext::endFastElement(sal_Int32 ) +{ + OUString sValue; + uno::Sequence<sal_Int8> aDecoded; + if (IsXMLToken(msType, XML_BASE64BINARY)) + { + OUString sChars = maCharBuffer.makeStringAndClear().trim(); + if( !sChars.isEmpty() ) + ::comphelper::Base64::decodeSomeChars( aDecoded, sChars ); + } + else + sValue = maCharBuffer.makeStringAndClear(); + + if (mpBaseContext) + { + if (IsXMLToken(msType, XML_BOOLEAN)) + { + bool bValue(false); + if (IsXMLToken(sValue, XML_TRUE)) + bValue = true; + mrAny <<= bValue; + } + else if (IsXMLToken(msType, XML_BYTE)) + { + sal_Int32 nValue(0); + ::sax::Converter::convertNumber(nValue, sValue); + mrAny <<= static_cast<sal_Int8>(nValue); + } + else if (IsXMLToken(msType, XML_SHORT)) + { + sal_Int32 nValue(0); + ::sax::Converter::convertNumber(nValue, sValue); + mrAny <<= static_cast<sal_Int16>(nValue); + } + else if (IsXMLToken(msType, XML_INT)) + { + sal_Int32 nValue(0); + ::sax::Converter::convertNumber(nValue, sValue); + mrAny <<= nValue; + } + else if (IsXMLToken(msType, XML_LONG)) + { + sal_Int64 nValue(sValue.toInt64()); + mrAny <<= nValue; + } + else if (IsXMLToken(msType, XML_DOUBLE)) + { + double fValue(0.0); + ::sax::Converter::convertDouble(fValue, sValue); + mrAny <<= fValue; + } + else if (IsXMLToken(msType, XML_STRING)) + { + mrAny <<= sValue; + } + else if (IsXMLToken(msType, XML_DATETIME)) + { + util::DateTime aDateTime; + ::sax::Converter::parseDateTime(aDateTime, sValue); + mrAny <<= aDateTime; + } + else if (IsXMLToken(msType, XML_BASE64BINARY)) + { + mrAny <<= aDecoded; + } + else { + SAL_INFO("xmloff.core", + "XMLConfigItemContext: unknown type: " << msType); + } + + ManipulateConfigItem(); + + mpBaseContext->AddPropertyValue(); + } + else { + assert(false && "no BaseContext"); + } +} + +/** There are some instances where there is a mismatch between API and + * XML mapping of a setting. In this case, this method allows us to + * manipulate the values accordingly. */ +void XMLConfigItemContext::ManipulateConfigItem() +{ + if( mrItemName == "PrinterIndependentLayout" ) + { + OUString sValue; + mrAny >>= sValue; + + sal_Int16 nTmp = document::PrinterIndependentLayout::HIGH_RESOLUTION; + + if( sValue == "enabled" || sValue == "low-resolution" ) + { + nTmp = document::PrinterIndependentLayout::LOW_RESOLUTION; + } + else if ( sValue == "disabled" ) + { + nTmp = document::PrinterIndependentLayout::DISABLED; + } + // else: default to high_resolution + + mrAny <<= nTmp; + } + else if( (mrItemName == "ColorTableURL") || (mrItemName == "LineEndTableURL") || (mrItemName == "HatchTableURL") + || (mrItemName == "DashTableURL") || (mrItemName == "GradientTableURL") || (mrItemName == "BitmapTableURL") ) + { + try + { + uno::Reference< uno::XComponentContext > xContext( GetImport().GetComponentContext() ); + uno::Reference< util::XStringSubstitution > xStringSubsitution( util::PathSubstitution::create(xContext) ); + + OUString aURL; + mrAny >>= aURL; + aURL = xStringSubsitution->substituteVariables( aURL, false ); + mrAny <<= aURL; + } + catch( uno::Exception& ) + { + } + } +} + +XMLConfigItemMapNamedContext::XMLConfigItemMapNamedContext(SvXMLImport& rImport, + css::uno::Any& rAny, + XMLConfigBaseContext* pBaseContext) + : XMLConfigBaseContext(rImport, rAny, pBaseContext) +{ +} + +css::uno::Reference< css::xml::sax::XFastContextHandler > XMLConfigItemMapNamedContext::createFastChildContext( + sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) +{ + return CreateSettingsContext(GetImport(), nElement, xAttrList, maProp, this); +} + +void XMLConfigItemMapNamedContext::endFastElement(sal_Int32 ) +{ + if (mpBaseContext) + { + mrAny <<= maProps.GetNameContainer(); + mpBaseContext->AddPropertyValue(); + } + else { + assert(false && "no BaseContext"); + } +} + +XMLConfigItemMapIndexedContext::XMLConfigItemMapIndexedContext(SvXMLImport& rImport, + css::uno::Any& rAny, + const OUString& rConfigItemName, + XMLConfigBaseContext* pBaseContext) + : XMLConfigBaseContext(rImport, rAny, pBaseContext), + maConfigItemName( rConfigItemName ) +{ +} + +css::uno::Reference< css::xml::sax::XFastContextHandler > XMLConfigItemMapIndexedContext::createFastChildContext( + sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) +{ + return CreateSettingsContext(GetImport(), nElement, xAttrList, maProp, this); +} + +void XMLConfigItemMapIndexedContext::endFastElement(sal_Int32 ) +{ + if (mpBaseContext) + { + if ( maConfigItemName == "ForbiddenCharacters" ) + { + uno::Reference< i18n::XForbiddenCharacters > xForbChars; + + // get the forbidden characters from the document + uno::Reference< lang::XMultiServiceFactory > xFac( GetImport().GetModel(), uno::UNO_QUERY ); + if( xFac.is() ) + { + uno::Reference< beans::XPropertySet > xProps( xFac->createInstance( "com.sun.star.document.Settings" ), uno::UNO_QUERY ); + if( xProps.is() && xProps->getPropertySetInfo()->hasPropertyByName( maConfigItemName ) ) + { + xProps->getPropertyValue( maConfigItemName ) >>= xForbChars; + } + } + + if( xForbChars.is() ) + { + + uno::Reference< container::XIndexAccess > xIndex = maProps.GetIndexContainer(); + + const sal_Int32 nCount = xIndex->getCount(); + uno::Sequence < beans::PropertyValue > aProps; + for (sal_Int32 i = 0; i < nCount; i++) + { + if ((xIndex->getByIndex( i ) >>= aProps) && (aProps.getLength() == XML_FORBIDDEN_CHARACTER_MAX ) ) + { + /* FIXME-BCP47: this stupid and counterpart in + * xmloff/source/core/SettingsExportHelper.cxx + * XMLSettingsExportHelper::exportForbiddenCharacters() + * */ + + beans::PropertyValue *pForChar = aProps.getArray(); + i18n::ForbiddenCharacters aForbid; + lang::Locale aLocale; + bool bHaveLanguage = false, bHaveCountry = false, bHaveVariant = false, + bHaveBegin = false, bHaveEnd = false; + + for ( sal_Int32 j = 0 ; j < XML_FORBIDDEN_CHARACTER_MAX ; j++ ) + { + if (pForChar->Name == "Language") + { + pForChar->Value >>= aLocale.Language; + bHaveLanguage = true; + } + else if (pForChar->Name == "Country") + { + pForChar->Value >>= aLocale.Country; + bHaveCountry = true; + } + else if (pForChar->Name == "Variant") + { + pForChar->Value >>= aLocale.Variant; + bHaveVariant = true; + } + else if (pForChar->Name == "BeginLine") + { + pForChar->Value >>= aForbid.beginLine; + bHaveBegin = true; + } + else if (pForChar->Name == "EndLine") + { + pForChar->Value >>= aForbid.endLine; + bHaveEnd = true; + } + pForChar++; + } + + if ( bHaveLanguage && bHaveCountry && bHaveVariant && bHaveBegin && bHaveEnd ) + { + try + { + xForbChars->setForbiddenCharacters( aLocale, aForbid ); + } + catch (uno::Exception const&) + { + TOOLS_WARN_EXCEPTION("xmloff.core", + "Exception while importing forbidden characters"); + } + } + } + } + } + else + { + SAL_WARN("xmloff.core", "could not get the XForbiddenCharacters from document!"); + mrAny <<= maProps.GetIndexContainer(); + } + } + else if ( maConfigItemName == "Symbols" ) + { + uno::Reference< container::XIndexAccess > xIndex = maProps.GetIndexContainer(); + + const sal_Int32 nCount = xIndex->getCount(); + uno::Sequence < beans::PropertyValue > aProps; + uno::Sequence < formula::SymbolDescriptor > aSymbolList ( nCount ); + + formula::SymbolDescriptor *pDescriptor = aSymbolList.getArray(); + + sal_Int16 nNumFullEntries = 0; + + for ( sal_Int32 i = 0; i < nCount; i++ ) + { + if ((xIndex->getByIndex( i ) >>= aProps) && (aProps.getLength() == XML_SYMBOL_DESCRIPTOR_MAX ) ) + { + bool bHaveName = false, bHaveExportName = false, bHaveCharSet = false, + bHaveFontName = false, bHaveFamily = false, bHavePitch = false, + bHaveWeight = false, bHaveItalic = false, bHaveSymbolSet = false, + bHaveCharacter = false; + beans::PropertyValue *pSymbol = aProps.getArray(); + + for ( sal_Int32 j = 0 ; j < XML_SYMBOL_DESCRIPTOR_MAX ; j++ ) + { + if (pSymbol->Name == "Name") + { + pSymbol->Value >>= pDescriptor[nNumFullEntries].sName; + bHaveName = true; + } + else if (pSymbol->Name == "ExportName") + { + pSymbol->Value >>= pDescriptor[nNumFullEntries].sExportName; + bHaveExportName = true; + } + else if (pSymbol->Name == "FontName") + { + pSymbol->Value >>= pDescriptor[nNumFullEntries].sFontName; + bHaveFontName = true; + } + else if (pSymbol->Name == "CharSet") + { + pSymbol->Value >>= pDescriptor[nNumFullEntries].nCharSet; + bHaveCharSet = true; + } + else if (pSymbol->Name == "Family") + { + pSymbol->Value >>= pDescriptor[nNumFullEntries].nFamily; + bHaveFamily = true; + } + else if (pSymbol->Name == "Pitch") + { + pSymbol->Value >>= pDescriptor[nNumFullEntries].nPitch; + bHavePitch = true; + } + else if (pSymbol->Name == "Weight") + { + pSymbol->Value >>= pDescriptor[nNumFullEntries].nWeight; + bHaveWeight = true; + } + else if (pSymbol->Name == "Italic") + { + pSymbol->Value >>= pDescriptor[nNumFullEntries].nItalic; + bHaveItalic = true; + } + else if (pSymbol->Name == "SymbolSet") + { + pSymbol->Value >>= pDescriptor[nNumFullEntries].sSymbolSet; + bHaveSymbolSet = true; + } + else if (pSymbol->Name == "Character") + { + pSymbol->Value >>= pDescriptor[nNumFullEntries].nCharacter; + bHaveCharacter = true; + } + pSymbol++; + } + if ( bHaveName && bHaveExportName && bHaveCharSet && bHaveFontName && bHaveCharacter + && bHaveFamily && bHavePitch && bHaveWeight && bHaveItalic && bHaveSymbolSet) + nNumFullEntries++; + } + } + aSymbolList.realloc (nNumFullEntries); + mrAny <<= aSymbolList; + } + else + { + mrAny <<= maProps.GetIndexContainer(); + } + mpBaseContext->AddPropertyValue(); + } + else { + assert(false && "no BaseContext"); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/DomBuilderContext.cxx b/xmloff/source/core/DomBuilderContext.cxx new file mode 100644 index 000000000..9f893d710 --- /dev/null +++ b/xmloff/source/core/DomBuilderContext.cxx @@ -0,0 +1,239 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <DomBuilderContext.hxx> + +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmlimp.hxx> +#include <xmloff/xmlerror.hxx> + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/xml/dom/DocumentBuilder.hpp> +#include <com/sun/star/xml/dom/XNode.hpp> +#include <com/sun/star/xml/dom/XElement.hpp> +#include <com/sun/star/xml/sax/XAttributeList.hpp> +#include <com/sun/star/xml/dom/NodeType.hpp> + +#include <rtl/ustring.hxx> +#include <sal/log.hxx> + +#include <comphelper/processfactory.hxx> + + +using com::sun::star::uno::XComponentContext; +using com::sun::star::uno::Reference; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::UNO_QUERY_THROW; +using com::sun::star::xml::dom::DocumentBuilder; +using com::sun::star::xml::dom::XDocument; +using com::sun::star::xml::dom::XDocumentBuilder; +using com::sun::star::xml::dom::XNode; +using com::sun::star::xml::dom::XElement; +using com::sun::star::xml::sax::XAttributeList; +using com::sun::star::xml::dom::NodeType_ELEMENT_NODE; + + +// helper functions; implemented below +static Reference<XNode> lcl_createDomInstance(); +static Reference<XNode> lcl_createElement( SvXMLImport& rImport, + sal_uInt16 nPrefix, + const OUString& rLocalName, + const Reference<XNode>& xParent); + + +DomBuilderContext::DomBuilderContext( SvXMLImport& rImport, + sal_uInt16 nPrefix, + const OUString& rLocalName ) : + SvXMLImportContext( rImport, nPrefix, rLocalName ), + mxNode( lcl_createElement( rImport, nPrefix, rLocalName, + lcl_createDomInstance() ) ) +{ + SAL_WARN_IF( !mxNode.is(), "xmloff", "empty XNode not allowed" ); + SAL_WARN_IF( !Reference<XElement>( mxNode, UNO_QUERY ).is(), "xmloff", "need element" ); + SAL_WARN_IF( mxNode->getNodeType() != NodeType_ELEMENT_NODE, "xmloff", "need element" ); +} + +DomBuilderContext::DomBuilderContext( SvXMLImport& rImport, + sal_uInt16 nPrefix, + const OUString& rLocalName, + Reference<XNode> const & xParent ) : + SvXMLImportContext( rImport, nPrefix, rLocalName ), + mxNode( lcl_createElement( rImport, nPrefix, rLocalName, xParent ) ) +{ + SAL_WARN_IF( !mxNode.is(), "xmloff", "empty XNode not allowed" ); + SAL_WARN_IF( !Reference<XElement>( mxNode, UNO_QUERY ).is(), "xmloff", "need element" ); + SAL_WARN_IF( mxNode->getNodeType() != NodeType_ELEMENT_NODE, "xmloff", "need element" ); +} + +DomBuilderContext::~DomBuilderContext() +{ +} + +Reference<XDocument> DomBuilderContext::getTree() +{ + SAL_WARN_IF( !mxNode.is(), "xmloff", "empty XNode not allowed" ); + return mxNode->getOwnerDocument(); +} + +SvXMLImportContextRef DomBuilderContext::CreateChildContext( + sal_uInt16 nPrefix, + const OUString& rLocalName, + const Reference<XAttributeList>& ) +{ + // create DomBuilder for subtree + return new DomBuilderContext( GetImport(), nPrefix, rLocalName, mxNode ); +} + + +void DomBuilderContext::StartElement( + const Reference<XAttributeList>& xAttrList ) +{ + SAL_WARN_IF( !mxNode.is(), "xmloff", "empty XNode not allowed" ); + SAL_WARN_IF( !mxNode->getOwnerDocument().is(), "xmloff", "XNode must have XDocument" ); + + // add attribute nodes to new node + sal_Int16 nAttributeCount = xAttrList->getLength(); + for( sal_Int16 i = 0; i < nAttributeCount; i++ ) + { + // get name & value for attribute + const OUString& rName = xAttrList->getNameByIndex( i ); + const OUString& rValue = xAttrList->getValueByIndex( i ); + + // namespace handling: determine namespace & namespace key + OUString sNamespace; + sal_uInt16 nNamespaceKey = + GetImport().GetNamespaceMap().GetKeyByAttrName( + rName, nullptr, nullptr, &sNamespace); + + // create attribute node and set value + Reference<XElement> xElement( mxNode, UNO_QUERY_THROW ); + switch( nNamespaceKey ) + { + case XML_NAMESPACE_NONE: + // no namespace: create a non-namespaced attribute + xElement->setAttribute( rName, rValue ); + break; + case XML_NAMESPACE_XMLNS: + // namespace declaration: ignore, since the DOM tree handles these + // declarations implicitly + break; + case XML_NAMESPACE_UNKNOWN: + // unknown namespace: illegal input. Raise Warning. + { + Sequence<OUString> aSeq(2); + aSeq[0] = rName; + aSeq[1] = rValue; + GetImport().SetError( + XMLERROR_FLAG_WARNING | XMLERROR_NAMESPACE_TROUBLE, aSeq ); + } + break; + default: + // a real and proper namespace: create namespaced attribute + xElement->setAttributeNS( sNamespace, rName, rValue ); + break; + } + } +} + +void DomBuilderContext::EndElement() +{ + // nothing to be done! +} + +void DomBuilderContext::Characters( const OUString& rCharacters ) +{ + SAL_WARN_IF( !mxNode.is(), "xmloff", "empty XNode not allowed" ); + + // TODO: I assume adjacent text nodes should be joined, to preserve + // processing model? (I.e., if the SAX parser breaks a string into 2 + // Characters(..) calls, the DOM model would still see only one child.) + + // create text node and append to parent + Reference<XNode> xNew( + mxNode->getOwnerDocument()->createTextNode( rCharacters ), + UNO_QUERY_THROW ); + mxNode->appendChild( xNew ); +} + + +// helper function implementations + + +static Reference<XNode> lcl_createDomInstance() +{ + Reference<XComponentContext> xContext = comphelper::getProcessComponentContext(); + SAL_WARN_IF( !xContext.is(), "xmloff", "can't get service factory" ); + + Reference<XDocumentBuilder> xBuilder( DocumentBuilder::create(xContext) ); + + return Reference<XNode>( xBuilder->newDocument(), UNO_QUERY_THROW ); +} + +static Reference<XNode> lcl_createElement( SvXMLImport& rImport, + sal_uInt16 nPrefix, + const OUString& rLocalName, + const Reference<XNode>& xParent) +{ + SAL_WARN_IF( !xParent.is(), "xmloff", "need parent node" ); + + Reference<XDocument> xDocument = xParent->getOwnerDocument(); + SAL_WARN_IF( !xDocument.is(), "xmloff", "no XDocument found!" ); + + // TODO: come up with proper way of handling namespaces; re-creating the + // namespace from the key is NOT a good idea, and will not work for + // multiple prefixes for the same namespace. Fortunately, those are rare. + + Reference<XElement> xElement; + switch( nPrefix ) + { + case XML_NAMESPACE_NONE: + // no namespace: use local name + xElement = xDocument->createElement( rLocalName ); + break; + case XML_NAMESPACE_XMLNS: + case XML_NAMESPACE_UNKNOWN: + // both cases are illegal; raise warning (and use only local name) + xElement = xDocument->createElement( rLocalName ); + { + Sequence<OUString> aSeq { rLocalName }; + rImport.SetError( + XMLERROR_FLAG_WARNING | XMLERROR_NAMESPACE_TROUBLE, aSeq ); + } + break; + default: + // We are only given the prefix and the local name; thus we have to ask + // the namespace map to create a qualified name for us. Technically, + // this is a bug, since this will fail for multiple prefixes used for + // the same namespace. + xElement = xDocument->createElementNS( + rImport.GetNamespaceMap().GetNameByKey( nPrefix ), + rImport.GetNamespaceMap().GetQNameByKey( nPrefix, rLocalName ) ); + break; + } + SAL_WARN_IF( !xElement.is(), "xmloff", "can't create element" ); + + // add new element to parent and return + xParent->appendChild( xElement ); + return xElement; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/DomExport.cxx b/xmloff/source/core/DomExport.cxx new file mode 100644 index 000000000..1a16a155a --- /dev/null +++ b/xmloff/source/core/DomExport.cxx @@ -0,0 +1,249 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <DomExport.hxx> + +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmlexp.hxx> +#include <xmloff/xmlerror.hxx> + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/xml/dom/XAttr.hpp> +#include <com/sun/star/xml/dom/XNode.hpp> +#include <com/sun/star/xml/dom/XElement.hpp> +#include <com/sun/star/xml/dom/NodeType.hpp> +#include <com/sun/star/xml/dom/XNamedNodeMap.hpp> + +#include <rtl/ustring.hxx> +#include <rtl/ustrbuf.hxx> +#include <sal/log.hxx> +#include <osl/diagnose.h> + + +#include <vector> + + +using com::sun::star::uno::Reference; +using com::sun::star::uno::UNO_QUERY_THROW; +using std::vector; + +using namespace com::sun::star::xml::dom; + +namespace { + +class DomVisitor +{ +public: + DomVisitor() {} + virtual ~DomVisitor() {} + virtual void element( const Reference<XElement>& ) {} + virtual void character( const Reference<XCharacterData>& ) {} + virtual void endElement( const Reference<XElement>& ) {} +}; + +} + +static void visit( DomVisitor&, const Reference<XDocument>& ); +static void visit( DomVisitor&, const Reference<XNode>& ); + + +static void visitNode( DomVisitor& rVisitor, const Reference<XNode>& xNode ) +{ + switch( xNode->getNodeType() ) + { + case NodeType_ATTRIBUTE_NODE: + break; + case NodeType_CDATA_SECTION_NODE: + break; + case NodeType_COMMENT_NODE: + break; + case NodeType_DOCUMENT_FRAGMENT_NODE: + break; + case NodeType_DOCUMENT_NODE: + break; + case NodeType_DOCUMENT_TYPE_NODE: + break; + case NodeType_ELEMENT_NODE: + rVisitor.element( Reference<XElement>( xNode, UNO_QUERY_THROW ) ); + break; + case NodeType_ENTITY_NODE: + break; + case NodeType_ENTITY_REFERENCE_NODE: + break; + case NodeType_NOTATION_NODE: + break; + case NodeType_PROCESSING_INSTRUCTION_NODE: + break; + case NodeType_TEXT_NODE: + rVisitor.character( Reference<XCharacterData>( xNode, UNO_QUERY_THROW ) ); + break; + default: + OSL_FAIL( "unknown DOM node type" ); + break; + } +} + +void visit( DomVisitor& rVisitor, const Reference<XDocument>& xDocument ) +{ + visit( rVisitor, Reference<XNode>( xDocument, UNO_QUERY_THROW ) ); +} + +void visit( DomVisitor& rVisitor, const Reference<XNode>& xNode ) +{ + visitNode( rVisitor, xNode ); + for( Reference<XNode> xChild = xNode->getFirstChild(); + xChild.is(); + xChild = xChild->getNextSibling() ) + { + visit( rVisitor, xChild ); + } + if( xNode->getNodeType() == NodeType_ELEMENT_NODE ) + rVisitor.endElement( Reference<XElement>( xNode, UNO_QUERY_THROW ) ); +} + +namespace { + +class DomExport: public DomVisitor +{ + SvXMLExport& mrExport; + vector<SvXMLNamespaceMap> maNamespaces; + + void pushNamespace(); + void addNamespace( const OUString& sPrefix, const OUString& sURI ); + OUString qualifiedName( const OUString& sPrefix, const OUString& sURI, + const OUString& sLocalName ); + OUString qualifiedName( const Reference<XElement>& ); + OUString qualifiedName( const Reference<XAttr>& ); + void addAttribute( const Reference<XAttr>& ); + +public: + + explicit DomExport( SvXMLExport& rExport ); + virtual ~DomExport() override; + + virtual void element( const Reference<XElement>& ) override; + virtual void endElement( const Reference<XElement>& ) override; + virtual void character( const Reference<XCharacterData>& ) override; +}; + +} + +DomExport::DomExport( SvXMLExport& rExport ) : + mrExport( rExport ) +{ + maNamespaces.push_back( rExport.GetNamespaceMap() ); +} + +DomExport::~DomExport() +{ + SAL_WARN_IF( maNamespaces.size() != 1, "xmloff", "namespace missing" ); + maNamespaces.clear(); +} + +void DomExport::pushNamespace() +{ + SvXMLNamespaceMap const aMap(maNamespaces.back()); + maNamespaces.push_back(aMap); +} + +void DomExport::addNamespace( const OUString& sPrefix, const OUString& sURI ) +{ + SvXMLNamespaceMap& rMap = maNamespaces.back(); + sal_uInt16 nKey = rMap.GetKeyByPrefix( sPrefix ); + + // we need to register the namespace, if either the prefix isn't known or + // is used for a different namespace + if( nKey == XML_NAMESPACE_UNKNOWN || + rMap.GetNameByKey( nKey ) != sURI ) + { + // add prefix to map, and add declaration + rMap.Add( sPrefix, sURI ); + mrExport.AddAttribute( "xmlns:" + sPrefix, sURI ); + } +} + +OUString DomExport::qualifiedName( const OUString& sPrefix, + const OUString& sURI, + const OUString& sLocalName ) +{ + OUStringBuffer sBuffer; + if( !sPrefix.isEmpty() && !sURI.isEmpty() ) + { + addNamespace( sPrefix, sURI ); + sBuffer.append( sPrefix ); + sBuffer.append( ':' ); + } + sBuffer.append( sLocalName ); + return sBuffer.makeStringAndClear(); +} + +OUString DomExport::qualifiedName( const Reference<XElement>& xElement ) +{ + return qualifiedName( xElement->getPrefix(), xElement->getNamespaceURI(), + xElement->getNodeName() ); +} + +OUString DomExport::qualifiedName( const Reference<XAttr>& xAttr ) +{ + return qualifiedName( xAttr->getPrefix(), xAttr->getNamespaceURI(), + xAttr->getNodeName() ); +} + +void DomExport::addAttribute( const Reference<XAttr>& xAttribute ) +{ + mrExport.AddAttribute( qualifiedName( xAttribute ), + xAttribute->getNodeValue() ); +} + +void DomExport::element( const Reference<XElement>& xElement ) +{ + pushNamespace(); + + // write attributes + Reference<XNamedNodeMap> xAttributes = xElement->getAttributes(); + sal_Int32 nLength = xAttributes.is() ? xAttributes->getLength() : 0; + for( sal_Int32 n = 0; n < nLength; n++ ) + { + addAttribute( Reference<XAttr>( xAttributes->item( n ), UNO_QUERY_THROW ) ); + } + + // write name + mrExport.StartElement( qualifiedName( xElement ), false ); +} + +void DomExport::endElement( const Reference<XElement>& xElement ) +{ + mrExport.EndElement( qualifiedName( xElement ), false ); + maNamespaces.pop_back(); +} + +void DomExport::character( const Reference<XCharacterData>& xChars ) +{ + mrExport.Characters( xChars->getNodeValue() ); +} + + +void exportDom( SvXMLExport& rExport, const Reference<XDocument>& xDocument ) +{ + DomExport aDomExport( rExport ); + visit( aDomExport, xDocument ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/ProgressBarHelper.cxx b/xmloff/source/core/ProgressBarHelper.cxx new file mode 100644 index 000000000..5c34cfadb --- /dev/null +++ b/xmloff/source/core/ProgressBarHelper.cxx @@ -0,0 +1,107 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <xmloff/ProgressBarHelper.hxx> + +#include <osl/diagnose.h> + +using namespace ::com::sun::star; + +static const sal_Int32 nDefaultProgressBarRange = 1000000; +static const float fProgressStep = 0.5; + +ProgressBarHelper::ProgressBarHelper(const css::uno::Reference < css::task::XStatusIndicator>& xTempStatusIndicator, + const bool bTempStrict) +: xStatusIndicator(xTempStatusIndicator) +, nRange(nDefaultProgressBarRange) +, nReference(100) +, nValue(0) +, fOldPercent(0.0) +, bStrict(bTempStrict) +, bRepeat(true) +#ifdef DBG_UTIL +, bFailure(false) +#endif +{ +} + +ProgressBarHelper::~ProgressBarHelper() +{ +} + +void ProgressBarHelper::ChangeReference(sal_Int32 nNewReference) +{ + if((nNewReference > 0) && (nNewReference != nReference)) + { + if (nReference) + { + double fPercent(static_cast<double>(nNewReference) / nReference); + double fValue(nValue * fPercent); + nValue = static_cast<sal_Int32>(fValue); + nReference = nNewReference; + } + else + { + nReference = nNewReference; + nValue = 0; + } + } +} + +void ProgressBarHelper::SetValue(sal_Int32 nTempValue) +{ + if (xStatusIndicator.is() && (nReference > 0)) + { + if ((nTempValue >= nValue) && (!bStrict || (nTempValue <= nReference))) + { + // #91317# no progress bar with values > 100% + if (nTempValue > nReference) + { + if (!bRepeat) + nValue = nReference; + else + { + xStatusIndicator->reset(); + nValue = 0; + } + } + else + nValue = nTempValue; + + double fValue(nValue); + double fNewValue ((fValue * nRange) / nReference); + + double fPercent((fNewValue * 100) / nRange); + if (fPercent >= (fOldPercent + fProgressStep) || fPercent < fOldPercent) + { + xStatusIndicator->setValue(static_cast<sal_Int32>(fNewValue)); + fOldPercent = fPercent; + } + } +#ifdef DBG_UTIL + else if (!bFailure) + { + OSL_FAIL("tried to set a wrong value on the progressbar"); + bFailure = true; + } +#endif + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/PropertySetMerger.cxx b/xmloff/source/core/PropertySetMerger.cxx new file mode 100644 index 000000000..812201024 --- /dev/null +++ b/xmloff/source/core/PropertySetMerger.cxx @@ -0,0 +1,231 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <com/sun/star/beans/XPropertyState.hpp> +#include <PropertySetMerger.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; + +#include <comphelper/sequence.hxx> +#include <cppuhelper/implbase3.hxx> + +namespace { + +class PropertySetMergerImpl : public ::cppu::WeakAggImplHelper3< XPropertySet, XPropertyState, XPropertySetInfo > +{ +private: + Reference< XPropertySet > mxPropSet1; + Reference< XPropertyState > mxPropSet1State; + Reference< XPropertySetInfo > mxPropSet1Info; + + Reference< XPropertySet > mxPropSet2; + Reference< XPropertyState > mxPropSet2State; + Reference< XPropertySetInfo > mxPropSet2Info; + +public: + PropertySetMergerImpl( const Reference< XPropertySet > & rPropSet1, const Reference< XPropertySet > & rPropSet2 ); + + // XPropertySet + virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override; + virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const Any& aValue ) override; + virtual Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override; + virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener ) override; + virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& aListener ) override; + virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) override; + virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) override; + + // XPropertyState + virtual PropertyState SAL_CALL getPropertyState( const OUString& PropertyName ) override; + virtual Sequence< PropertyState > SAL_CALL getPropertyStates( const Sequence< OUString >& aPropertyName ) override; + virtual void SAL_CALL setPropertyToDefault( const OUString& PropertyName ) override; + virtual Any SAL_CALL getPropertyDefault( const OUString& aPropertyName ) override; + + // XPropertySetInfo + virtual Sequence< Property > SAL_CALL getProperties( ) override; + virtual Property SAL_CALL getPropertyByName( const OUString& aName ) override; + virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) override; +}; + +} + +// Interface implementation + +PropertySetMergerImpl::PropertySetMergerImpl( Reference< XPropertySet > const & rPropSet1, Reference< XPropertySet > const & rPropSet2 ) +: mxPropSet1( rPropSet1 ) +, mxPropSet1State( rPropSet1, UNO_QUERY ) +, mxPropSet1Info( rPropSet1->getPropertySetInfo() ) +, mxPropSet2( rPropSet2 ) +, mxPropSet2State( rPropSet2, UNO_QUERY ) +, mxPropSet2Info( rPropSet2->getPropertySetInfo() ) +{ +} + +// XPropertySet +Reference< XPropertySetInfo > SAL_CALL PropertySetMergerImpl::getPropertySetInfo( ) +{ + return this; +} + +void SAL_CALL PropertySetMergerImpl::setPropertyValue( const OUString& aPropertyName, const Any& aValue ) +{ + if( mxPropSet1Info->hasPropertyByName( aPropertyName ) ) + { + mxPropSet1->setPropertyValue( aPropertyName, aValue ); + } + else + { + mxPropSet2->setPropertyValue( aPropertyName, aValue ); + } +} + +Any SAL_CALL PropertySetMergerImpl::getPropertyValue( const OUString& PropertyName ) +{ + if( mxPropSet1Info->hasPropertyByName( PropertyName ) ) + { + return mxPropSet1->getPropertyValue( PropertyName ); + } + else + { + return mxPropSet2->getPropertyValue( PropertyName ); + } +} + +void SAL_CALL PropertySetMergerImpl::addPropertyChangeListener( const OUString& /*aPropertyName*/, const Reference< XPropertyChangeListener >& /*xListener*/ ) +{ +} + +void SAL_CALL PropertySetMergerImpl::removePropertyChangeListener( const OUString& /*aPropertyName*/, const Reference< XPropertyChangeListener >& /*aListener*/ ) +{ +} + +void SAL_CALL PropertySetMergerImpl::addVetoableChangeListener( const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener >& /*aListener*/ ) +{ +} + +void SAL_CALL PropertySetMergerImpl::removeVetoableChangeListener( const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener >& /*aListener*/ ) +{ +} + +// XPropertyState +PropertyState SAL_CALL PropertySetMergerImpl::getPropertyState( const OUString& PropertyName ) +{ + if( mxPropSet1Info->hasPropertyByName( PropertyName ) ) + { + if( mxPropSet1State.is() ) + { + return mxPropSet1State->getPropertyState( PropertyName ); + } + else + { + return PropertyState_DIRECT_VALUE; + } + } + else + { + if( mxPropSet2State.is() ) + { + return mxPropSet2State->getPropertyState( PropertyName ); + } + else + { + return PropertyState_DIRECT_VALUE; + } + } +} + +Sequence< PropertyState > SAL_CALL PropertySetMergerImpl::getPropertyStates( const Sequence< OUString >& aPropertyName ) +{ + const sal_Int32 nCount = aPropertyName.getLength(); + Sequence< PropertyState > aPropStates( nCount ); + + std::transform(aPropertyName.begin(), aPropertyName.end(), aPropStates.begin(), + [this](const OUString& rPropName) -> PropertyState { return getPropertyState(rPropName); }); + + return aPropStates; +} + +void SAL_CALL PropertySetMergerImpl::setPropertyToDefault( const OUString& PropertyName ) +{ + if( mxPropSet1State.is() && mxPropSet1Info->hasPropertyByName( PropertyName ) ) + { + mxPropSet1State->setPropertyToDefault( PropertyName ); + } + else + { + if( mxPropSet2State.is() ) + { + mxPropSet2State->setPropertyToDefault( PropertyName ); + } + } +} + +Any SAL_CALL PropertySetMergerImpl::getPropertyDefault( const OUString& aPropertyName ) +{ + if( mxPropSet1State.is() && mxPropSet1Info->hasPropertyByName( aPropertyName ) ) + { + return mxPropSet1State->getPropertyDefault( aPropertyName ); + } + else + { + if( mxPropSet2State.is() ) + { + return mxPropSet2State->getPropertyDefault( aPropertyName ); + } + else + { + Any aAny; + return aAny; + } + } +} + +// XPropertySetInfo +Sequence< Property > SAL_CALL PropertySetMergerImpl::getProperties() +{ + Sequence< Property > aProps1( mxPropSet1Info->getProperties() ); + Sequence< Property > aProps2( mxPropSet2Info->getProperties() ); + + return comphelper::concatSequences(aProps1, aProps2); +} + +Property SAL_CALL PropertySetMergerImpl::getPropertyByName( const OUString& aName ) +{ + if( mxPropSet1Info->hasPropertyByName( aName ) ) + return mxPropSet1Info->getPropertyByName( aName ); + + return mxPropSet2Info->getPropertyByName( aName ); +} + +sal_Bool SAL_CALL PropertySetMergerImpl::hasPropertyByName( const OUString& Name ) +{ + if(mxPropSet1Info->hasPropertyByName( Name ) ) + return true; + + return mxPropSet2Info->hasPropertyByName( Name ); +} + +Reference< XPropertySet > PropertySetMerger_CreateInstance( const Reference< XPropertySet >& rPropSet1, const Reference< XPropertySet >& rPropSet2 ) throw() +{ + return new PropertySetMergerImpl( rPropSet1, rPropSet2 ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/RDFaExportHelper.cxx b/xmloff/source/core/RDFaExportHelper.cxx new file mode 100644 index 000000000..5b9e3b965 --- /dev/null +++ b/xmloff/source/core/RDFaExportHelper.cxx @@ -0,0 +1,180 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <RDFaExportHelper.hxx> + +#include <xmloff/xmlnmspe.hxx> + +#include <xmloff/xmlexp.hxx> +#include <xmloff/xmltoken.hxx> + +#include <comphelper/stl_types.hxx> +#include <comphelper/processfactory.hxx> + +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/uri/XUriReference.hpp> +#include <com/sun/star/uri/UriReferenceFactory.hpp> +#include <com/sun/star/rdf/Statement.hpp> +#include <com/sun/star/rdf/XLiteral.hpp> +#include <com/sun/star/rdf/XRepositorySupplier.hpp> +#include <com/sun/star/rdf/XDocumentRepository.hpp> + +#include <rtl/ustrbuf.hxx> +#include <osl/diagnose.h> + +#include <algorithm> + +using namespace ::com::sun::star; + +namespace xmloff { + +static OUString +makeCURIE(SvXMLExport * i_pExport, + uno::Reference<rdf::XURI> const & i_xURI) +{ + OSL_ENSURE(i_xURI.is(), "makeCURIE: null URI"); + if (!i_xURI.is()) throw uno::RuntimeException(); + + const OUString Namespace( i_xURI->getNamespace() ); + OSL_ENSURE(!Namespace.isEmpty(), "makeCURIE: no namespace"); + if (Namespace.isEmpty()) throw uno::RuntimeException(); + + // N.B.: empty LocalName is valid! + return i_pExport->EnsureNamespace(Namespace) + ":" + i_xURI->getLocalName(); +} + +// #i112473# SvXMLExport::GetRelativeReference() not right for RDF on SaveAs +// because the URIs in the repository are not rewritten on SaveAs, the +// URI of the loaded document has to be used, not the URI of the target doc. +static OUString +getRelativeReference(SvXMLExport const& rExport, OUString const& rURI) +{ + uno::Reference< rdf::XURI > const xModelURI( + rExport.GetModel(), uno::UNO_QUERY_THROW ); + OUString const baseURI( xModelURI->getStringValue() ); + + uno::Reference<uno::XComponentContext> xContext( comphelper::getProcessComponentContext() ); + uno::Reference<uri::XUriReferenceFactory> const xUriFactory = + uri::UriReferenceFactory::create( xContext ); + + uno::Reference< uri::XUriReference > const xBaseURI( + xUriFactory->parse(baseURI), uno::UNO_SET_THROW ); + uno::Reference< uri::XUriReference > const xAbsoluteURI( + xUriFactory->parse(rURI), uno::UNO_SET_THROW ); + uno::Reference< uri::XUriReference > const xRelativeURI( + xUriFactory->makeRelative(xBaseURI, xAbsoluteURI, true, true, false), + uno::UNO_SET_THROW ); + OUString const relativeURI(xRelativeURI->getUriReference()); + + return relativeURI; +} + +RDFaExportHelper::RDFaExportHelper(SvXMLExport & i_rExport) + : m_rExport(i_rExport), m_Counter(0) +{ + const uno::Reference<rdf::XRepositorySupplier> xRS( m_rExport.GetModel(), + uno::UNO_QUERY_THROW); + m_xRepository.set(xRS->getRDFRepository(), uno::UNO_QUERY_THROW); +} + +OUString +RDFaExportHelper::LookupBlankNode( + uno::Reference<rdf::XBlankNode> const & i_xBlankNode) +{ + OSL_ENSURE(i_xBlankNode.is(), "null BlankNode?"); + if (!i_xBlankNode.is()) throw uno::RuntimeException(); + OUString & rEntry( + m_BlankNodeMap[ i_xBlankNode->getStringValue() ] ); + if (rEntry.isEmpty()) + { + rEntry = "_:b" + OUString::number(++m_Counter); + } + return rEntry; +} + +void +RDFaExportHelper::AddRDFa( + uno::Reference<rdf::XMetadatable> const & i_xMetadatable) +{ + try + { + beans::Pair< uno::Sequence<rdf::Statement>, sal_Bool > const + RDFaResult( m_xRepository->getStatementRDFa(i_xMetadatable) ); + + uno::Sequence<rdf::Statement> const & rStatements( RDFaResult.First ); + + if (!rStatements.hasElements()) + { + return; // no RDFa + } + + // all stmts have the same subject, so we only handle first one + const uno::Reference<rdf::XURI> xSubjectURI(rStatements[0].Subject, + uno::UNO_QUERY); + const uno::Reference<rdf::XBlankNode> xSubjectBNode( + rStatements[0].Subject, uno::UNO_QUERY); + if (!xSubjectURI.is() && !xSubjectBNode.is()) + { + throw uno::RuntimeException(); + } + const OUString about( xSubjectURI.is() + ? getRelativeReference(m_rExport, xSubjectURI->getStringValue()) + : "[" + LookupBlankNode(xSubjectBNode) + "]" + ); + + const uno::Reference<rdf::XLiteral> xContent( + rStatements[0].Object, uno::UNO_QUERY_THROW ); + const uno::Reference<rdf::XURI> xDatatype(xContent->getDatatype()); + if (xDatatype.is()) + { + const OUString datatype( + makeCURIE(&m_rExport, xDatatype) ); + m_rExport.AddAttribute(XML_NAMESPACE_XHTML, + token::XML_DATATYPE, datatype); + } + if (RDFaResult.Second) // there is xhtml:content + { + m_rExport.AddAttribute(XML_NAMESPACE_XHTML, token::XML_CONTENT, + xContent->getValue()); + } + + ::std::vector<OUString> curies; + for (rdf::Statement const& rStatement : rStatements) + { + curies.push_back(makeCURIE(&m_rExport, rStatement.Predicate)); + } + OUStringBuffer property; + ::comphelper::intersperse(curies.begin(), curies.end(), + ::comphelper::OUStringBufferAppender(property), + OUString(" ")); + + m_rExport.AddAttribute(XML_NAMESPACE_XHTML, token::XML_PROPERTY, + property.makeStringAndClear()); + + m_rExport.AddAttribute(XML_NAMESPACE_XHTML, token::XML_ABOUT, about); + } + catch (uno::Exception &) + { + OSL_FAIL("AddRDFa: exception"); + } +} + +} // namespace xmloff + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/RDFaImportHelper.cxx b/xmloff/source/core/RDFaImportHelper.cxx new file mode 100644 index 000000000..e0cc65698 --- /dev/null +++ b/xmloff/source/core/RDFaImportHelper.cxx @@ -0,0 +1,449 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <RDFaImportHelper.hxx> + +#include <xmloff/xmlimp.hxx> +#include <xmloff/nmspmap.hxx> + +#include <comphelper/sequence.hxx> + +#include <com/sun/star/rdf/URI.hpp> +#include <com/sun/star/rdf/XDocumentRepository.hpp> +#include <com/sun/star/rdf/XRepositorySupplier.hpp> + +#include <rtl/ustring.hxx> +#include <sal/log.hxx> + +#include <map> + +using namespace ::com::sun::star; + +namespace xmloff { + +namespace { + +/** a bit of context for parsing RDFa attributes */ +class RDFaReader +{ + const SvXMLImport & m_rImport; + + const SvXMLImport & GetImport() const { return m_rImport; } + + //FIXME: this is an ugly hack to workaround buggy SvXMLImport::GetAbsolute + OUString GetAbsoluteReference(OUString const & i_rURI) const + { + if (i_rURI.isEmpty() || i_rURI[0] == '#') + { + return GetImport().GetBaseURL() + i_rURI; + } + else + { + return GetImport().GetAbsoluteReference(i_rURI); + } + } + +public: + explicit RDFaReader(SvXMLImport const & i_rImport) + : m_rImport(i_rImport) + { } + + // returns URI or blank node! + OUString ReadCURIE(OUString const & i_rCURIE) const; + + std::vector< OUString > + ReadCURIEs(OUString const & i_rCURIEs) const; + + OUString + ReadURIOrSafeCURIE( OUString const & i_rURIOrSafeCURIE) const; +}; + +/** helper to insert RDFa statements into the RDF repository */ +class RDFaInserter +{ + const uno::Reference<uno::XComponentContext> m_xContext; + uno::Reference< rdf::XDocumentRepository > m_xRepository; + + typedef ::std::map< OUString, uno::Reference< rdf::XBlankNode > > + BlankNodeMap_t; + + BlankNodeMap_t m_BlankNodeMap; + +public: + RDFaInserter(uno::Reference<uno::XComponentContext> const & i_xContext, + uno::Reference< rdf::XDocumentRepository > const & i_xRepository) + : m_xContext(i_xContext) + , m_xRepository(i_xRepository) + {} + + uno::Reference< rdf::XBlankNode > + LookupBlankNode(OUString const & i_rNodeId ); + + uno::Reference< rdf::XURI > + MakeURI( OUString const & i_rURI) const; + + uno::Reference< rdf::XResource> + MakeResource( OUString const & i_rResource); + + void InsertRDFaEntry(struct RDFaEntry const & i_rEntry); +}; + +} + +/** store parsed RDFa attributes */ +struct ParsedRDFaAttributes +{ + OUString m_About; + ::std::vector< OUString > m_Properties; + OUString m_Content; + OUString m_Datatype; + + ParsedRDFaAttributes( + OUString const & i_rAbout, + ::std::vector< OUString > const & i_rProperties, + OUString const & i_rContent, + OUString const & i_rDatatype) + : m_About(i_rAbout) + , m_Properties(i_rProperties) + , m_Content(i_rContent) + , m_Datatype(i_rDatatype) + { } +}; + +/** store metadatable object and its RDFa attributes */ +struct RDFaEntry +{ + uno::Reference<rdf::XMetadatable> m_xObject; + std::shared_ptr<ParsedRDFaAttributes> m_xRDFaAttributes; + + RDFaEntry(uno::Reference<rdf::XMetadatable> const & i_xObject, + std::shared_ptr<ParsedRDFaAttributes> const& i_pRDFaAttributes) + : m_xObject(i_xObject) + , m_xRDFaAttributes(i_pRDFaAttributes) + { } +}; + +static bool isWS(const sal_Unicode i_Char) +{ + return ('\t' == i_Char) || ('\n' == i_Char) || ('\r' == i_Char) + || (' ' == i_Char); +} + +static OUString splitAtWS(OUString & io_rString) +{ + const sal_Int32 len( io_rString.getLength() ); + sal_Int32 idxstt(0); + while ((idxstt < len) && ( isWS(io_rString[idxstt]))) + ++idxstt; // skip leading ws + sal_Int32 idxend(idxstt); + while ((idxend < len) && (!isWS(io_rString[idxend]))) + ++idxend; // the CURIE + const OUString ret(io_rString.copy(idxstt, idxend - idxstt)); + io_rString = io_rString.copy(idxend); // rest + return ret; +} + +OUString +RDFaReader::ReadCURIE(OUString const & i_rCURIE) const +{ + // the RDFa spec says that a prefix is required (it may be empty: ":foo") + const sal_Int32 idx( i_rCURIE.indexOf(':') ); + if (idx >= 0) + { + OUString Prefix; + OUString LocalName; + OUString Namespace; + // LocalName may contain ':', see "ipchar" in RFC 3987 + sal_uInt16 nKey( GetImport().GetNamespaceMap().GetKeyByQName( + i_rCURIE, &Prefix, &LocalName, &Namespace, SvXMLNamespaceMap::QNameMode::AttrValue) ); + if ( Prefix == "_" ) + { + // eeek, it's a bnode! + // "_" is not a valid URI scheme => we can identify bnodes + return i_rCURIE; + } + else + { + SAL_WARN_IF(XML_NAMESPACE_NONE == nKey, "xmloff.core", "no namespace?"); + if ((XML_NAMESPACE_UNKNOWN != nKey) && + (XML_NAMESPACE_XMLNS != nKey)) + { + // N.B.: empty LocalName is valid! + const OUString URI(Namespace + LocalName); + return GetAbsoluteReference(URI); + } + else + { + SAL_INFO("xmloff.core", "ReadCURIE: invalid CURIE: invalid prefix" ); + return OUString(); + } + } + } + SAL_INFO("xmloff.core", "ReadCURIE: invalid CURIE: no prefix" ); + return OUString(); +} + +::std::vector< OUString > +RDFaReader::ReadCURIEs(OUString const & i_rCURIEs) const +{ + std::vector< OUString > vec; + OUString CURIEs(i_rCURIEs); + do { + OUString curie( splitAtWS(CURIEs) ); + if (!curie.isEmpty()) + { + const OUString uri(ReadCURIE(curie)); + if (!uri.isEmpty()) + { + vec.push_back(uri); + } + } + } + while (!CURIEs.isEmpty()); + if (vec.empty()) + { + SAL_INFO("xmloff.core", "ReadCURIEs: invalid CURIEs" ); + } + return vec; +} + +OUString +RDFaReader::ReadURIOrSafeCURIE(OUString const & i_rURIOrSafeCURIE) const +{ + const sal_Int32 len(i_rURIOrSafeCURIE.getLength()); + if (len && (i_rURIOrSafeCURIE[0] == '[')) + { + if ((len >= 2) && (i_rURIOrSafeCURIE[len - 1] == ']')) + { + return ReadCURIE(i_rURIOrSafeCURIE.copy(1, len - 2)); + } + else + { + SAL_INFO("xmloff.core", "ReadURIOrSafeCURIE: invalid SafeCURIE" ); + return OUString(); + } + } + else + { + if (i_rURIOrSafeCURIE.startsWith("_:")) // blank node + { + SAL_INFO("xmloff.core", "ReadURIOrSafeCURIE: invalid URI: scheme is _" ); + return OUString(); + } + else + { + return GetAbsoluteReference(i_rURIOrSafeCURIE); + } + } +} + +uno::Reference< rdf::XBlankNode > +RDFaInserter::LookupBlankNode(OUString const & i_rNodeId ) +{ + uno::Reference< rdf::XBlankNode > & rEntry( m_BlankNodeMap[ i_rNodeId ] ); + if (!rEntry.is()) + { + rEntry = m_xRepository->createBlankNode(); + } + return rEntry; +} + +uno::Reference< rdf::XURI > +RDFaInserter::MakeURI( OUString const & i_rURI) const +{ + if (i_rURI.startsWith("_:")) // blank node + { + SAL_INFO("xmloff.core", "MakeURI: cannot create URI for blank node"); + return nullptr; + } + else + { + try + { + return rdf::URI::create( m_xContext, i_rURI ); + } + catch (uno::Exception &) + { + SAL_WARN("xmloff.core", "MakeURI: cannot create URI"); + return nullptr; + } + } +} + +uno::Reference<rdf::XResource> +RDFaInserter::MakeResource( OUString const & i_rResource) +{ + if (i_rResource.startsWith("_:")) // blank node + { + // we cannot use the blank node label as-is: it must be distinct + // from labels in other graphs, so create fresh ones per XML stream + // N.B.: content.xml and styles.xml are distinct graphs + OUString name( i_rResource.copy(2) ); + const uno::Reference< rdf::XBlankNode > xBNode( LookupBlankNode(name) ); + SAL_WARN_IF(!xBNode.is(), "xmloff.core", "no blank node?"); + return xBNode; + } + else + { + return MakeURI( i_rResource ); + } +} + +void RDFaInserter::InsertRDFaEntry( + struct RDFaEntry const & i_rEntry) +{ + SAL_WARN_IF(!i_rEntry.m_xObject.is(), "xmloff.core", "InsertRDFaEntry: invalid arg: null object"); + if (!i_rEntry.m_xObject.is()) return; + + const uno::Reference< rdf::XResource > xSubject( + MakeResource( i_rEntry.m_xRDFaAttributes->m_About ) ); + if (!xSubject.is()) + { + return; // invalid + } + + ::std::vector< uno::Reference< rdf::XURI > > predicates; + + predicates.reserve(i_rEntry.m_xRDFaAttributes->m_Properties.size()); + + for (OUString const& prop : i_rEntry.m_xRDFaAttributes->m_Properties) + { + auto const xURI(MakeURI(prop)); + if (xURI.is()) + { + predicates.push_back(xURI); + } + } + + if (predicates.empty()) + { + return; // invalid + } + + uno::Reference<rdf::XURI> xDatatype; + if (!i_rEntry.m_xRDFaAttributes->m_Datatype.isEmpty()) + { + xDatatype = MakeURI( i_rEntry.m_xRDFaAttributes->m_Datatype ); + } + + try + { + // N.B.: this will call xMeta->ensureMetadataReference, which is why + // this must be done _after_ importing the whole XML file, + // to prevent collision between generated ids and ids in the file + m_xRepository->setStatementRDFa(xSubject, comphelper::containerToSequence(predicates), + i_rEntry.m_xObject, + i_rEntry.m_xRDFaAttributes->m_Content, xDatatype); + } + catch (uno::Exception &) + { + SAL_WARN("xmloff.core", "InsertRDFaEntry: setStatementRDFa failed?"); + } +} + +RDFaImportHelper::RDFaImportHelper(const SvXMLImport & i_rImport) + : m_rImport(i_rImport) +{ +} + +RDFaImportHelper::~RDFaImportHelper() +{ +} + +std::shared_ptr<ParsedRDFaAttributes> +RDFaImportHelper::ParseRDFa( + OUString const & i_rAbout, + OUString const & i_rProperty, + OUString const & i_rContent, + OUString const & i_rDatatype) +{ + if (i_rProperty.isEmpty()) + { + SAL_INFO("xmloff.core", "AddRDFa: invalid input: xhtml:property empty"); + return std::shared_ptr<ParsedRDFaAttributes>(); + } + // must parse CURIEs here: need namespace declaration context + RDFaReader reader(GetImport()); + const OUString about( reader.ReadURIOrSafeCURIE(i_rAbout) ); + if (about.isEmpty()) { + return std::shared_ptr<ParsedRDFaAttributes>(); + } + const ::std::vector< OUString > properties( + reader.ReadCURIEs(i_rProperty) ); + if (properties.empty()) { + return std::shared_ptr<ParsedRDFaAttributes>(); + } + const OUString datatype( !i_rDatatype.isEmpty() + ? reader.ReadCURIE(i_rDatatype) + : OUString() ); + return std::make_shared<ParsedRDFaAttributes>( + about, properties, i_rContent, datatype); +} + +void +RDFaImportHelper::AddRDFa( + uno::Reference<rdf::XMetadatable> const & i_xObject, + std::shared_ptr<ParsedRDFaAttributes> const & i_pRDFaAttributes) +{ + if (!i_xObject.is()) + { + SAL_WARN("xmloff.core", "AddRDFa: invalid arg: null textcontent"); + return; + } + if (!i_pRDFaAttributes) + { + SAL_WARN("xmloff.core", "AddRDFa: invalid arg: null RDFa attributes"); + return; + } + m_RDFaEntries.emplace_back(i_xObject, i_pRDFaAttributes); +} + +void +RDFaImportHelper::ParseAndAddRDFa( + uno::Reference<rdf::XMetadatable> const & i_xObject, + OUString const & i_rAbout, + OUString const & i_rProperty, + OUString const & i_rContent, + OUString const & i_rDatatype) +{ + std::shared_ptr<ParsedRDFaAttributes> pAttributes( + ParseRDFa(i_rAbout, i_rProperty, i_rContent, i_rDatatype) ); + if (pAttributes) + { + AddRDFa(i_xObject, pAttributes); + } +} + +void RDFaImportHelper::InsertRDFa( + uno::Reference< rdf::XRepositorySupplier> const & i_xModel) +{ + SAL_WARN_IF(!i_xModel.is(), "xmloff.core", "InsertRDFa: invalid arg: model null"); + if (!i_xModel.is()) return; + const uno::Reference< rdf::XDocumentRepository > xRepository( + i_xModel->getRDFRepository(), uno::UNO_QUERY); + SAL_WARN_IF(!xRepository.is(), "xmloff.core", "InsertRDFa: no DocumentRepository?"); + if (!xRepository.is()) return; + RDFaInserter inserter(GetImport().GetComponentContext(), xRepository); + for (const auto& RDFaEntry : m_RDFaEntries) + inserter.InsertRDFaEntry(RDFaEntry); +} + +} // namespace xmloff + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/SettingsExportHelper.cxx b/xmloff/source/core/SettingsExportHelper.cxx new file mode 100644 index 000000000..09a615b51 --- /dev/null +++ b/xmloff/source/core/SettingsExportHelper.cxx @@ -0,0 +1,517 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <sax/tools/converter.hxx> + +#include <xmloff/SettingsExportHelper.hxx> +#include <xmloff/xmltoken.hxx> +#include <sal/log.hxx> +#include <tools/debug.hxx> +#include <tools/diagnose_ex.h> +#include <comphelper/base64.hxx> +#include <comphelper/extract.hxx> + +#include <com/sun/star/linguistic2/XSupportedLocales.hpp> +#include <com/sun/star/i18n/XForbiddenCharacters.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/container/XIndexContainer.hpp> +#include <com/sun/star/util/PathSubstitution.hpp> +#include <com/sun/star/util/DateTime.hpp> +#include <com/sun/star/formula/SymbolDescriptor.hpp> +#include <com/sun/star/document/PrinterIndependentLayout.hpp> +#include <com/sun/star/document/IndexedPropertyValues.hpp> +#include <xmloff/XMLSettingsExportContext.hxx> +#include "xmlenums.hxx" + +using namespace ::com::sun::star; +using namespace ::xmloff::token; + +static const OUStringLiteral gsPrinterIndependentLayout( "PrinterIndependentLayout" ); +static const OUStringLiteral gsColorTableURL( "ColorTableURL" ); +static const OUStringLiteral gsLineEndTableURL( "LineEndTableURL" ); +static const OUStringLiteral gsHatchTableURL( "HatchTableURL" ); +static const OUStringLiteral gsDashTableURL( "DashTableURL" ); +static const OUStringLiteral gsGradientTableURL( "GradientTableURL" ); +static const OUStringLiteral gsBitmapTableURL( "BitmapTableURL" ); + +XMLSettingsExportHelper::XMLSettingsExportHelper( ::xmloff::XMLSettingsExportContext& i_rContext ) +: m_rContext( i_rContext ) +{ +} + +XMLSettingsExportHelper::~XMLSettingsExportHelper() +{ +} + +void XMLSettingsExportHelper::CallTypeFunction(const uno::Any& rAny, + const OUString& rName) const +{ + uno::Any aAny( rAny ); + ManipulateSetting( aAny, rName ); + + uno::TypeClass eClass = aAny.getValueTypeClass(); + switch (eClass) + { + case uno::TypeClass_VOID: + { + /* + * This assertion pops up when exporting values which are set to: + * PropertyAttribute::MAYBEVOID, and thus are _supposed_ to have + * a VOID value...so I'm removing it ...mtg + * OSL_FAIL("no type"); + */ + } + break; + case uno::TypeClass_BOOLEAN: + { + exportBool(::cppu::any2bool(aAny), rName); + } + break; + case uno::TypeClass_BYTE: + { + exportByte(); + } + break; + case uno::TypeClass_SHORT: + { + sal_Int16 nInt16 = 0; + aAny >>= nInt16; + exportShort(nInt16, rName); + } + break; + case uno::TypeClass_LONG: + { + sal_Int32 nInt32 = 0; + aAny >>= nInt32; + exportInt(nInt32, rName); + } + break; + case uno::TypeClass_HYPER: + { + sal_Int64 nInt64 = 0; + aAny >>= nInt64; + exportLong(nInt64, rName); + } + break; + case uno::TypeClass_DOUBLE: + { + double fDouble = 0.0; + aAny >>= fDouble; + exportDouble(fDouble, rName); + } + break; + case uno::TypeClass_STRING: + { + OUString sString; + aAny >>= sString; + exportString(sString, rName); + } + break; + default: + { + const uno::Type& aType = aAny.getValueType(); + if (aType.equals(cppu::UnoType<uno::Sequence<beans::PropertyValue>>::get() ) ) + { + uno::Sequence< beans::PropertyValue> aProps; + aAny >>= aProps; + exportSequencePropertyValue(aProps, rName); + } + else if( aType.equals(cppu::UnoType<uno::Sequence<sal_Int8>>::get() ) ) + { + uno::Sequence< sal_Int8 > aProps; + aAny >>= aProps; + exportbase64Binary(aProps, rName); + } + else if (aType.equals(cppu::UnoType<container::XNameContainer>::get()) || + aType.equals(cppu::UnoType<container::XNameAccess>::get())) + { + uno::Reference< container::XNameAccess> aNamed; + aAny >>= aNamed; + exportNameAccess(aNamed, rName); + } + else if (aType.equals(cppu::UnoType<container::XIndexAccess>::get()) || + aType.equals(cppu::UnoType<container::XIndexContainer>::get()) ) + { + uno::Reference<container::XIndexAccess> aIndexed; + aAny >>= aIndexed; + exportIndexAccess(aIndexed, rName); + } + else if (aType.equals(cppu::UnoType<util::DateTime>::get()) ) + { + util::DateTime aDateTime; + aAny >>= aDateTime; + exportDateTime(aDateTime, rName); + } + else if( aType.equals(cppu::UnoType<i18n::XForbiddenCharacters>::get()) ) + { + exportForbiddenCharacters( aAny, rName ); + } + else if( aType.equals(cppu::UnoType<uno::Sequence<formula::SymbolDescriptor>>::get() ) ) + { + uno::Sequence< formula::SymbolDescriptor > aProps; + aAny >>= aProps; + exportSymbolDescriptors(aProps, rName); + } + else { + OSL_FAIL("this type is not implemented now"); + } + } + break; + } +} + +void XMLSettingsExportHelper::exportBool(const bool bValue, const OUString& rName) const +{ + DBG_ASSERT(!rName.isEmpty(), "no name"); + m_rContext.AddAttribute( XML_NAME, rName ); + m_rContext.AddAttribute( XML_TYPE, XML_BOOLEAN ); + m_rContext.StartElement( XML_CONFIG_ITEM ); + OUString sValue; + if (bValue) + sValue = GetXMLToken(XML_TRUE); + else + sValue = GetXMLToken(XML_FALSE); + m_rContext.Characters( sValue ); + m_rContext.EndElement( false ); +} + +void XMLSettingsExportHelper::exportByte() +{ + OSL_ENSURE(false, "XMLSettingsExportHelper::exportByte(): #i114162#:\n" + "config-items of type \"byte\" are not valid ODF, " + "so storing them is disabled!\n" + "Use a different type instead (e.g. \"short\")."); +} +void XMLSettingsExportHelper::exportShort(const sal_Int16 nValue, const OUString& rName) const +{ + DBG_ASSERT(!rName.isEmpty(), "no name"); + m_rContext.AddAttribute( XML_NAME, rName ); + m_rContext.AddAttribute( XML_TYPE, XML_SHORT ); + m_rContext.StartElement( XML_CONFIG_ITEM ); + m_rContext.Characters( OUString::number(nValue) ); + m_rContext.EndElement( false ); +} + +void XMLSettingsExportHelper::exportInt(const sal_Int32 nValue, const OUString& rName) const +{ + DBG_ASSERT(!rName.isEmpty(), "no name"); + m_rContext.AddAttribute( XML_NAME, rName ); + m_rContext.AddAttribute( XML_TYPE, XML_INT ); + m_rContext.StartElement( XML_CONFIG_ITEM ); + m_rContext.Characters( OUString::number(nValue) ); + m_rContext.EndElement( false ); +} + +void XMLSettingsExportHelper::exportLong(const sal_Int64 nValue, const OUString& rName) const +{ + DBG_ASSERT(!rName.isEmpty(), "no name"); + m_rContext.AddAttribute( XML_NAME, rName ); + m_rContext.AddAttribute( XML_TYPE, XML_LONG ); + m_rContext.StartElement( XML_CONFIG_ITEM ); + m_rContext.Characters( OUString::number(nValue) ); + m_rContext.EndElement( false ); +} + +void XMLSettingsExportHelper::exportDouble(const double fValue, const OUString& rName) const +{ + DBG_ASSERT(!rName.isEmpty(), "no name"); + m_rContext.AddAttribute( XML_NAME, rName ); + m_rContext.AddAttribute( XML_TYPE, XML_DOUBLE ); + m_rContext.StartElement( XML_CONFIG_ITEM ); + OUStringBuffer sBuffer; + ::sax::Converter::convertDouble(sBuffer, fValue); + m_rContext.Characters( sBuffer.makeStringAndClear() ); + m_rContext.EndElement( false ); +} + +void XMLSettingsExportHelper::exportString(const OUString& sValue, const OUString& rName) const +{ + DBG_ASSERT(!rName.isEmpty(), "no name"); + m_rContext.AddAttribute( XML_NAME, rName ); + m_rContext.AddAttribute( XML_TYPE, XML_STRING ); + m_rContext.StartElement( XML_CONFIG_ITEM ); + if (!sValue.isEmpty()) + m_rContext.Characters( sValue ); + m_rContext.EndElement( false ); +} + +void XMLSettingsExportHelper::exportDateTime(const util::DateTime& aValue, const OUString& rName) const +{ + DBG_ASSERT(!rName.isEmpty(), "no name"); + m_rContext.AddAttribute( XML_NAME, rName ); + m_rContext.AddAttribute( XML_TYPE, XML_DATETIME ); + OUStringBuffer sBuffer; + ::sax::Converter::convertDateTime(sBuffer, aValue, nullptr); + m_rContext.StartElement( XML_CONFIG_ITEM ); + m_rContext.Characters( sBuffer.makeStringAndClear() ); + m_rContext.EndElement( false ); +} + +void XMLSettingsExportHelper::exportSequencePropertyValue( + const uno::Sequence<beans::PropertyValue>& aProps, + const OUString& rName) const +{ + DBG_ASSERT(!rName.isEmpty(), "no name"); + if(aProps.hasElements()) + { + m_rContext.AddAttribute( XML_NAME, rName ); + m_rContext.StartElement( XML_CONFIG_ITEM_SET ); + for (const auto& rProp : aProps) + CallTypeFunction(rProp.Value, rProp.Name); + m_rContext.EndElement( true ); + } +} +void XMLSettingsExportHelper::exportSymbolDescriptors( + const uno::Sequence < formula::SymbolDescriptor > &rProps, + const OUString& rName) const +{ + uno::Reference< container::XIndexContainer > xBox = document::IndexedPropertyValues::create(m_rContext.GetComponentContext()); + + const OUString sName ( "Name" ); + const OUString sExportName ( "ExportName" ); + const OUString sSymbolSet ( "SymbolSet" ); + const OUString sCharacter ( "Character" ); + const OUString sFontName ( "FontName" ); + const OUString sCharSet ( "CharSet" ); + const OUString sFamily ( "Family" ); + const OUString sPitch ( "Pitch" ); + const OUString sWeight ( "Weight" ); + const OUString sItalic ( "Italic" ); + + sal_Int32 nCount = rProps.getLength(); + const formula::SymbolDescriptor *pDescriptor = rProps.getConstArray(); + + for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++, pDescriptor++ ) + { + uno::Sequence < beans::PropertyValue > aSequence ( XML_SYMBOL_DESCRIPTOR_MAX ); + beans::PropertyValue *pSymbol = aSequence.getArray(); + + pSymbol[XML_SYMBOL_DESCRIPTOR_NAME].Name = sName; + pSymbol[XML_SYMBOL_DESCRIPTOR_NAME].Value <<= pDescriptor->sName; + pSymbol[XML_SYMBOL_DESCRIPTOR_EXPORT_NAME].Name = sExportName; + pSymbol[XML_SYMBOL_DESCRIPTOR_EXPORT_NAME].Value<<= pDescriptor->sExportName; + pSymbol[XML_SYMBOL_DESCRIPTOR_FONT_NAME].Name = sFontName; + pSymbol[XML_SYMBOL_DESCRIPTOR_FONT_NAME].Value <<= pDescriptor->sFontName; + pSymbol[XML_SYMBOL_DESCRIPTOR_CHAR_SET].Name = sCharSet; + pSymbol[XML_SYMBOL_DESCRIPTOR_CHAR_SET].Value <<= pDescriptor->nCharSet; + pSymbol[XML_SYMBOL_DESCRIPTOR_FAMILY].Name = sFamily; + pSymbol[XML_SYMBOL_DESCRIPTOR_FAMILY].Value <<= pDescriptor->nFamily; + pSymbol[XML_SYMBOL_DESCRIPTOR_PITCH].Name = sPitch; + pSymbol[XML_SYMBOL_DESCRIPTOR_PITCH].Value <<= pDescriptor->nPitch; + pSymbol[XML_SYMBOL_DESCRIPTOR_WEIGHT].Name = sWeight; + pSymbol[XML_SYMBOL_DESCRIPTOR_WEIGHT].Value <<= pDescriptor->nWeight; + pSymbol[XML_SYMBOL_DESCRIPTOR_ITALIC].Name = sItalic; + pSymbol[XML_SYMBOL_DESCRIPTOR_ITALIC].Value <<= pDescriptor->nItalic; + pSymbol[XML_SYMBOL_DESCRIPTOR_SYMBOL_SET].Name = sSymbolSet; + pSymbol[XML_SYMBOL_DESCRIPTOR_SYMBOL_SET].Value <<= pDescriptor->sSymbolSet; + pSymbol[XML_SYMBOL_DESCRIPTOR_CHARACTER].Name = sCharacter; + pSymbol[XML_SYMBOL_DESCRIPTOR_CHARACTER].Value <<= pDescriptor->nCharacter; + + xBox->insertByIndex(nIndex, uno::makeAny( aSequence )); + } + + exportIndexAccess( xBox, rName ); +} +void XMLSettingsExportHelper::exportbase64Binary( + const uno::Sequence<sal_Int8>& aProps, + const OUString& rName) const +{ + DBG_ASSERT(!rName.isEmpty(), "no name"); + m_rContext.AddAttribute( XML_NAME, rName ); + m_rContext.AddAttribute( XML_TYPE, XML_BASE64BINARY ); + m_rContext.StartElement( XML_CONFIG_ITEM ); + if(aProps.hasElements()) + { + OUStringBuffer sBuffer; + ::comphelper::Base64::encode(sBuffer, aProps); + m_rContext.Characters( sBuffer.makeStringAndClear() ); + } + m_rContext.EndElement( false ); +} + +void XMLSettingsExportHelper::exportMapEntry(const uno::Any& rAny, + const OUString& rName, + const bool bNameAccess) const +{ + DBG_ASSERT((bNameAccess && !rName.isEmpty()) || !bNameAccess, "no name"); + uno::Sequence<beans::PropertyValue> aProps; + rAny >>= aProps; + if (aProps.hasElements()) + { + if (bNameAccess) + m_rContext.AddAttribute( XML_NAME, rName ); + m_rContext.StartElement( XML_CONFIG_ITEM_MAP_ENTRY ); + for (const auto& rProp : std::as_const(aProps)) + CallTypeFunction(rProp.Value, rProp.Name); + m_rContext.EndElement( true ); + } +} + +void XMLSettingsExportHelper::exportNameAccess( + const uno::Reference<container::XNameAccess>& aNamed, + const OUString& rName) const +{ + DBG_ASSERT(!rName.isEmpty(), "no name"); + DBG_ASSERT(aNamed->getElementType().equals(cppu::UnoType<uno::Sequence<beans::PropertyValue>>::get() ), + "wrong NameAccess" ); + if(aNamed->hasElements()) + { + m_rContext.AddAttribute( XML_NAME, rName ); + m_rContext.StartElement( XML_CONFIG_ITEM_MAP_NAMED ); + const uno::Sequence< OUString > aNames(aNamed->getElementNames()); + for (const auto& rElementName : aNames) + exportMapEntry(aNamed->getByName(rElementName), rElementName, true); + m_rContext.EndElement( true ); + } +} + +void XMLSettingsExportHelper::exportIndexAccess( + const uno::Reference<container::XIndexAccess>& rIndexed, + const OUString& rName) const +{ + DBG_ASSERT(!rName.isEmpty(), "no name"); + DBG_ASSERT(rIndexed->getElementType().equals(cppu::UnoType<uno::Sequence<beans::PropertyValue>>::get() ), + "wrong IndexAccess" ); + if (rIndexed->hasElements()) + { + m_rContext.AddAttribute( XML_NAME, rName ); + m_rContext.StartElement( XML_CONFIG_ITEM_MAP_INDEXED ); + sal_Int32 nCount = rIndexed->getCount(); + for (sal_Int32 i = 0; i < nCount; i++) + { + exportMapEntry(rIndexed->getByIndex(i), "", false); + } + m_rContext.EndElement( true ); + } +} + +void XMLSettingsExportHelper::exportForbiddenCharacters( + const uno::Any &rAny, + const OUString& rName) const +{ + uno::Reference<i18n::XForbiddenCharacters> xForbChars; + uno::Reference<linguistic2::XSupportedLocales> xLocales; + + rAny >>= xForbChars; + rAny >>= xLocales; + + SAL_WARN_IF( !(xForbChars.is() && xLocales.is()), "xmloff","XMLSettingsExportHelper::exportForbiddenCharacters: got illegal forbidden characters!" ); + + if( !xForbChars.is() || !xLocales.is() ) + return; + + uno::Reference< container::XIndexContainer > xBox = document::IndexedPropertyValues::create(m_rContext.GetComponentContext()); + const uno::Sequence< lang::Locale > aLocales( xLocales->getLocales() ); + + /* FIXME-BCP47: this stupid and counterpart in + * xmloff/source/core/DocumentSettingsContext.cxx + * XMLConfigItemMapIndexedContext::EndElement() */ + + const OUString sLanguage ( "Language" ); + const OUString sCountry ( "Country" ); + const OUString sVariant ( "Variant" ); + const OUString sBeginLine ( "BeginLine" ); + const OUString sEndLine ( "EndLine" ); + + sal_Int32 nPos = 0; + for( const auto& rLocale : aLocales ) + { + if( xForbChars->hasForbiddenCharacters( rLocale ) ) + { + const i18n::ForbiddenCharacters aChars( xForbChars->getForbiddenCharacters( rLocale ) ); + + + uno::Sequence < beans::PropertyValue > aSequence ( XML_FORBIDDEN_CHARACTER_MAX ); + beans::PropertyValue *pForChar = aSequence.getArray(); + + pForChar[XML_FORBIDDEN_CHARACTER_LANGUAGE].Name = sLanguage; + pForChar[XML_FORBIDDEN_CHARACTER_LANGUAGE].Value <<= rLocale.Language; + pForChar[XML_FORBIDDEN_CHARACTER_COUNTRY].Name = sCountry; + pForChar[XML_FORBIDDEN_CHARACTER_COUNTRY].Value <<= rLocale.Country; + pForChar[XML_FORBIDDEN_CHARACTER_VARIANT].Name = sVariant; + pForChar[XML_FORBIDDEN_CHARACTER_VARIANT].Value <<= rLocale.Variant; + pForChar[XML_FORBIDDEN_CHARACTER_BEGIN_LINE].Name = sBeginLine; + pForChar[XML_FORBIDDEN_CHARACTER_BEGIN_LINE].Value <<= aChars.beginLine; + pForChar[XML_FORBIDDEN_CHARACTER_END_LINE].Name = sEndLine; + pForChar[XML_FORBIDDEN_CHARACTER_END_LINE].Value <<= aChars.endLine; + xBox->insertByIndex(nPos++, uno::makeAny( aSequence )); + } + } + + exportIndexAccess( xBox, rName ); +} + +void XMLSettingsExportHelper::exportAllSettings( + const uno::Sequence<beans::PropertyValue>& aProps, + const OUString& rName) const +{ + DBG_ASSERT(!rName.isEmpty(), "no name"); + exportSequencePropertyValue(aProps, rName); +} + + +/** For some settings we may want to change their API representation + * from their XML settings representation. This is your chance to do + * so! + */ +void XMLSettingsExportHelper::ManipulateSetting( uno::Any& rAny, const OUString& rName ) const +{ + if( rName == gsPrinterIndependentLayout ) + { + sal_Int16 nTmp = sal_Int16(); + if( rAny >>= nTmp ) + { + if( nTmp == document::PrinterIndependentLayout::LOW_RESOLUTION ) + rAny <<= OUString("low-resolution"); + else if( nTmp == document::PrinterIndependentLayout::DISABLED ) + rAny <<= OUString("disabled"); + else if( nTmp == document::PrinterIndependentLayout::HIGH_RESOLUTION ) + rAny <<= OUString("high-resolution"); + } + } + else if( (rName == gsColorTableURL) || (rName == gsLineEndTableURL) || (rName == gsHatchTableURL) || + (rName == gsDashTableURL) || (rName == gsGradientTableURL) || (rName == gsBitmapTableURL ) ) + { + if( !mxStringSubsitution.is() ) + { + try + { + const_cast< XMLSettingsExportHelper* >(this)->mxStringSubsitution = + util::PathSubstitution::create( m_rContext.GetComponentContext() ); + } + catch( uno::Exception& ) + { + DBG_UNHANDLED_EXCEPTION("xmloff.core"); + } + } + + if( mxStringSubsitution.is() ) + { + OUString aURL; + rAny >>= aURL; + aURL = mxStringSubsitution->reSubstituteVariables( aURL ); + rAny <<= aURL; + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/SvXMLAttr.cxx b/xmloff/source/core/SvXMLAttr.cxx new file mode 100644 index 000000000..5fa0f5ce5 --- /dev/null +++ b/xmloff/source/core/SvXMLAttr.cxx @@ -0,0 +1,38 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <limits.h> +#include "SvXMLAttr.hxx" + +SvXMLAttr::SvXMLAttr( const OUString& rLName, + const OUString& rValue ) : + aPrefixPos(USHRT_MAX), + aLName(rLName), + aValue(rValue) +{ +} + +SvXMLAttr::SvXMLAttr( const sal_uInt16 nPos, + const OUString& rLName, + const OUString& rValue ) : + aPrefixPos(nPos), + aLName(rLName), + aValue(rValue) +{ +} + +bool SvXMLAttr::operator== (const SvXMLAttr &rCmp) const +{ + return ( rCmp.aPrefixPos == aPrefixPos ) && + ( rCmp.aLName == aLName ) && + ( rCmp.aValue == aValue ); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/SvXMLAttr.hxx b/xmloff/source/core/SvXMLAttr.hxx new file mode 100644 index 000000000..354b67497 --- /dev/null +++ b/xmloff/source/core/SvXMLAttr.hxx @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_XMLOFF_SOURCE_CORE_SVXMLATTR_HXX +#define INCLUDED_XMLOFF_SOURCE_CORE_SVXMLATTR_HXX + +#include <rtl/ustring.hxx> + +class SvXMLAttr { +private: + sal_uInt16 aPrefixPos; + OUString aLName; + OUString aValue; +public: + // Assuming OUString is well behaved, the default copy constructor and + // assignment operator are fine. + SvXMLAttr( const OUString& rLName, + const OUString& rValue ); + SvXMLAttr( const sal_uInt16 nPos, + const OUString& rLName, + const OUString& rValue ); + bool operator== (const SvXMLAttr &rCmp) const; + + sal_uInt16 getPrefixPos() const { return aPrefixPos;} + const OUString& getLName() const { return aLName;} + const OUString& getValue() const { return aValue;} +}; + +#endif // INCLUDED_XMLOFF_SOURCE_CORE_SVXMLATTR_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/SvXMLAttrCollection.cxx b/xmloff/source/core/SvXMLAttrCollection.cxx new file mode 100644 index 000000000..466008b9f --- /dev/null +++ b/xmloff/source/core/SvXMLAttrCollection.cxx @@ -0,0 +1,180 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "SvXMLAttrCollection.hxx" +#include <limits.h> +#include <osl/diagnose.h> + +bool SvXMLAttrCollection::operator ==( const SvXMLAttrCollection& rCmp ) const +{ + return (rCmp.aNamespaceMap == aNamespaceMap) && + (rCmp.aAttrs == aAttrs); +} + +bool SvXMLAttrCollection::AddAttr( const OUString& rLName, + const OUString& rValue ) +{ + assert(!rLName.isEmpty()); + aAttrs.emplace_back(rLName, rValue ); + return true; +} + +bool SvXMLAttrCollection::AddAttr( const OUString& rPrefix, + const OUString& rNamespace, + const OUString& rLName, + const OUString& rValue ) +{ + assert(!rPrefix.isEmpty()); + assert(!rNamespace.isEmpty()); + assert(!rLName.isEmpty()); + sal_uInt16 nPos = aNamespaceMap.Add( rPrefix, rNamespace ); + aAttrs.emplace_back(nPos, rLName, rValue ); + return true; +} + +bool SvXMLAttrCollection::AddAttr( const OUString& rPrefix, + const OUString& rLName, + const OUString& rValue ) +{ + assert(!rPrefix.isEmpty()); + assert(!rLName.isEmpty()); + sal_uInt16 nPos = aNamespaceMap.GetIndexByPrefix( rPrefix ); + if( USHRT_MAX == nPos ) + return false; + aAttrs.emplace_back(nPos, rLName, rValue ); + return true; +} + +bool SvXMLAttrCollection::SetAt( size_t i, + const OUString& rLName, + const OUString& rValue ) +{ + assert(!rLName.isEmpty()); + if( i >= GetAttrCount() ) + return false; + aAttrs[i] = SvXMLAttr(rLName, rValue); + return true; +} + +bool SvXMLAttrCollection::SetAt( size_t i, + const OUString& rPrefix, + const OUString& rNamespace, + const OUString& rLName, + const OUString& rValue ) +{ + assert(!rPrefix.isEmpty()); + assert(!rNamespace.isEmpty()); + assert(!rLName.isEmpty()); + if( i >= GetAttrCount() ) + return false; + + sal_uInt16 nPos = aNamespaceMap.Add( rPrefix, rNamespace ); + if( USHRT_MAX == nPos ) + return false; + + aAttrs[i] = SvXMLAttr(nPos, rLName, rValue); + return true; +} + +bool SvXMLAttrCollection::SetAt( size_t i, + const OUString& rPrefix, + const OUString& rLName, + const OUString& rValue ) +{ + assert(!rPrefix.isEmpty()); + assert(!rLName.isEmpty()); + if( i >= GetAttrCount() ) + return false; + + sal_uInt16 nPos = aNamespaceMap.GetIndexByPrefix( rPrefix ); + if( USHRT_MAX == nPos ) + return false; + + aAttrs[i] = SvXMLAttr(nPos, rLName, rValue); + return true; +} + +void SvXMLAttrCollection::Remove( size_t i ) +{ + if( i < GetAttrCount() ) + { + aAttrs.erase( aAttrs.begin() + i ); + } + else + { + OSL_FAIL( "illegal index" ); + } +} + +size_t SvXMLAttrCollection::GetAttrCount() const +{ + return aAttrs.size(); +} + +const OUString& SvXMLAttrCollection::GetAttrLName(size_t i) const +{ + OSL_ENSURE( i < aAttrs.size(), "SvXMLAttrContainerData::GetLName: illegal index" ); + return aAttrs[i].getLName(); +} + +const OUString& SvXMLAttrCollection::GetAttrValue(size_t i) const +{ + OSL_ENSURE( i < aAttrs.size(), "SvXMLAttrContainerData::GetValue: illegal index" ); + return aAttrs[i].getValue(); +} + +OUString SvXMLAttrCollection::GetAttrNamespace( size_t i ) const +{ + OUString sRet; + sal_uInt16 nPos = GetPrefixPos( i ); + //Does this point to a valid namespace entry? + if( USHRT_MAX != nPos ) + sRet = aNamespaceMap.GetNameByIndex( nPos ); + return sRet; +} + +OUString SvXMLAttrCollection::GetAttrPrefix( size_t i ) const +{ + OUString sRet; + sal_uInt16 nPos = GetPrefixPos( i ); + //Does this point to a valid namespace entry? + if( USHRT_MAX != nPos ) + sRet = aNamespaceMap.GetPrefixByIndex( nPos ); + return sRet; +} + +const OUString& SvXMLAttrCollection::GetNamespace( sal_uInt16 i ) const +{ + return aNamespaceMap.GetNameByIndex( i ); +} + +const OUString& SvXMLAttrCollection::GetPrefix( sal_uInt16 i ) const +{ + return aNamespaceMap.GetPrefixByIndex( i ); +} + +sal_uInt16 SvXMLAttrCollection::GetFirstNamespaceIndex() const +{ + return aNamespaceMap.GetFirstIndex(); +} + +sal_uInt16 SvXMLAttrCollection::GetNextNamespaceIndex( sal_uInt16 nIdx ) const +{ + return aNamespaceMap.GetNextIndex( nIdx ); +} + +sal_uInt16 SvXMLAttrCollection::GetPrefixPos( size_t i ) const +{ +// SAL_WARN_IF( i < 0 || i >= aAttrs.size()), "xmloff", +// "SvXMLAttrCollection::GetPrefixPos: illegal index" ); + return aAttrs[i].getPrefixPos(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ + diff --git a/xmloff/source/core/SvXMLAttrCollection.hxx b/xmloff/source/core/SvXMLAttrCollection.hxx new file mode 100644 index 000000000..e029491ce --- /dev/null +++ b/xmloff/source/core/SvXMLAttrCollection.hxx @@ -0,0 +1,69 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_XMLOFF_SOURCE_CORE_SVXMLATTRCOLLECTION_HXX +#define INCLUDED_XMLOFF_SOURCE_CORE_SVXMLATTRCOLLECTION_HXX + +#include "SvXMLAttr.hxx" + +#include <xmloff/nmspmap.hxx> +#include <rtl/ustring.hxx> +#include <sal/types.h> +#include <vector> + +class SvXMLAttrCollection +{ +public: + SvXMLNamespaceMap aNamespaceMap; + std::vector<SvXMLAttr> aAttrs; + + bool operator==(const SvXMLAttrCollection &rCmp) const; + bool AddAttr( const OUString& rLName, + const OUString& rValue ); + bool AddAttr( const OUString& rPrefix, + const OUString& rNamespace, + const OUString& rLName, + const OUString& rValue ); + bool AddAttr( const OUString& rPrefix, + const OUString& rLName, + const OUString& rValue ); + + bool SetAt( size_t i, + const OUString& rLName, + const OUString& rValue ); + bool SetAt( size_t i, + const OUString& rPrefix, + const OUString& rNamespace, + const OUString& rLName, + const OUString& rValue ); + bool SetAt( size_t i, + const OUString& rPrefix, + const OUString& rLName, + const OUString& rValue ); + + void Remove( size_t i ); + + size_t GetAttrCount() const; + const OUString& GetAttrLName(size_t i) const; + const OUString& GetAttrValue(size_t i) const; + OUString GetAttrNamespace( size_t i ) const; + OUString GetAttrPrefix( size_t i ) const; + const OUString& GetNamespace( sal_uInt16 i ) const; + const OUString& GetPrefix( sal_uInt16 i ) const; + sal_uInt16 GetFirstNamespaceIndex() const; + sal_uInt16 GetNextNamespaceIndex( sal_uInt16 nIdx ) const; + +private: + sal_uInt16 GetPrefixPos( size_t i ) const; +}; + +#endif // INCLUDED_XMLOFF_SOURCE_CORE_SVXMLATTRCOLLECTION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ + diff --git a/xmloff/source/core/XMLBase64Export.cxx b/xmloff/source/core/XMLBase64Export.cxx new file mode 100644 index 000000000..0aa2ff136 --- /dev/null +++ b/xmloff/source/core/XMLBase64Export.cxx @@ -0,0 +1,84 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <rtl/ustrbuf.hxx> + +#include <com/sun/star/io/XInputStream.hpp> + +#include <comphelper/base64.hxx> + +#include <xmloff/xmlexp.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <XMLBase64Export.hxx> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::io; + +#define INPUT_BUFFER_SIZE 54 +#define OUTPUT_BUFFER_SIZE 72 + +XMLBase64Export::XMLBase64Export( SvXMLExport& rExp ) : + rExport( rExp ){ +} + +bool XMLBase64Export::exportXML( const Reference < XInputStream> & rIn ) +{ + bool bRet = true; + try + { + Sequence < sal_Int8 > aInBuff( INPUT_BUFFER_SIZE ); + OUStringBuffer aOutBuff( OUTPUT_BUFFER_SIZE ); + sal_Int32 nRead; + do + { + nRead = rIn->readBytes( aInBuff, INPUT_BUFFER_SIZE ); + if( nRead > 0 ) + { + ::comphelper::Base64::encode( aOutBuff, aInBuff ); + GetExport().Characters( aOutBuff.makeStringAndClear() ); + if( nRead == INPUT_BUFFER_SIZE ) + GetExport().IgnorableWhitespace(); + } + } + while( nRead == INPUT_BUFFER_SIZE ); + } + catch( ... ) + { + bRet = false; + } + + return bRet; +} + +bool XMLBase64Export::exportElement( + const Reference < XInputStream > & rIn, + enum ::xmloff::token::XMLTokenEnum eName ) +{ + SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_OFFICE, eName, true, true ); + return exportXML( rIn ); +} + +bool XMLBase64Export::exportOfficeBinaryDataElement( + const Reference < XInputStream > & rIn ) +{ + return exportElement( rIn, ::xmloff::token::XML_BINARY_DATA ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/XMLBase64ImportContext.cxx b/xmloff/source/core/XMLBase64ImportContext.cxx new file mode 100644 index 000000000..4e46b8181 --- /dev/null +++ b/xmloff/source/core/XMLBase64ImportContext.cxx @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <com/sun/star/io/XOutputStream.hpp> + +#include <comphelper/base64.hxx> + +#include <xmloff/xmlimp.hxx> +#include <xmloff/XMLBase64ImportContext.hxx> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::xml::sax; +using namespace ::com::sun::star::io; + + +XMLBase64ImportContext::XMLBase64ImportContext( + SvXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName, + const Reference< XAttributeList >&, + const Reference< XOutputStream >& rOut ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + xOut( rOut ) +{ +} + +XMLBase64ImportContext::~XMLBase64ImportContext() +{ +} + +void XMLBase64ImportContext::EndElement() +{ + OUString sChars = maCharBuffer.makeStringAndClear().trim(); + if( !sChars.isEmpty() ) + { + Sequence< sal_Int8 > aBuffer( (sChars.getLength() / 4) * 3 ); + ::comphelper::Base64::decodeSomeChars( aBuffer, sChars ); + xOut->writeBytes( aBuffer ); + } + xOut->closeOutput(); +} + +void XMLBase64ImportContext::Characters( const OUString& rChars ) +{ + maCharBuffer.append(rChars); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/XMLBasicExportFilter.cxx b/xmloff/source/core/XMLBasicExportFilter.cxx new file mode 100644 index 000000000..6b9393819 --- /dev/null +++ b/xmloff/source/core/XMLBasicExportFilter.cxx @@ -0,0 +1,86 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <XMLBasicExportFilter.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +// XMLBasicExportFilter + +XMLBasicExportFilter::XMLBasicExportFilter( const Reference< xml::sax::XDocumentHandler >& rxHandler ) + :m_xHandler( rxHandler ) +{ +} + +XMLBasicExportFilter::~XMLBasicExportFilter() +{ +} + +// XDocumentHandler + +void XMLBasicExportFilter::startDocument() +{ + // do nothing, filter this +} + +void XMLBasicExportFilter::endDocument() +{ + // do nothing, filter this +} + +void XMLBasicExportFilter::startElement( const OUString& aName, + const Reference< xml::sax::XAttributeList >& xAttribs ) +{ + if ( m_xHandler.is() ) + m_xHandler->startElement( aName, xAttribs ); +} + +void XMLBasicExportFilter::endElement( const OUString& aName ) +{ + if ( m_xHandler.is() ) + m_xHandler->endElement( aName ); +} + +void XMLBasicExportFilter::characters( const OUString& aChars ) +{ + if ( m_xHandler.is() ) + m_xHandler->characters( aChars ); +} + +void XMLBasicExportFilter::ignorableWhitespace( const OUString& aWhitespaces ) +{ + if ( m_xHandler.is() ) + m_xHandler->ignorableWhitespace( aWhitespaces ); +} + +void XMLBasicExportFilter::processingInstruction( const OUString& aTarget, + const OUString& aData ) +{ + if ( m_xHandler.is() ) + m_xHandler->processingInstruction( aTarget, aData ); +} + +void XMLBasicExportFilter::setDocumentLocator( const Reference< xml::sax::XLocator >& xLocator ) +{ + if ( m_xHandler.is() ) + m_xHandler->setDocumentLocator( xLocator ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/XMLEmbeddedObjectExportFilter.cxx b/xmloff/source/core/XMLEmbeddedObjectExportFilter.cxx new file mode 100644 index 000000000..e89c192a0 --- /dev/null +++ b/xmloff/source/core/XMLEmbeddedObjectExportFilter.cxx @@ -0,0 +1,147 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <XMLEmbeddedObjectExportFilter.hxx> +#include <cppuhelper/supportsservice.hxx> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::xml::sax; + + +XMLEmbeddedObjectExportFilter::XMLEmbeddedObjectExportFilter( + const Reference< XDocumentHandler > & rHandler ) throw() : + xHandler( rHandler ), + xExtHandler( rHandler, UNO_QUERY ) +{ +} + +XMLEmbeddedObjectExportFilter::~XMLEmbeddedObjectExportFilter () throw() +{ +} + +void SAL_CALL XMLEmbeddedObjectExportFilter::startDocument() +{ + // do nothing, filter this +} + +void SAL_CALL XMLEmbeddedObjectExportFilter::endDocument() +{ + // do nothing, filter this +} + +void SAL_CALL XMLEmbeddedObjectExportFilter::startElement( + const OUString& rName, + const Reference< XAttributeList >& xAttrList ) +{ + xHandler->startElement( rName, xAttrList ); +} + +void SAL_CALL XMLEmbeddedObjectExportFilter::endElement( const OUString& rName ) +{ + xHandler->endElement( rName ); +} + +void SAL_CALL XMLEmbeddedObjectExportFilter::characters( const OUString& rChars ) +{ + xHandler->characters( rChars ); +} + +void SAL_CALL XMLEmbeddedObjectExportFilter::ignorableWhitespace( + const OUString& rWhitespaces ) +{ + xHandler->ignorableWhitespace( rWhitespaces ); +} + +void SAL_CALL XMLEmbeddedObjectExportFilter::processingInstruction( + const OUString& rTarget, + const OUString& rData ) +{ + xHandler->processingInstruction( rTarget, rData ); +} + +void SAL_CALL XMLEmbeddedObjectExportFilter::setDocumentLocator( + const Reference< XLocator >& rLocator ) +{ + xHandler->setDocumentLocator( rLocator ); +} + +// XExtendedDocumentHandler +void SAL_CALL XMLEmbeddedObjectExportFilter::startCDATA() +{ + if( xExtHandler.is() ) + xExtHandler->startCDATA(); +} + +void SAL_CALL XMLEmbeddedObjectExportFilter::endCDATA() +{ + if( xExtHandler.is() ) + xExtHandler->endCDATA(); +} + +void SAL_CALL XMLEmbeddedObjectExportFilter::comment( const OUString& rComment ) +{ + if( xExtHandler.is() ) + xExtHandler->comment( rComment ); +} + +void SAL_CALL XMLEmbeddedObjectExportFilter::allowLineBreak() +{ + if( xExtHandler.is() ) + xExtHandler->allowLineBreak(); +} + +void SAL_CALL XMLEmbeddedObjectExportFilter::unknown( const OUString& rString ) +{ + if( xExtHandler.is() ) + xExtHandler->unknown( rString ); +} + +// XInitialize +void SAL_CALL XMLEmbeddedObjectExportFilter::initialize( + const Sequence< Any >& aArguments ) +{ + for( const auto& rAny : aArguments ) + { + if( rAny.getValueType() == + cppu::UnoType<XDocumentHandler>::get()) + { + rAny >>= xHandler; + rAny >>= xExtHandler; + } + } +} + +// XServiceInfo +OUString SAL_CALL XMLEmbeddedObjectExportFilter::getImplementationName() +{ + return OUString(); +} + +sal_Bool SAL_CALL XMLEmbeddedObjectExportFilter::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService(this, ServiceName); +} + +Sequence< OUString > SAL_CALL XMLEmbeddedObjectExportFilter::getSupportedServiceNames( ) +{ + Sequence< OUString > aSeq; + return aSeq; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/XMLEmbeddedObjectImportContext.cxx b/xmloff/source/core/XMLEmbeddedObjectImportContext.cxx new file mode 100644 index 000000000..abb6601cb --- /dev/null +++ b/xmloff/source/core/XMLEmbeddedObjectImportContext.cxx @@ -0,0 +1,293 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <com/sun/star/document/XImporter.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/util/XModifiable2.hpp> +#include <tools/globname.hxx> +#include <comphelper/classids.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmlimp.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/attrlist.hxx> +#include <xmloff/XMLFilterServiceNames.h> +#include <XMLEmbeddedObjectImportContext.hxx> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::document; +using namespace ::com::sun::star::xml::sax; +using namespace ::xmloff::token; + +namespace { + +class XMLEmbeddedObjectImportContext_Impl : public SvXMLImportContext +{ + css::uno::Reference< css::xml::sax::XDocumentHandler > xHandler; + +public: + + XMLEmbeddedObjectImportContext_Impl( SvXMLImport& rImport, sal_uInt16 nPrfx, + const OUString& rLName, + const css::uno::Reference< css::xml::sax::XDocumentHandler >& rHandler ); + + virtual SvXMLImportContextRef CreateChildContext( sal_uInt16 nPrefix, + const OUString& rLocalName, + const css::uno::Reference< css::xml::sax::XAttributeList >& xAttrList ) override; + + virtual void StartElement( const css::uno::Reference< css::xml::sax::XAttributeList >& xAttrList ) override; + + virtual void EndElement() override; + + virtual void Characters( const OUString& rChars ) override; +}; + +} + +XMLEmbeddedObjectImportContext_Impl::XMLEmbeddedObjectImportContext_Impl( + SvXMLImport& rImport, sal_uInt16 nPrfx, + const OUString& rLName, + const Reference< XDocumentHandler >& rHandler ) : + SvXMLImportContext( rImport, nPrfx, rLName ), + xHandler( rHandler ) +{ +} + +SvXMLImportContextRef XMLEmbeddedObjectImportContext_Impl::CreateChildContext( + sal_uInt16 nPrefix, + const OUString& rLocalName, + const Reference< XAttributeList >& ) +{ + return new XMLEmbeddedObjectImportContext_Impl( GetImport(), + nPrefix, rLocalName, + xHandler ); +} + +void XMLEmbeddedObjectImportContext_Impl::StartElement( + const Reference< XAttributeList >& xAttrList ) +{ + xHandler->startElement( GetImport().GetNamespaceMap().GetQNameByKey( + GetPrefix(), GetLocalName() ), + xAttrList ); +} + +void XMLEmbeddedObjectImportContext_Impl::EndElement() +{ + xHandler->endElement( GetImport().GetNamespaceMap().GetQNameByKey( + GetPrefix(), GetLocalName() ) ); +} + +void XMLEmbeddedObjectImportContext_Impl::Characters( const OUString& rChars ) +{ + xHandler->characters( rChars ); +} + + +void XMLEmbeddedObjectImportContext::SetComponent( Reference< XComponent > const & rComp ) +{ + if( !rComp.is() || sFilterService.isEmpty() ) + return; + + Sequence<Any> aArgs( 0 ); + + Reference< XComponentContext > xContext( GetImport().GetComponentContext() ); + + xHandler.set( + xContext->getServiceManager()->createInstanceWithArgumentsAndContext(sFilterService, aArgs, xContext), + UNO_QUERY); + + if( !xHandler.is() ) + return; + + if (SvXMLImport *pFastHandler = dynamic_cast<SvXMLImport*>(xHandler.get())) + xHandler.set( new SvXMLLegacyToFastDocHandler( pFastHandler ) ); + + try + { + Reference < XModifiable2 > xModifiable2( rComp, UNO_QUERY_THROW ); + xModifiable2->disableSetModified(); + } + catch( Exception& ) + { + } + + Reference < XImporter > xImporter( xHandler, UNO_QUERY ); + xImporter->setTargetDocument( rComp ); + + xComp = rComp; // keep ref to component only if there is a handler +} + +XMLEmbeddedObjectImportContext::XMLEmbeddedObjectImportContext( + SvXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName, + const Reference< XAttributeList >& xAttrList ) : + SvXMLImportContext( rImport, nPrfx, rLName ) +{ + SvGlobalName aName; + + if( nPrfx == XML_NAMESPACE_MATH && + IsXMLToken( rLName, XML_MATH ) ) + { + sFilterService = XML_IMPORT_FILTER_MATH; + aName = SvGlobalName(SO3_SM_CLASSID); + } + else if( nPrfx == XML_NAMESPACE_OFFICE && + IsXMLToken( rLName, XML_DOCUMENT ) ) + { + OUString sMime; + + 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 ); + if( nPrefix == XML_NAMESPACE_OFFICE && + IsXMLToken( aLocalName, XML_MIMETYPE ) ) + { + sMime = xAttrList->getValueByIndex( i ); + break; + } + } + + OUString sClass; + static OUStringLiteral const prefixes[] = { + "application/vnd.oasis.openoffice.", + "application/x-vnd.oasis.openoffice.", + "application/vnd.oasis.opendocument.", + "application/x-vnd.oasis.opendocument."}; + for (auto const & p: prefixes) + { + if (sMime.startsWith(p, &sClass)) + { + break; + } + } + + if( !sClass.isEmpty() ) + { + static struct { XMLTokenEnum eClass; OUStringLiteral sFilterService; + } const aServiceMap[] = { + { XML_TEXT, OUStringLiteral(XML_IMPORT_FILTER_WRITER) }, + { XML_ONLINE_TEXT, OUStringLiteral(XML_IMPORT_FILTER_WRITER) }, + { XML_SPREADSHEET, OUStringLiteral(XML_IMPORT_FILTER_CALC) }, + { XML_DRAWING, OUStringLiteral(XML_IMPORT_FILTER_DRAW) }, + { XML_GRAPHICS, OUStringLiteral(XML_IMPORT_FILTER_DRAW) }, + { XML_PRESENTATION, OUStringLiteral(XML_IMPORT_FILTER_IMPRESS) }, + { XML_CHART, OUStringLiteral(XML_IMPORT_FILTER_CHART) }}; + for (auto const & entry: aServiceMap) + { + if( IsXMLToken( sClass, entry.eClass ) ) + { + sFilterService = entry.sFilterService; + + switch( entry.eClass ) + { + case XML_TEXT: aName = SvGlobalName(SO3_SW_CLASSID); break; + case XML_ONLINE_TEXT: aName = SvGlobalName(SO3_SWWEB_CLASSID); break; + case XML_SPREADSHEET: aName = SvGlobalName(SO3_SC_CLASSID); break; + case XML_DRAWING: + case XML_GRAPHICS: + case XML_IMAGE: aName = SvGlobalName(SO3_SDRAW_CLASSID); break; + case XML_PRESENTATION: aName = SvGlobalName(SO3_SIMPRESS_CLASSID); break; + case XML_CHART: aName = SvGlobalName(SO3_SCH_CLASSID); break; + default: + break; + } + + break; + } + } + } + } + + sCLSID = aName.GetHexName(); +} + +XMLEmbeddedObjectImportContext::~XMLEmbeddedObjectImportContext() +{ +} + +SvXMLImportContextRef XMLEmbeddedObjectImportContext::CreateChildContext( + sal_uInt16 nPrefix, const OUString& rLocalName, + const Reference< XAttributeList >& ) +{ + if( xHandler.is() ) + return new XMLEmbeddedObjectImportContext_Impl( GetImport(), + nPrefix, rLocalName, + xHandler ); + return nullptr; +} + +void XMLEmbeddedObjectImportContext::StartElement( + const Reference< XAttributeList >& rAttrList ) +{ + if( xHandler.is() ) + { + xHandler->startDocument(); + // #i34042: copy namepspace declarations + SvXMLAttributeList *pAttrList = new SvXMLAttributeList( rAttrList ); + Reference< XAttributeList > xAttrList( pAttrList ); + const SvXMLNamespaceMap& rNamespaceMap = GetImport().GetNamespaceMap(); + sal_uInt16 nPos = rNamespaceMap.GetFirstKey(); + while( USHRT_MAX != nPos ) + { + OUString aAttrName( rNamespaceMap.GetAttrNameByKey( nPos ) ); + if( xAttrList->getValueByName( aAttrName ).isEmpty() ) + { + pAttrList->AddAttribute( aAttrName, + rNamespaceMap.GetNameByKey( nPos ) ); + } + nPos = rNamespaceMap.GetNextKey( nPos ); + } + xHandler->startElement( GetImport().GetNamespaceMap().GetQNameByKey( + GetPrefix(), GetLocalName() ), + xAttrList ); + } +} + +void XMLEmbeddedObjectImportContext::EndElement() +{ + if( xHandler.is() ) + { + xHandler->endElement( GetImport().GetNamespaceMap().GetQNameByKey( + GetPrefix(), GetLocalName() ) ); + xHandler->endDocument(); + + try + { + Reference < XModifiable2 > xModifiable2( xComp, UNO_QUERY_THROW ); + xModifiable2->enableSetModified(); + xModifiable2->setModified( true ); // trigger new replacement image generation + } + catch( Exception& ) + { + } + } +} + +void XMLEmbeddedObjectImportContext::Characters( const OUString& rChars ) +{ + if( xHandler.is() ) + xHandler->characters( rChars ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/attrlist.cxx b/xmloff/source/core/attrlist.cxx new file mode 100644 index 000000000..c65b9a3cb --- /dev/null +++ b/xmloff/source/core/attrlist.cxx @@ -0,0 +1,225 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <vector> + +#include <o3tl/safeint.hxx> +#include <osl/diagnose.h> +#include <xmloff/xmltoken.hxx> +#include <cppuhelper/implbase.hxx> + +#include <xmloff/attrlist.hxx> + + +using namespace ::com::sun::star; +using namespace ::xmloff::token; + +namespace { + +struct SvXMLTagAttribute_Impl +{ + SvXMLTagAttribute_Impl( const OUString &rName, + const OUString &rValue ) + : sName(rName), + sValue(rValue) + { + } + + OUString sName; + OUString sValue; +}; + +} + +struct SvXMLAttributeList_Impl +{ + SvXMLAttributeList_Impl() + { + // performance improvement during adding + vecAttribute.reserve(20); + } + + ::std::vector<struct SvXMLTagAttribute_Impl> vecAttribute; + typedef ::std::vector<struct SvXMLTagAttribute_Impl>::size_type size_type; +}; + + +sal_Int16 SAL_CALL SvXMLAttributeList::getLength() +{ + return sal::static_int_cast< sal_Int16 >(m_pImpl->vecAttribute.size()); +} + + +SvXMLAttributeList::SvXMLAttributeList( const SvXMLAttributeList &r ) : + cppu::WeakImplHelper<css::xml::sax::XAttributeList, css::util::XCloneable, css::lang::XUnoTunnel>(r), + m_pImpl( new SvXMLAttributeList_Impl( *r.m_pImpl ) ) +{ +} + +SvXMLAttributeList::SvXMLAttributeList( const uno::Reference< + xml::sax::XAttributeList> & rAttrList ) + : m_pImpl( new SvXMLAttributeList_Impl), + sType( GetXMLToken(XML_CDATA) ) +{ + + SvXMLAttributeList* pImpl = + comphelper::getUnoTunnelImplementation<SvXMLAttributeList>( rAttrList ); + + if( pImpl ) + *m_pImpl = *(pImpl->m_pImpl); + else + AppendAttributeList( rAttrList ); +} + +OUString SAL_CALL SvXMLAttributeList::getNameByIndex(sal_Int16 i) +{ + return ( o3tl::make_unsigned( i ) < m_pImpl->vecAttribute.size() ) ? m_pImpl->vecAttribute[i].sName : OUString(); +} + + +OUString SAL_CALL SvXMLAttributeList::getTypeByIndex(sal_Int16) +{ + return sType; +} + +OUString SAL_CALL SvXMLAttributeList::getValueByIndex(sal_Int16 i) +{ + return ( o3tl::make_unsigned( i ) < m_pImpl->vecAttribute.size() ) ? m_pImpl->vecAttribute[i].sValue : OUString(); +} + +OUString SAL_CALL SvXMLAttributeList::getTypeByName( const OUString& ) +{ + return sType; +} + +OUString SAL_CALL SvXMLAttributeList::getValueByName(const OUString& sName) +{ + auto ii = std::find_if(m_pImpl->vecAttribute.begin(), m_pImpl->vecAttribute.end(), + [&sName](struct SvXMLTagAttribute_Impl& rAttr) { return rAttr.sName == sName; }); + + if (ii != m_pImpl->vecAttribute.end()) + return (*ii).sValue; + + return OUString(); +} + + +uno::Reference< css::util::XCloneable > SvXMLAttributeList::createClone() +{ + uno::Reference< css::util::XCloneable > r = new SvXMLAttributeList( *this ); + return r; +} + + +SvXMLAttributeList::SvXMLAttributeList() + : m_pImpl( new SvXMLAttributeList_Impl ), + sType( GetXMLToken(XML_CDATA) ) +{ +} + + +SvXMLAttributeList::~SvXMLAttributeList() +{ +} + + +void SvXMLAttributeList::AddAttribute( const OUString &sName , + const OUString &sValue ) +{ + m_pImpl->vecAttribute.emplace_back( sName , sValue ); +} + +void SvXMLAttributeList::Clear() +{ + m_pImpl->vecAttribute.clear(); + + OSL_ASSERT( ! getLength() ); +} + +void SvXMLAttributeList::RemoveAttribute( const OUString& sName ) +{ + auto ii = std::find_if(m_pImpl->vecAttribute.begin(), m_pImpl->vecAttribute.end(), + [&sName](struct SvXMLTagAttribute_Impl& rAttr) { return rAttr.sName == sName; }); + + if (ii != m_pImpl->vecAttribute.end()) + m_pImpl->vecAttribute.erase( ii ); +} + +void SvXMLAttributeList::AppendAttributeList( const uno::Reference< css::xml::sax::XAttributeList > &r ) +{ + OSL_ASSERT( r.is() ); + + sal_Int16 nMax = r->getLength(); + SvXMLAttributeList_Impl::size_type nTotalSize = + m_pImpl->vecAttribute.size() + nMax; + m_pImpl->vecAttribute.reserve( nTotalSize ); + + for( sal_Int16 i = 0 ; i < nMax ; ++i ) { + m_pImpl->vecAttribute.emplace_back( + r->getNameByIndex( i ) , + r->getValueByIndex( i )); + } + + OSL_ASSERT( nTotalSize == static_cast<SvXMLAttributeList_Impl::size_type>(getLength())); +} + +void SvXMLAttributeList::SetValueByIndex( sal_Int16 i, + const OUString& rValue ) +{ + if( o3tl::make_unsigned( i ) + < m_pImpl->vecAttribute.size() ) + { + m_pImpl->vecAttribute[i].sValue = rValue; + } +} + +void SvXMLAttributeList::RemoveAttributeByIndex( sal_Int16 i ) +{ + if( o3tl::make_unsigned( i ) + < m_pImpl->vecAttribute.size() ) + m_pImpl->vecAttribute.erase( m_pImpl->vecAttribute.begin() + i ); +} + +void SvXMLAttributeList::RenameAttributeByIndex( sal_Int16 i, + const OUString& rNewName ) +{ + if( o3tl::make_unsigned( i ) + < m_pImpl->vecAttribute.size() ) + { + m_pImpl->vecAttribute[i].sName = rNewName; + } +} + +sal_Int16 SvXMLAttributeList::GetIndexByName( const OUString& rName ) const +{ + auto ii = std::find_if(m_pImpl->vecAttribute.begin(), m_pImpl->vecAttribute.end(), + [&rName](struct SvXMLTagAttribute_Impl& rAttr) { return rAttr.sName == rName; }); + + if (ii != m_pImpl->vecAttribute.end()) + return static_cast<sal_Int16>(std::distance(m_pImpl->vecAttribute.begin(), ii)); + + return -1; +} + +// XUnoTunnel & co +UNO3_GETIMPLEMENTATION_IMPL(SvXMLAttributeList) + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/facreg.cxx b/xmloff/source/core/facreg.cxx new file mode 100644 index 000000000..52c719d30 --- /dev/null +++ b/xmloff/source/core/facreg.cxx @@ -0,0 +1,73 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <sal/config.h> + +#include <xmloff/dllapi.h> + +#include <string.h> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> + +#include <cppuhelper/factory.hxx> + +#include <facreg.hxx> + +using namespace com::sun::star; + +extern "C" +{ + +#define SINGLEFACTORY(classname)\ + if( classname##_getImplementationName().equalsAsciiL( pImplName, nImplNameLen ) )\ + {\ + xFactory = ::cppu::createSingleFactory( xMSF,\ + classname##_getImplementationName(),\ + classname##_createInstance,\ + classname##_getSupportedServiceNames() );\ + } + +XMLOFF_DLLPUBLIC void * xo_component_getFactory( const char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ ) +{ + void * pRet = nullptr; + if( pServiceManager ) + { + uno::Reference< lang::XMultiServiceFactory > xMSF( static_cast< lang::XMultiServiceFactory * >( pServiceManager ) ); + + uno::Reference< lang::XSingleServiceFactory > xFactory; + + const sal_Int32 nImplNameLen = strlen( pImplName ); + + // auto text import/export + SINGLEFACTORY( XMLAutoTextEventExport ) + else SINGLEFACTORY( XMLAutoTextEventImport ) + else SINGLEFACTORY( XMLAutoTextEventExportOOO ) + + if( xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + return pRet; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/fasttokenhandler.cxx b/xmloff/source/core/fasttokenhandler.cxx new file mode 100644 index 000000000..8d63cb74f --- /dev/null +++ b/xmloff/source/core/fasttokenhandler.cxx @@ -0,0 +1,104 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <fasttokenhandler.hxx> + +#include <xmloff/token/tokens.hxx> + +namespace xmloff { + +namespace { +// include auto-generated Perfect_Hash +#if defined __clang__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +#if __has_warning("-Wdeprecated-register") +#pragma GCC diagnostic ignored "-Wdeprecated-register" +#endif +#endif +#include <tokenhash.inc> +#if defined __clang__ +#pragma GCC diagnostic pop +#endif +} // namespace + +namespace token { + +using namespace css; + +const css::uno::Sequence< sal_Int8 > TokenMap::EMPTY_BYTE_SEQ; +const OUString TokenMap::EMPTY_STRING; + +TokenMap::TokenMap() : + maTokenNamesUtf8( static_cast< size_t >( XML_TOKEN_COUNT ) ), + maTokenNames( static_cast< size_t >( XML_TOKEN_COUNT ) ) +{ + static const char* sppcTokenNames[] = + { +#include <tokennames.inc> + "" + }; + + const char* const* ppcTokenName = sppcTokenNames; + int i = 0; + for( auto& rTokenName : maTokenNamesUtf8 ) + { + OString aUtf8Token( *ppcTokenName ); + rTokenName = uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( + aUtf8Token.getStr() ), aUtf8Token.getLength() ); + maTokenNames[i++] = OUString( aUtf8Token.getStr(), aUtf8Token.getLength(), RTL_TEXTENCODING_UTF8 ); + ++ppcTokenName; + } +} + +TokenMap::~TokenMap() +{ +} + +sal_Int32 TokenMap::getTokenPerfectHash( const char *pStr, sal_Int32 nLength ) +{ + const struct xmltoken *pToken = Perfect_Hash::in_word_set( pStr, nLength ); + return pToken ? pToken->nToken : xmloff::XML_TOKEN_INVALID; +} + +FastTokenHandler::FastTokenHandler() : + mrTokenMap( StaticTokenMap::get() ) +{ +} + +FastTokenHandler::~FastTokenHandler() +{ +} + +// XFastTokenHandler +uno::Sequence< sal_Int8 > FastTokenHandler::getUTF8Identifier( sal_Int32 nToken ) +{ + return mrTokenMap.getUtf8TokenName( nToken ); +} + +const OUString& FastTokenHandler::getIdentifier( sal_Int32 nToken ) const +{ + return mrTokenMap.getTokenName( nToken ); +} + +sal_Int32 FastTokenHandler::getTokenFromUTF8( const uno::Sequence< sal_Int8 >& rIdentifier ) +{ + return TokenMap::getTokenFromUtf8( rIdentifier ); +} + +// Much faster direct C++ shortcut +sal_Int32 FastTokenHandler::getTokenDirect( const char* pToken, sal_Int32 nLength ) const +{ + return TokenMap::getTokenFromUTF8( pToken, nLength ); +} + +} // namespace token +} // namespace xmloff + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/i18nmap.cxx b/xmloff/source/core/i18nmap.cxx new file mode 100644 index 000000000..db760ca1d --- /dev/null +++ b/xmloff/source/core/i18nmap.cxx @@ -0,0 +1,41 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <rtl/ustring.hxx> +#include <sal/log.hxx> +#include <xmloff/i18nmap.hxx> + +void SvI18NMap::Add( sal_uInt16 nKind, const OUString& rName, + const OUString& rNewName ) +{ + SvI18NMapEntry_Key aKey(nKind, rName); + bool bIsNewInsertion = m_aMap.emplace(aKey, rNewName).second; + SAL_INFO_IF(!bIsNewInsertion, "xmloff.core", "SvI18NMap::Add: item with key \"" << rName << "\" registered already, likely invalid input file"); +} + +const OUString& SvI18NMap::Get( sal_uInt16 nKind, const OUString& rName ) const +{ + SvI18NMapEntry_Key aKey(nKind, rName); + SvI18NMap_Impl::const_iterator aI = m_aMap.find(aKey); + if (aI != m_aMap.end()) + return aI->second; + return rName; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/nmspmap.cxx b/xmloff/source/core/nmspmap.cxx new file mode 100644 index 000000000..2a2d106a6 --- /dev/null +++ b/xmloff/source/core/nmspmap.cxx @@ -0,0 +1,560 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <rtl/ustring.hxx> +#include <rtl/ustrbuf.hxx> +#include <sal/log.hxx> + +#include <xmloff/xmltoken.hxx> +#include <xmloff/nmspmap.hxx> + +#include <xmloff/xmlnmspe.hxx> + + +using namespace ::xmloff::token; + +/* The basic idea of this class is that we have two ways to search our + * data, by prefix and by key. We use an unordered_map for fast prefix + * searching and an STL map for fast key searching. + * + * The references to an 'Index' refer to an earlier implementation of the + * name space map and remain to support code which uses these interfaces. + * + * In this implementation, key and index should always be the same number. + * + * All references to Indices are now deprecated and the corresponding + * 'Key' methods should be used instead + * + * Martin 13/06/01 + */ + +static const OUString sEmpty; + +SvXMLNamespaceMap::SvXMLNamespaceMap() +: sXMLNS( GetXMLToken ( XML_XMLNS ) ) +{ +} + +SvXMLNamespaceMap::SvXMLNamespaceMap( const SvXMLNamespaceMap& rMap ) +: sXMLNS( GetXMLToken ( XML_XMLNS ) ) +{ + aNameHash = rMap.aNameHash; + aNameMap = rMap.aNameMap; +} + +SvXMLNamespaceMap& SvXMLNamespaceMap::operator=( const SvXMLNamespaceMap& rMap ) +{ + aNameHash = rMap.aNameHash; + aNameMap = rMap.aNameMap; + return *this; +} + +SvXMLNamespaceMap::~SvXMLNamespaceMap() +{ +} + +bool SvXMLNamespaceMap::operator ==( const SvXMLNamespaceMap& rCmp ) const +{ + return aNameHash == rCmp.aNameHash; +} + +sal_uInt16 SvXMLNamespaceMap::Add_( const OUString& rPrefix, const OUString &rName, sal_uInt16 nKey ) +{ + if( XML_NAMESPACE_UNKNOWN == nKey ) + { + // create a new unique key with UNKNOWN flag set + nKey = XML_NAMESPACE_UNKNOWN_FLAG; + do + { + NameSpaceMap::const_iterator aIter = aNameMap.find ( nKey ); + if( aIter == aNameMap.end() ) + break; + nKey++; + } + while ( true ); + } + ::rtl::Reference<NameSpaceEntry> pEntry(new NameSpaceEntry); + pEntry->sName = rName; + pEntry->nKey = nKey; + pEntry->sPrefix = rPrefix; + aNameHash[ rPrefix ] = pEntry; + aNameMap [ nKey ] = pEntry; + return nKey; +} + +sal_uInt16 SvXMLNamespaceMap::Add( const OUString& rPrefix, const OUString& rName, + sal_uInt16 nKey ) +{ + if( XML_NAMESPACE_UNKNOWN == nKey ) + nKey = GetKeyByName( rName ); + +#ifdef NDEBUG + if( XML_NAMESPACE_NONE == nKey ) + return USHRT_MAX; +#else + assert(XML_NAMESPACE_NONE != nKey); +#endif + + if ( aNameHash.find ( rPrefix ) == aNameHash.end() ) + nKey = Add_( rPrefix, rName, nKey ); + + return nKey; +} + +sal_uInt16 SvXMLNamespaceMap::AddIfKnown( const OUString& rPrefix, const OUString& rName ) +{ + sal_uInt16 nKey = GetKeyByName( rName ); + +#ifdef NDEBUG + if( XML_NAMESPACE_NONE == nKey ) + return XML_NAMESPACE_UNKNOWN; +#else + assert(nKey != XML_NAMESPACE_NONE); +#endif + + if( XML_NAMESPACE_UNKNOWN != nKey ) + { + NameSpaceHash::const_iterator aIter = aNameHash.find( rPrefix ); + if( aIter == aNameHash.end() || (*aIter).second->sName != rName ) + nKey = Add_( rPrefix, rName, nKey ); + } + + return nKey; +} + + +sal_uInt16 SvXMLNamespaceMap::GetKeyByPrefix( const OUString& rPrefix ) const +{ + NameSpaceHash::const_iterator aIter = aNameHash.find(rPrefix); + return (aIter != aNameHash.end()) ? (*aIter).second->nKey : USHRT_MAX; +} + +sal_uInt16 SvXMLNamespaceMap::GetKeyByName( const OUString& rName ) const +{ + sal_uInt16 nKey = XML_NAMESPACE_UNKNOWN; + auto aIter = std::find_if(aNameHash.cbegin(), aNameHash.cend(), + [&rName](const NameSpaceHash::value_type& rEntry) { return rEntry.second->sName == rName; }); + + if (aIter != aNameHash.cend()) + nKey = (*aIter).second->nKey; + + return nKey; +} + +const OUString& SvXMLNamespaceMap::GetPrefixByKey( sal_uInt16 nKey ) const +{ + NameSpaceMap::const_iterator aIter = aNameMap.find (nKey); + return (aIter != aNameMap.end()) ? (*aIter).second->sPrefix : sEmpty; +} + +const OUString& SvXMLNamespaceMap::GetNameByKey( sal_uInt16 nKey ) const +{ + NameSpaceMap::const_iterator aIter = aNameMap.find (nKey); + return (aIter != aNameMap.end()) ? (*aIter).second->sName : sEmpty; +} + +OUString SvXMLNamespaceMap::GetAttrNameByKey( sal_uInt16 nKey ) const +{ + NameSpaceMap::const_iterator aIter = aNameMap.find ( nKey ); + if (aIter == aNameMap.end()) + return OUString(); + + const OUString & prefix( (*aIter).second->sPrefix ); + if (prefix.isEmpty()) // default namespace + return sXMLNS; + + return sXMLNS + ":" + prefix; +} + +OUString SvXMLNamespaceMap::GetQNameByKey( sal_uInt16 nKey, + const OUString& rLocalName, + bool bCache) const +{ + // We always want to return at least the rLocalName... + + switch ( nKey ) + { + case XML_NAMESPACE_UNKNOWN: + // ...if it's a completely unknown namespace, assert and return the local name + SAL_WARN("xmloff.core", "unknown namespace, probable missing xmlns: declaration"); + [[fallthrough]]; + case XML_NAMESPACE_NONE: + // ...if there isn't one, return the local name + return rLocalName; + case XML_NAMESPACE_XMLNS: + { + // ...if it's in the xmlns namespace, make the prefix + // don't bother caching this, it rarely happens + OUStringBuffer sQName; + sQName.append ( sXMLNS ); + if (!rLocalName.isEmpty()) // not default namespace + { + sQName.append ( ':' ); + sQName.append ( rLocalName ); + } + return sQName.makeStringAndClear(); + } + case XML_NAMESPACE_XML: + { + // this namespace is reserved, and needs not to be declared + return GetXMLToken(XML_XML) + ":" + rLocalName; + } + default: + { + QNameCache::const_iterator aQCacheIter; + if (bCache) + aQCacheIter = aQNameCache.find ( QNamePair ( nKey, rLocalName ) ); + else + aQCacheIter = aQNameCache.end(); + if ( aQCacheIter != aQNameCache.end() ) + return (*aQCacheIter).second; + else + { + NameSpaceMap::const_iterator aIter = aNameMap.find ( nKey ); + if ( aIter != aNameMap.end() ) + { + // ...if it's in our map, make the prefix + const OUString & prefix( (*aIter).second->sPrefix ); + OUStringBuffer sQName(prefix.getLength() + 1 + rLocalName.getLength()); + if (!prefix.isEmpty()) // not default namespace + { + sQName.append( prefix ); + sQName.append( ':' ); + } + sQName.append ( rLocalName ); + if (bCache) + { + OUString sString(sQName.makeStringAndClear()); + aQNameCache.emplace(QNamePair(nKey, rLocalName), sString); + return sString; + } + else + return sQName.makeStringAndClear(); + } + else + { + // ... if it isn't, this is a Bad Thing, assert and return the local name + assert(false); + return rLocalName; + } + } + } + } +} + +sal_uInt16 SvXMLNamespaceMap::GetKeyByAttrValueQName( + const OUString& rAttrValue, + OUString *pLocalName) const +{ + return GetKeyByQName(rAttrValue, nullptr, pLocalName, nullptr, QNameMode::AttrValue); +} + +/** + @param rQName either attribute name or qualified/namespaced attribute value + @param bCacheAttrName true: rQName is element or attribute name, cache it + false: rQName is attribute value, may contain extra ':', don't cache it + */ +sal_uInt16 SvXMLNamespaceMap::GetKeyByQName(const OUString& rQName, + OUString *pPrefix, + OUString *pLocalName, + OUString *pNamespace, + QNameMode const eMode) const +{ + sal_uInt16 nKey; + + NameSpaceHash::const_iterator it; + if (eMode == QNameMode::AttrNameCached) + it = aNameCache.find ( rQName ); + else + it = aNameCache.end(); + if ( it != aNameCache.end() ) + { + const NameSpaceEntry &rEntry = *((*it).second); + if ( pPrefix ) + *pPrefix = rEntry.sPrefix; + if ( pLocalName ) + *pLocalName = rEntry.sName; + nKey = rEntry.nKey; + if ( pNamespace ) + { + NameSpaceMap::const_iterator aMapIter = aNameMap.find (nKey); + *pNamespace = aMapIter != aNameMap.end() ? (*aMapIter).second->sName : OUString(); + } + } + else + { + OUString sEntryPrefix, sEntryName; + + sal_Int32 nColonPos = rQName.indexOf( ':' ); + if( -1 == nColonPos ) + { + // case: no ':' found -> default namespace + sEntryName = rQName; + } + else + { + // normal case: ':' found -> get prefix/suffix + sEntryPrefix = rQName.copy( 0L, nColonPos ); + sEntryName = rQName.copy( nColonPos + 1 ); + } + + if (eMode == QNameMode::AttrNameCached && sEntryName.indexOf(':') != -1) + { + SAL_INFO("xmloff", "invalid attribute name with multiple ':'"); + return XML_NAMESPACE_UNKNOWN; + } + + if( pPrefix ) + *pPrefix = sEntryPrefix; + if( pLocalName ) + *pLocalName = sEntryName; + + NameSpaceHash::const_iterator aIter = aNameHash.find( sEntryPrefix ); + if ( aIter != aNameHash.end() ) + { + // found: retrieve namespace key + nKey = (*aIter).second->nKey; + if ( pNamespace ) + *pNamespace = (*aIter).second->sName; + } + else if ( sEntryPrefix == sXMLNS ) + // not found, but xmlns prefix: return xmlns 'namespace' + nKey = XML_NAMESPACE_XMLNS; + else if( nColonPos == -1 ) + // not found, and no namespace: 'namespace' none + nKey = XML_NAMESPACE_NONE; + else + nKey = XML_NAMESPACE_UNKNOWN; + + if (eMode == QNameMode::AttrNameCached) + { + rtl::Reference<NameSpaceEntry> xEntry(new NameSpaceEntry); + xEntry->sPrefix = std::move(sEntryPrefix); + xEntry->sName = std::move(sEntryName); + xEntry->nKey = std::move(nKey); + aNameCache.emplace(rQName, std::move(xEntry)); + } + } + + return nKey; +} + +sal_uInt16 SvXMLNamespaceMap::GetFirstKey() const +{ + return aNameMap.empty() ? USHRT_MAX : (*aNameMap.begin()).second->nKey; +} + +sal_uInt16 SvXMLNamespaceMap::GetNextKey( sal_uInt16 nLastKey ) const +{ + NameSpaceMap::const_iterator aIter = aNameMap.find ( nLastKey ); + return (++aIter == aNameMap.end()) ? USHRT_MAX : (*aIter).second->nKey; +} + + +// All methods after this are deprecated... + +sal_uInt16 SvXMLNamespaceMap::GetIndexByKey( sal_uInt16 nKey ) +{ + return nKey; +} +sal_uInt16 SvXMLNamespaceMap::GetFirstIndex() const +{ + return aNameMap.empty() ? USHRT_MAX : (*aNameMap.begin()).second->nKey; +} + +sal_uInt16 SvXMLNamespaceMap::GetNextIndex( sal_uInt16 nOldIdx ) const +{ + NameSpaceMap::const_iterator aIter = aNameMap.find ( nOldIdx ); + return (++aIter == aNameMap.end()) ? USHRT_MAX : (*aIter).second->nKey; +} + +void SvXMLNamespaceMap::AddAtIndex( const OUString& rPrefix, + const OUString& rName, sal_uInt16 nKey ) +{ + if( XML_NAMESPACE_UNKNOWN == nKey ) + nKey = GetKeyByName( rName ); + + assert(XML_NAMESPACE_NONE != nKey); + if( XML_NAMESPACE_NONE != nKey && ! ( aNameHash.count ( rPrefix ) ) ) + { + Add_( rPrefix, rName, nKey ); + } +} + +OUString SvXMLNamespaceMap::GetAttrNameByIndex( sal_uInt16 nIdx ) const +{ + return GetAttrNameByKey( nIdx ); +} + +OUString SvXMLNamespaceMap::GetQNameByIndex( sal_uInt16 nIdx, + const OUString& rLocalName ) const +{ + return GetQNameByKey( nIdx, rLocalName ); +} + +const OUString& SvXMLNamespaceMap::GetPrefixByIndex( sal_uInt16 nIdx ) const +{ + NameSpaceMap::const_iterator aIter = aNameMap.find (nIdx); + return (aIter != aNameMap.end()) ? (*aIter).second->sPrefix : sEmpty; +} + +const OUString& SvXMLNamespaceMap::GetNameByIndex( sal_uInt16 nIdx ) const +{ + NameSpaceMap::const_iterator aIter = aNameMap.find (nIdx); + return (aIter != aNameMap.end()) ? (*aIter).second->sName : sEmpty; +} + +sal_uInt16 SvXMLNamespaceMap::GetIndexByPrefix( const OUString& rPrefix ) const +{ + NameSpaceHash::const_iterator aIter = aNameHash.find(rPrefix); + return (aIter != aNameHash.end()) ? (*aIter).second->nKey : USHRT_MAX; +} +sal_uInt16 SvXMLNamespaceMap::GetKeyByAttrName( + const OUString& rAttrName, + OUString *pLocalName) const +{ + return GetKeyByQName(rAttrName, nullptr, pLocalName, nullptr, QNameMode::AttrNameCached); +} + +sal_uInt16 SvXMLNamespaceMap::GetKeyByAttrName( const OUString& rAttrName, + OUString *pPrefix, + OUString *pLocalName, + OUString *pNamespace ) const +{ + return GetKeyByQName(rAttrName, pPrefix, pLocalName, pNamespace, QNameMode::AttrNameCached); +} + +bool SvXMLNamespaceMap::NormalizeURI( OUString& rName ) +{ + // try OASIS + W3 URI normalization + bool bSuccess = NormalizeOasisURN( rName ); + if( ! bSuccess ) + bSuccess = NormalizeW3URI( rName ); + return bSuccess; +} + +bool SvXMLNamespaceMap::NormalizeW3URI( OUString& rName ) +{ + // check if URI matches: + // http://www.w3.org/[0-9]*/[:letter:]* + // (year)/(WG name) + // For the following WG/standards names: + // - xforms + + bool bSuccess = false; + const OUString& sURIPrefix = GetXMLToken( XML_URI_W3_PREFIX ); + if( rName.startsWith( sURIPrefix ) ) + { + const OUString& sURISuffix = GetXMLToken( XML_URI_XFORMS_SUFFIX ); + sal_Int32 nCompareFrom = rName.getLength() - sURISuffix.getLength(); + if( rName.copy( nCompareFrom ) == sURISuffix ) + { + // found W3 prefix, and xforms suffix + rName = GetXMLToken( XML_N_XFORMS_1_0 ); + bSuccess = true; + } + } + return bSuccess; +} + +bool SvXMLNamespaceMap::NormalizeOasisURN( OUString& rName ) +{ + // #i38644# + // we exported the wrong namespace for smil, so we correct this here on load + // for older documents + if( IsXMLToken( rName, ::xmloff::token::XML_N_SVG ) ) + { + rName = GetXMLToken( ::xmloff::token::XML_N_SVG_COMPAT ); + return true; + } + else if( IsXMLToken( rName, ::xmloff::token::XML_N_FO ) ) + { + rName = GetXMLToken( ::xmloff::token::XML_N_FO_COMPAT ); + return true; + } + else if( IsXMLToken( rName, ::xmloff::token::XML_N_SMIL ) || + IsXMLToken( rName, ::xmloff::token::XML_N_SMIL_OLD ) ) + { + rName = GetXMLToken( ::xmloff::token::XML_N_SMIL_COMPAT ); + return true; + } + + + // Check if URN matches + // :urn:oasis:names:tc:[^:]*:xmlns:[^:]*:1.[^:]* + // |---| |---| |-----| + // TC-Id Sub-Id Version + + sal_Int32 nNameLen = rName.getLength(); + // :urn:oasis:names:tc.* + const OUString& rOasisURN = GetXMLToken( XML_URN_OASIS_NAMES_TC ); + if( !rName.startsWith( rOasisURN ) ) + return false; + + // :urn:oasis:names:tc:.* + sal_Int32 nPos = rOasisURN.getLength(); + if( nPos >= nNameLen || rName[nPos] != ':' ) + return false; + + // :urn:oasis:names:tc:[^:]:.* + sal_Int32 nTCIdStart = nPos+1; + sal_Int32 nTCIdEnd = rName.indexOf( ':', nTCIdStart ); + if( -1 == nTCIdEnd ) + return false; + + // :urn:oasis:names:tc:[^:]:xmlns.* + nPos = nTCIdEnd + 1; + OUString sTmp( rName.copy( nPos ) ); + const OUString& rXMLNS = GetXMLToken( XML_XMLNS ); + if( !sTmp.startsWith( rXMLNS ) ) + return false; + + // :urn:oasis:names:tc:[^:]:xmlns:.* + nPos += rXMLNS.getLength(); + if( nPos >= nNameLen || rName[nPos] != ':' ) + return false; + + // :urn:oasis:names:tc:[^:]:xmlns:[^:]*:.* + nPos = rName.indexOf( ':', nPos+1 ); + if( -1 == nPos ) + return false; + + // :urn:oasis:names:tc:[^:]:xmlns:[^:]*:[^:][^:][^:][^:]* + sal_Int32 nVersionStart = nPos+1; + if( nVersionStart+2 >= nNameLen || + -1 != rName.indexOf( ':', nVersionStart ) ) + return false; + + // :urn:oasis:names:tc:[^:]:xmlns:[^:]*:1\.[^:][^:]* + if( rName[nVersionStart] != '1' || rName[nVersionStart+1] != '.' ) + return false; + + // replace [tcid] with current TCID and version with current version. + + rName = rName.copy( 0, nTCIdStart ) + + GetXMLToken( XML_OPENDOCUMENT ) + + rName.copy( nTCIdEnd, nVersionStart-nTCIdEnd ) + + GetXMLToken( XML_1_0 ); + + return true; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/unoatrcn.cxx b/xmloff/source/core/unoatrcn.cxx new file mode 100644 index 000000000..81ec1e93e --- /dev/null +++ b/xmloff/source/core/unoatrcn.cxx @@ -0,0 +1,250 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <memory> +#include <com/sun/star/xml/AttributeData.hpp> +#include <o3tl/any.hxx> +#include <rtl/ustrbuf.hxx> +#include <comphelper/servicehelper.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <limits.h> + +#include <xmloff/xmlcnimp.hxx> + +#include <xmloff/unoatrcn.hxx> + +using namespace ::com::sun::star; + +// Interface implementation + +uno::Reference< uno::XInterface > SvUnoAttributeContainer_CreateInstance() +{ + return *(new SvUnoAttributeContainer); +} + +SvUnoAttributeContainer::SvUnoAttributeContainer( std::unique_ptr<SvXMLAttrContainerData> pContainer) +: mpContainer( std::move( pContainer ) ) +{ + if( !mpContainer ) + mpContainer = std::make_unique<SvXMLAttrContainerData>(); +} + +// container::XElementAccess +uno::Type SAL_CALL SvUnoAttributeContainer::getElementType() +{ + return cppu::UnoType<xml::AttributeData>::get(); +} + +sal_Bool SAL_CALL SvUnoAttributeContainer::hasElements() +{ + return mpContainer->GetAttrCount() != 0; +} + +sal_uInt16 SvUnoAttributeContainer::getIndexByName(const OUString& aName ) const +{ + const sal_uInt16 nAttrCount = mpContainer->GetAttrCount(); + + sal_Int32 nPos = aName.indexOf( ':' ); + if( nPos == -1 ) + { + for( sal_uInt16 nAttr = 0; nAttr < nAttrCount; nAttr++ ) + { + if( mpContainer->GetAttrLName(nAttr) == aName && + mpContainer->GetAttrPrefix(nAttr).isEmpty() ) + return nAttr; + } + } + else + { + const OUString aPrefix( aName.copy( 0L, nPos ) ); + const OUString aLName( aName.copy( nPos+1 ) ); + + for( sal_uInt16 nAttr = 0; nAttr < nAttrCount; nAttr++ ) + { + if( mpContainer->GetAttrLName(nAttr) == aLName && + mpContainer->GetAttrPrefix(nAttr) == aPrefix ) + return nAttr; + } + } + + return USHRT_MAX; +} + +namespace +{ + class theSvUnoAttributeContainerUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSvUnoAttributeContainerUnoTunnelId> {}; +} + +const css::uno::Sequence< sal_Int8 > & SvUnoAttributeContainer::getUnoTunnelId() throw() +{ + return theSvUnoAttributeContainerUnoTunnelId::get().getSeq(); +} + +sal_Int64 SAL_CALL SvUnoAttributeContainer::getSomething( const css::uno::Sequence< sal_Int8 >& rId ) +{ + if( isUnoTunnelId<SvUnoAttributeContainer>(rId) ) + { + return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this)); + } + return 0; +} + +// container::XNameAccess +uno::Any SAL_CALL SvUnoAttributeContainer::getByName(const OUString& aName) +{ + sal_uInt16 nAttr = getIndexByName(aName ); + + if( nAttr == USHRT_MAX ) + throw container::NoSuchElementException(); + + xml::AttributeData aData; + aData.Namespace = mpContainer->GetAttrNamespace(nAttr); + aData.Type = "CDATA"; + aData.Value = mpContainer->GetAttrValue(nAttr); + + return uno::Any(aData); +} + +uno::Sequence< OUString > SAL_CALL SvUnoAttributeContainer::getElementNames() +{ + const sal_uInt16 nAttrCount = mpContainer->GetAttrCount(); + + uno::Sequence< OUString > aElementNames( static_cast<sal_Int32>(nAttrCount) ); + OUString *pNames = aElementNames.getArray(); + + for( sal_uInt16 nAttr = 0; nAttr < nAttrCount; nAttr++ ) + { + OUStringBuffer sBuffer( mpContainer->GetAttrPrefix(nAttr) ); + if( !sBuffer.isEmpty() ) + sBuffer.append( ':' ); + sBuffer.append( mpContainer->GetAttrLName(nAttr) ); + *pNames++ = sBuffer.makeStringAndClear(); + } + + return aElementNames; +} + +sal_Bool SAL_CALL SvUnoAttributeContainer::hasByName(const OUString& aName) +{ + return getIndexByName(aName ) != USHRT_MAX; +} + +// container::XNameReplace +void SAL_CALL SvUnoAttributeContainer::replaceByName(const OUString& aName, const uno::Any& aElement) +{ + if( auto pData = o3tl::tryAccess<xml::AttributeData>(aElement) ) + { + sal_uInt16 nAttr = getIndexByName(aName ); + if( nAttr == USHRT_MAX ) + throw container::NoSuchElementException(); + + sal_Int32 nPos = aName.indexOf( ':' ); + if( nPos != -1 ) + { + const OUString aPrefix( aName.copy( 0L, nPos )); + const OUString aLName( aName.copy( nPos+1 )); + + if( pData->Namespace.isEmpty() ) + { + if( mpContainer->SetAt( nAttr, aPrefix, aLName, pData->Value ) ) + return; + } + else + { + if( mpContainer->SetAt( nAttr, aPrefix, pData->Namespace, aLName, pData->Value ) ) + return; + } + } + else + { + if( pData->Namespace.isEmpty() ) + { + if( mpContainer->SetAt( nAttr, aName, pData->Value ) ) + return; + } + } + } + + throw lang::IllegalArgumentException(); +} + +// container::XNameContainer +void SAL_CALL SvUnoAttributeContainer::insertByName(const OUString& aName, const uno::Any& aElement) +{ + auto pData = o3tl::tryAccess<xml::AttributeData>(aElement); + if( !pData ) + throw lang::IllegalArgumentException(); + + sal_uInt16 nAttr = getIndexByName(aName ); + if( nAttr != USHRT_MAX ) + throw container::ElementExistException(); + + sal_Int32 nPos = aName.indexOf( ':' ); + if( nPos != -1 ) + { + const OUString aPrefix( aName.copy( 0L, nPos )); + const OUString aLName( aName.copy( nPos+1 )); + + if( pData->Namespace.isEmpty() ) + { + if( mpContainer->AddAttr( aPrefix, aLName, pData->Value ) ) + return; + } + else + { + if( mpContainer->AddAttr( aPrefix, pData->Namespace, aLName, pData->Value ) ) + return; + } + } + else + { + if( pData->Namespace.isEmpty() ) + { + if( mpContainer->AddAttr( aName, pData->Value ) ) + return; + } + } +} + +void SAL_CALL SvUnoAttributeContainer::removeByName(const OUString& Name) +{ + sal_uInt16 nAttr = getIndexByName(Name); + if( nAttr == USHRT_MAX ) + throw container::NoSuchElementException(); + + mpContainer->Remove( nAttr ); +} + +//XServiceInfo +OUString SAL_CALL SvUnoAttributeContainer::getImplementationName() +{ + return "SvUnoAttributeContainer"; +} + +uno::Sequence< OUString > SvUnoAttributeContainer::getSupportedServiceNames() +{ + return { "com.sun.star.xml.AttributeContainer" }; +} + +sal_Bool SvUnoAttributeContainer::supportsService(const OUString& ServiceName) +{ + return cppu::supportsService(this, ServiceName); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/unointerfacetouniqueidentifiermapper.cxx b/xmloff/source/core/unointerfacetouniqueidentifiermapper.cxx new file mode 100644 index 000000000..d2e29422a --- /dev/null +++ b/xmloff/source/core/unointerfacetouniqueidentifiermapper.cxx @@ -0,0 +1,174 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <o3tl/safeint.hxx> +#include <xmloff/unointerfacetouniqueidentifiermapper.hxx> + +using namespace ::com::sun::star; +using css::uno::Reference; +using css::uno::XInterface; + +namespace comphelper +{ + +UnoInterfaceToUniqueIdentifierMapper::UnoInterfaceToUniqueIdentifierMapper() +: mnNextId( 1 ) +{ +} + +const OUString& UnoInterfaceToUniqueIdentifierMapper::registerReference( const Reference< XInterface >& rInterface ) +{ + // Be certain that the references we store in our table are to the + // leading / primary XInterface - cf. findReference + uno::Reference< uno::XInterface > xRef( rInterface, uno::UNO_QUERY ); + + IdMap_t::const_iterator aIter; + if( findReference( xRef, aIter ) ) + { + return (*aIter).first; + } + else + { + OUString aId = "id" + OUString::number( mnNextId++ ); + return (*maEntries.emplace( aId, xRef ).first).first; + } +} + +bool UnoInterfaceToUniqueIdentifierMapper::registerReference( const OUString& rIdentifier, const Reference< XInterface >& rInterface ) +{ + IdMap_t::const_iterator aIter; + + // Be certain that the references we store in our table are to the + // leading / primary XInterface - cf. findReference + uno::Reference< uno::XInterface > xRef( rInterface, uno::UNO_QUERY ); + + if( findReference( xRef, aIter ) ) + { + return rIdentifier != (*aIter).first; + } + else if( findIdentifier( rIdentifier, aIter ) ) + { + return false; + } + else + { + insertReference( rIdentifier, xRef ); + } + + return true; +} + +void UnoInterfaceToUniqueIdentifierMapper::registerReferenceAlways( const OUString& rIdentifier, const Reference< XInterface >& rInterface ) +{ + // Be certain that the references we store in our table are to the + // leading / primary XInterface - cf. findReference + uno::Reference< uno::XInterface > xRef( rInterface, uno::UNO_QUERY ); + + insertReference( rIdentifier, xRef ); +} + +const OUString& UnoInterfaceToUniqueIdentifierMapper::getIdentifier( const Reference< XInterface >& rInterface ) const +{ + IdMap_t::const_iterator aIter; + if( findReference( rInterface, aIter ) ) + { + return (*aIter).first; + } + else + { + static const OUString aEmpty; + return aEmpty; + } +} + +const Reference< XInterface >& UnoInterfaceToUniqueIdentifierMapper::getReference( const OUString& rIdentifier ) const +{ + IdMap_t::const_iterator aIter; + if( findIdentifier( rIdentifier, aIter ) ) + { + return (*aIter).second; + } + else + { + static const Reference< XInterface > aEmpty; + return aEmpty; + } +} + +bool UnoInterfaceToUniqueIdentifierMapper::findReference( const Reference< XInterface >& rInterface, IdMap_t::const_iterator& rIter ) const +{ + uno::Reference< uno::XInterface > xRef( rInterface, uno::UNO_QUERY ); + + const IdMap_t::const_iterator aEnd( maEntries.end() ); + rIter = std::find_if(maEntries.begin(), aEnd, [&xRef](const IdMap_t::value_type& rItem) { + // The Reference == operator, does a repeated queryInterface on + // this to ensure we got the right XInterface base-class. However, + // we can be sure that this has been done already by the time we + // get to here. + return rItem.second.get() == xRef.get(); + }); + + return rIter != aEnd; +} + +bool UnoInterfaceToUniqueIdentifierMapper::findIdentifier( const OUString& rIdentifier, IdMap_t::const_iterator& rIter ) const +{ + rIter = maEntries.find( rIdentifier ); + return rIter != maEntries.end(); +} + +void UnoInterfaceToUniqueIdentifierMapper::insertReference( const OUString& rIdentifier, const Reference< XInterface >& rInterface ) +{ + maEntries[rIdentifier] = rInterface; + + // see if this is a reference like something we would generate in the future + const sal_Unicode *p = rIdentifier.getStr(); + sal_Int32 nLength = rIdentifier.getLength(); + + // see if the identifier is 'id' followed by a pure integer value + if( nLength < 2 || p[0] != 'i' || p[1] != 'd' ) + return; + + nLength -= 2; + p += 2; + + while(nLength--) + { + if( (*p < '0') || (*p > '9') ) + return; // a custom id, that will never conflict with generated id's + + p++; + } + + // the identifier is a pure integer value + // so we make sure we will never generate + // an integer value like this one + sal_Int32 nId = rIdentifier.copy(2).toInt32(); + if (nId > 0 && mnNextId <= o3tl::make_unsigned(nId)) + { + mnNextId = nId; + ++mnNextId; + } +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/xmlcnimp.cxx b/xmloff/source/core/xmlcnimp.cxx new file mode 100644 index 000000000..f9cc06532 --- /dev/null +++ b/xmloff/source/core/xmlcnimp.cxx @@ -0,0 +1,139 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "SvXMLAttrCollection.hxx" +#include <xmloff/xmlcnimp.hxx> +#include <rtl/ustring.hxx> + +SvXMLAttrContainerData::SvXMLAttrContainerData() : pimpl( new SvXMLAttrCollection ) +{ +} + +SvXMLAttrContainerData::SvXMLAttrContainerData(const SvXMLAttrContainerData &rCopy) : + pimpl( new SvXMLAttrCollection( *(rCopy.pimpl) ) ) +{ +} + +// Need destructor defined (despite it being empty) to avoid "checked_delete" +// compiler errors. +SvXMLAttrContainerData::~SvXMLAttrContainerData() +{ +} + +bool SvXMLAttrContainerData::operator ==( const SvXMLAttrContainerData& rCmp ) const +{ + return ( *(rCmp.pimpl) == *pimpl ); +} + +bool SvXMLAttrContainerData::AddAttr( const OUString& rLName, + const OUString& rValue ) +{ + return pimpl->AddAttr(rLName, rValue); +} + +bool SvXMLAttrContainerData::AddAttr( const OUString& rPrefix, + const OUString& rNamespace, + const OUString& rLName, + const OUString& rValue ) +{ + return pimpl->AddAttr(rPrefix, rNamespace, rLName, rValue); +} + +bool SvXMLAttrContainerData::AddAttr( const OUString& rPrefix, + const OUString& rLName, + const OUString& rValue ) +{ + return pimpl->AddAttr(rPrefix, rLName, rValue); +} + +bool SvXMLAttrContainerData::SetAt( size_t i, + const OUString& rLName, + const OUString& rValue ) +{ + return pimpl->SetAt(i, rLName, rValue); +} + +bool SvXMLAttrContainerData::SetAt( size_t i, + const OUString& rPrefix, + const OUString& rNamespace, + const OUString& rLName, + const OUString& rValue ) +{ + return pimpl->SetAt(i, rPrefix, rNamespace, rLName, rValue); +} + +bool SvXMLAttrContainerData::SetAt( size_t i, + const OUString& rPrefix, + const OUString& rLName, + const OUString& rValue ) +{ + return pimpl->SetAt(i, rPrefix, rLName, rValue); +} + +void SvXMLAttrContainerData::Remove( size_t i ) +{ + pimpl->Remove(i); +} + +size_t SvXMLAttrContainerData::GetAttrCount() const +{ + return pimpl->GetAttrCount(); +} + +const OUString& SvXMLAttrContainerData::GetAttrLName(size_t i) const +{ + return pimpl->GetAttrLName(i); +} + +const OUString& SvXMLAttrContainerData::GetAttrValue(size_t i) const +{ + return pimpl->GetAttrValue(i); +} + +OUString SvXMLAttrContainerData::GetAttrNamespace( size_t i ) const +{ + return pimpl->GetAttrNamespace(i); +} + +OUString SvXMLAttrContainerData::GetAttrPrefix( size_t i ) const +{ + return pimpl->GetAttrPrefix(i); +} + +const OUString& SvXMLAttrContainerData::GetNamespace( sal_uInt16 i ) const +{ + return pimpl->GetNamespace(i); +} + +const OUString& SvXMLAttrContainerData::GetPrefix( sal_uInt16 i ) const +{ + return pimpl->GetPrefix(i); +} + +sal_uInt16 SvXMLAttrContainerData::GetFirstNamespaceIndex() const +{ + return pimpl->GetFirstNamespaceIndex(); +} + +sal_uInt16 SvXMLAttrContainerData::GetNextNamespaceIndex( sal_uInt16 nIdx ) const +{ + return pimpl->GetNextNamespaceIndex( nIdx ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/xmlenums.hxx b/xmloff/source/core/xmlenums.hxx new file mode 100644 index 000000000..18b0f9a4a --- /dev/null +++ b/xmloff/source/core/xmlenums.hxx @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_XMLOFF_SOURCE_CORE_XMLENUMS_HXX +#define INCLUDED_XMLOFF_SOURCE_CORE_XMLENUMS_HXX + +enum XMLForbiddenCharactersEnum +{ + XML_FORBIDDEN_CHARACTER_LANGUAGE, + XML_FORBIDDEN_CHARACTER_COUNTRY, + XML_FORBIDDEN_CHARACTER_VARIANT, + XML_FORBIDDEN_CHARACTER_BEGIN_LINE, + XML_FORBIDDEN_CHARACTER_END_LINE, + XML_FORBIDDEN_CHARACTER_MAX +}; + +enum XMLSymbolDescriptorsEnum +{ + XML_SYMBOL_DESCRIPTOR_NAME, + XML_SYMBOL_DESCRIPTOR_EXPORT_NAME, + XML_SYMBOL_DESCRIPTOR_SYMBOL_SET, + XML_SYMBOL_DESCRIPTOR_CHARACTER, + XML_SYMBOL_DESCRIPTOR_FONT_NAME, + XML_SYMBOL_DESCRIPTOR_CHAR_SET, + XML_SYMBOL_DESCRIPTOR_FAMILY, + XML_SYMBOL_DESCRIPTOR_PITCH, + XML_SYMBOL_DESCRIPTOR_WEIGHT, + XML_SYMBOL_DESCRIPTOR_ITALIC, + XML_SYMBOL_DESCRIPTOR_MAX +}; +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/xmlerror.cxx b/xmloff/source/core/xmlerror.cxx new file mode 100644 index 000000000..8b070c7f5 --- /dev/null +++ b/xmloff/source/core/xmlerror.cxx @@ -0,0 +1,208 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <xmloff/xmlerror.hxx> +#include <rtl/ustring.hxx> +#include <sal/log.hxx> +#include <com/sun/star/xml/sax/XLocator.hpp> +#include <com/sun/star/xml/sax/SAXParseException.hpp> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +#include <rtl/ustrbuf.hxx> + +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::xml::sax::XLocator; +using ::com::sun::star::xml::sax::SAXParseException; + + +/// ErrorRecord: contains all information for one error + + +class ErrorRecord +{ +public: + + ErrorRecord( sal_Int32 nId, + const Sequence<OUString>& rParams, + const OUString& rExceptionMessage, + sal_Int32 nRow, + sal_Int32 nColumn, + const OUString& rPublicId, + const OUString& rSystemId); + + sal_Int32 nId; /// error ID + + OUString sExceptionMessage;/// message of original exception (if available) + + // XLocator information: + sal_Int32 nRow; /// row number where error occurred (or -1 for unknown) + sal_Int32 nColumn; /// column number where error occurred (or -1) + OUString sPublicId; /// public identifier + OUString sSystemId; /// public identifier + + /// message Parameters + Sequence<OUString> aParams; +}; + + +ErrorRecord::ErrorRecord( sal_Int32 nID, const Sequence<OUString>& rParams, + const OUString& rExceptionMessage, sal_Int32 nRowNumber, sal_Int32 nCol, + const OUString& rPublicId, const OUString& rSystemId) : + nId(nID), + sExceptionMessage(rExceptionMessage), + nRow(nRowNumber), + nColumn(nCol), + sPublicId(rPublicId), + sSystemId(rSystemId), + aParams(rParams) +{ +} + +XMLErrors::XMLErrors() +{ +} + +XMLErrors::~XMLErrors() +{ +} + +void XMLErrors::AddRecord( + sal_Int32 nId, + const Sequence<OUString> & rParams, + const OUString& rExceptionMessage, + sal_Int32 nRow, + sal_Int32 nColumn, + const OUString& rPublicId, + const OUString& rSystemId ) +{ + aErrors.emplace_back( nId, rParams, rExceptionMessage, + nRow, nColumn, rPublicId, rSystemId ); + +#ifdef DBG_UTIL + + // give detailed assertion on this message + + OUStringBuffer sMessage; + + sMessage.append( "An error or a warning has occurred during XML import/export!\n" ); + + // ID & flags + sMessage.append( "Error-Id: 0x"); + sMessage.append( nId, 16 ); + sMessage.append( "\n Flags: " ); + sal_Int32 nFlags = (nId & XMLERROR_MASK_FLAG); + sMessage.append( nFlags >> 28, 16 ); + if( (nFlags & XMLERROR_FLAG_WARNING) != 0 ) + sMessage.append( " WARNING" ); + if( (nFlags & XMLERROR_FLAG_ERROR) != 0 ) + sMessage.append( " ERROR" ); + if( (nFlags & XMLERROR_FLAG_SEVERE) != 0 ) + sMessage.append( " SEVERE" ); + sMessage.append( "\n Class: " ); + sal_Int32 nClass = (nId & XMLERROR_MASK_CLASS); + sMessage.append( nClass >> 16, 16 ); + if( (nClass & XMLERROR_CLASS_IO) != 0 ) + sMessage.append( " IO" ); + if( (nClass & XMLERROR_CLASS_FORMAT) != 0 ) + sMessage.append( " FORMAT" ); + if( (nClass & XMLERROR_CLASS_API) != 0 ) + sMessage.append( " API" ); + if( (nClass & XMLERROR_CLASS_OTHER) != 0 ) + sMessage.append( " OTHER" ); + sMessage.append( "\n Number: " ); + sal_Int32 nNumber = (nId & XMLERROR_MASK_NUMBER); + sMessage.append( nNumber, 16 ); + sMessage.append( "\n"); + + // the parameters + sMessage.append( "Parameters:\n" ); + sal_Int32 nLength = rParams.getLength(); + const OUString* pParams = rParams.getConstArray(); + for( sal_Int32 i = 0; i < nLength; i++ ) + { + sMessage.append( " " ); + sMessage.append( i ); + sMessage.append( ": " ); + sMessage.append( pParams[i] ); + sMessage.append( "\n" ); + } + + // the exception message + sMessage.append( "Exception-Message: " ); + sMessage.append( rExceptionMessage ); + sMessage.append( "\n" ); + + // position (if given) + if( (nRow != -1) || (nColumn != -1) ) + { + sMessage.append( "Position:\n Public Identifier: " ); + sMessage.append( rPublicId ); + sMessage.append( "\n System Identifier: " ); + sMessage.append( rSystemId ); + sMessage.append( "\n Row, Column: " ); + sMessage.append( nRow ); + sMessage.append( "," ); + sMessage.append( nColumn ); + sMessage.append( "\n" ); + } + + SAL_WARN( "xmloff", sMessage.makeStringAndClear() ); +#endif +} + +void XMLErrors::AddRecord( + sal_Int32 nId, + const Sequence<OUString> & rParams, + const OUString& rExceptionMessage, + const Reference<XLocator> & rLocator) +{ + if ( rLocator.is() ) + { + AddRecord( nId, rParams, rExceptionMessage, + rLocator->getLineNumber(), rLocator->getColumnNumber(), + rLocator->getPublicId(), rLocator->getSystemId() ); + } + else + { + AddRecord( nId, rParams, rExceptionMessage, + -1, -1, "", "" ); + } +} + +void XMLErrors::ThrowErrorAsSAXException(sal_Int32 nIdMask) +{ + // search first error/warning that matches the nIdMask + for( const auto& rError : aErrors ) + { + if ( (rError.nId & nIdMask) != 0 ) + { + // we throw the error + ErrorRecord& rErr = aErrors[0]; + throw SAXParseException( + rErr.sExceptionMessage, nullptr, Any(rErr.aParams), + rErr.sPublicId, rErr.sSystemId, rErr.nRow, rErr.nColumn ); + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/xmlexp.cxx b/xmloff/source/core/xmlexp.cxx new file mode 100644 index 000000000..71a36957f --- /dev/null +++ b/xmloff/source/core/xmlexp.cxx @@ -0,0 +1,2502 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <memory> +#include <sal/config.h> +#include <sal/log.hxx> + +#include <stack> + +#include <officecfg/Office/Common.hxx> +#include <xmloff/unointerfacetouniqueidentifiermapper.hxx> +#include <osl/mutex.hxx> +#include <tools/urlobj.hxx> +#include <vcl/graph.hxx> +#include <comphelper/genericpropertyset.hxx> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/document/XBinaryStreamResolver.hpp> +#include <com/sun/star/document/XEmbeddedObjectResolver.hpp> +#include <com/sun/star/text/XTextContent.hpp> +#include <com/sun/star/xml/sax/SAXInvalidCharacterException.hpp> +#include <com/sun/star/uri/XUriReferenceFactory.hpp> +#include <com/sun/star/uri/UriReferenceFactory.hpp> +#include <com/sun/star/util/XNumberFormatsSupplier.hpp> +#include <com/sun/star/util/MeasureUnit.hpp> +#include <i18nlangtag/languagetag.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/propertysetinfo.hxx> +#include <xmloff/attrlist.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmluconv.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlexp.hxx> +#include <xmloff/xmlnumfe.hxx> +#include <xmloff/xmlmetae.hxx> +#include <xmloff/XMLSettingsExportContext.hxx> +#include <xmloff/XMLEventExport.hxx> +#include <xmloff/ProgressBarHelper.hxx> +#include <XMLStarBasicExportHandler.hxx> +#include <XMLScriptExportHandler.hxx> +#include <xmloff/SettingsExportHelper.hxx> +#include <com/sun/star/document/XEventsSupplier.hpp> +#include <com/sun/star/document/XViewDataSupplier.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <xmloff/GradientStyle.hxx> +#include <xmloff/HatchStyle.hxx> +#include <xmloff/ImageStyle.hxx> +#include <TransGradientStyle.hxx> +#include <xmloff/MarkerStyle.hxx> +#include <xmloff/DashStyle.hxx> +#include <xmloff/XMLFontAutoStylePool.hxx> +#include <XMLImageMapExport.hxx> +#include <XMLBase64Export.hxx> +#include <xmloff/xmlerror.hxx> +#include <com/sun/star/style/XStyle.hpp> +#include <com/sun/star/style/XStyleFamiliesSupplier.hpp> +#include <com/sun/star/lang/ServiceNotRegisteredException.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <xmloff/XMLFilterServiceNames.h> +#include <XMLEmbeddedObjectExportFilter.hxx> +#include <XMLBasicExportFilter.hxx> +#include <cppuhelper/exc_hlp.hxx> +#include <cppuhelper/implbase.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <comphelper/extract.hxx> +#include <PropertySetMerger.hxx> + +#include <unotools/docinfohelper.hxx> +#include <com/sun/star/document/XDocumentProperties.hpp> +#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> +#include <com/sun/star/document/XMLOasisBasicExporter.hpp> +#include <com/sun/star/embed/XEncryptionProtectedSource2.hpp> +#include <com/sun/star/document/XGraphicStorageHandler.hpp> +#include <com/sun/star/rdf/XMetadatable.hpp> +#include <RDFaExportHelper.hxx> + +#include <comphelper/xmltools.hxx> +#include <comphelper/graphicmimetype.hxx> + +using namespace ::osl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::document; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::xml::sax; +using namespace ::com::sun::star::io; +using namespace ::xmloff::token; + +#define XML_MODEL_SERVICE_WRITER "com.sun.star.text.TextDocument" +#define XML_MODEL_SERVICE_CALC "com.sun.star.sheet.SpreadsheetDocument" +#define XML_MODEL_SERVICE_DRAW "com.sun.star.drawing.DrawingDocument" +#define XML_MODEL_SERVICE_IMPRESS "com.sun.star.presentation.PresentationDocument" +#define XML_MODEL_SERVICE_MATH "com.sun.star.formula.FormulaProperties" +#define XML_MODEL_SERVICE_CHART "com.sun.star.chart.ChartDocument" + +#define XML_USEPRETTYPRINTING "UsePrettyPrinting" + +#define XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE "vnd.sun.star.GraphicObject:" +#define XML_EMBEDDEDOBJECT_URL_BASE "vnd.sun.star.EmbeddedObject:" + +namespace { + +struct XMLServiceMapEntry_Impl +{ + const char *sModelService; + sal_Int32 nModelServiceLen; + const char *sFilterService; + sal_Int32 nFilterServiceLen; +}; + +} + +#define SERVICE_MAP_ENTRY( app ) \ + { XML_MODEL_SERVICE_##app, sizeof(XML_MODEL_SERVICE_##app)-1, \ + XML_EXPORT_FILTER_##app, sizeof(XML_EXPORT_FILTER_##app)-1 } + +const XMLServiceMapEntry_Impl aServiceMap[] = +{ + SERVICE_MAP_ENTRY( WRITER ), + SERVICE_MAP_ENTRY( CALC ), + SERVICE_MAP_ENTRY( IMPRESS ),// Impress supports DrawingDocument, too, so + SERVICE_MAP_ENTRY( DRAW ), // it must appear before Draw + SERVICE_MAP_ENTRY( MATH ), + SERVICE_MAP_ENTRY( CHART ), + { nullptr, 0, nullptr, 0 } +}; + +namespace { + +class SettingsExportFacade : public ::xmloff::XMLSettingsExportContext +{ +public: + explicit SettingsExportFacade( SvXMLExport& i_rExport ) + :m_rExport( i_rExport ) + { + } + + virtual ~SettingsExportFacade() + { + } + + virtual void AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, + const OUString& i_rValue ) override; + virtual void AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, + enum ::xmloff::token::XMLTokenEnum i_eValue ) override; + + virtual void StartElement( enum ::xmloff::token::XMLTokenEnum i_eName ) override; + virtual void EndElement( const bool i_bIgnoreWhitespace ) override; + + virtual void Characters( const OUString& i_rCharacters ) override; + + virtual css::uno::Reference< css::uno::XComponentContext > + GetComponentContext() const override; +private: + SvXMLExport& m_rExport; + ::std::stack< OUString > m_aElements; +}; + +} + +void SettingsExportFacade::AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, const OUString& i_rValue ) +{ + m_rExport.AddAttribute( XML_NAMESPACE_CONFIG, i_eName, i_rValue ); +} + +void SettingsExportFacade::AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, enum ::xmloff::token::XMLTokenEnum i_eValue ) +{ + m_rExport.AddAttribute( XML_NAMESPACE_CONFIG, i_eName, i_eValue ); +} + +void SettingsExportFacade::StartElement( enum ::xmloff::token::XMLTokenEnum i_eName ) +{ + const OUString sElementName( m_rExport.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_CONFIG, GetXMLToken( i_eName ) ) ); + m_rExport.StartElement( sElementName, true/*i_bIgnoreWhitespace*/ ); + m_aElements.push( sElementName ); +} + +void SettingsExportFacade::EndElement( const bool i_bIgnoreWhitespace ) +{ + const OUString sElementName( m_aElements.top() ); + m_rExport.EndElement( sElementName, i_bIgnoreWhitespace ); + m_aElements.pop(); +} + +void SettingsExportFacade::Characters( const OUString& i_rCharacters ) +{ + m_rExport.GetDocHandler()->characters( i_rCharacters ); +} + +Reference< XComponentContext > SettingsExportFacade::GetComponentContext() const +{ + return m_rExport.getComponentContext(); +} + +namespace { + +class SvXMLExportEventListener : public cppu::WeakImplHelper< + css::lang::XEventListener > +{ +private: + SvXMLExport* pExport; + +public: + explicit SvXMLExportEventListener(SvXMLExport* pExport); + + // XEventListener + virtual void SAL_CALL disposing(const lang::EventObject& rEventObject) override; +}; + +} + +SvXMLExportEventListener::SvXMLExportEventListener(SvXMLExport* pTempExport) + : pExport(pTempExport) +{ +} + +// XEventListener +void SAL_CALL SvXMLExportEventListener::disposing( const lang::EventObject& ) +{ + if (pExport) + { + pExport->DisposingModel(); + pExport = nullptr; + } +} + +class SvXMLExport_Impl +{ +public: + SvXMLExport_Impl(); + + ::comphelper::UnoInterfaceToUniqueIdentifierMapper maInterfaceToIdentifierMapper; + uno::Reference< uri::XUriReferenceFactory > mxUriReferenceFactory; + OUString msPackageURI; + OUString msPackageURIScheme; + // Written OpenDocument file format doesn't fit to the created text document (#i69627#) + bool mbOutlineStyleAsNormalListStyle; + + uno::Reference< embed::XStorage > mxTargetStorage; + + SvtSaveOptions maSaveOptions; + + /// name of stream in package, e.g., "content.xml" + OUString mStreamName; + + OUString maSrcShellID; + OUString maDestShellID; + + /// stack of backed up namespace maps + /// long: depth at which namespace map has been backed up into the stack + ::std::stack< ::std::pair< std::unique_ptr<SvXMLNamespaceMap>, long > > mNamespaceMaps; + /// counts depth (number of open elements/start tags) + long mDepth; + + ::std::unique_ptr< ::xmloff::RDFaExportHelper> mpRDFaHelper; + + bool mbExportTextNumberElement; + bool mbNullDateInitialized; + + void SetSchemeOf( const OUString& rOrigFileName ) + { + sal_Int32 nSep = rOrigFileName.indexOf(':'); + if( nSep != -1 ) + msPackageURIScheme = rOrigFileName.copy( 0, nSep ); + } +}; + +SvXMLExport_Impl::SvXMLExport_Impl() +: mxUriReferenceFactory( uri::UriReferenceFactory::create(comphelper::getProcessComponentContext()) ), + // Written OpenDocument file format doesn't fit to the created text document (#i69627#) + mbOutlineStyleAsNormalListStyle( false ), + mDepth( 0 ), + mbExportTextNumberElement( false ), + mbNullDateInitialized( false ) +{ +} + +void SvXMLExport::SetDocHandler( const uno::Reference< xml::sax::XDocumentHandler > &rHandler ) +{ + mxHandler = rHandler; + mxExtHandler.set( mxHandler, UNO_QUERY ); +} + +void SvXMLExport::InitCtor_() +{ + // note: it is not necessary to add XML_NP_XML (it is declared implicitly) + if( getExportFlags() & ~SvXMLExportFlags::OASIS ) + { + mpNamespaceMap->Add( GetXMLToken(XML_NP_OFFICE), GetXMLToken(XML_N_OFFICE), XML_NAMESPACE_OFFICE ); + mpNamespaceMap->Add( GetXMLToken(XML_NP_OOO), GetXMLToken(XML_N_OOO), XML_NAMESPACE_OOO ); + } + if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::FONTDECLS) ) + { + mpNamespaceMap->Add( GetXMLToken(XML_NP_FO), GetXMLToken(XML_N_FO_COMPAT), XML_NAMESPACE_FO ); + } + if( getExportFlags() & (SvXMLExportFlags::META|SvXMLExportFlags::STYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::SCRIPTS|SvXMLExportFlags::SETTINGS) ) + { + mpNamespaceMap->Add( GetXMLToken(XML_NP_XLINK), GetXMLToken(XML_N_XLINK), XML_NAMESPACE_XLINK ); + } + if( getExportFlags() & SvXMLExportFlags::SETTINGS ) + { + mpNamespaceMap->Add( GetXMLToken(XML_NP_CONFIG), GetXMLToken(XML_N_CONFIG), XML_NAMESPACE_CONFIG ); + } + + if( getExportFlags() & (SvXMLExportFlags::META|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) ) + { + mpNamespaceMap->Add( GetXMLToken(XML_NP_DC), GetXMLToken(XML_N_DC), XML_NAMESPACE_DC ); + mpNamespaceMap->Add( GetXMLToken(XML_NP_META), GetXMLToken(XML_N_META), XML_NAMESPACE_META ); + } + if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::FONTDECLS) ) + { + mpNamespaceMap->Add( GetXMLToken(XML_NP_STYLE), GetXMLToken(XML_N_STYLE), XML_NAMESPACE_STYLE ); + } + + // namespaces for documents + if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) ) + { + mpNamespaceMap->Add( GetXMLToken(XML_NP_DC), GetXMLToken(XML_N_DC), XML_NAMESPACE_DC ); + mpNamespaceMap->Add( GetXMLToken(XML_NP_TEXT), GetXMLToken(XML_N_TEXT), XML_NAMESPACE_TEXT ); + mpNamespaceMap->Add( GetXMLToken(XML_NP_DRAW), GetXMLToken(XML_N_DRAW), XML_NAMESPACE_DRAW ); + mpNamespaceMap->Add( GetXMLToken(XML_NP_DR3D), GetXMLToken(XML_N_DR3D), XML_NAMESPACE_DR3D ); + mpNamespaceMap->Add( GetXMLToken(XML_NP_SVG), GetXMLToken(XML_N_SVG_COMPAT), XML_NAMESPACE_SVG ); + mpNamespaceMap->Add( GetXMLToken(XML_NP_CHART), GetXMLToken(XML_N_CHART), XML_NAMESPACE_CHART ); + mpNamespaceMap->Add( GetXMLToken(XML_NP_RPT), GetXMLToken(XML_N_RPT), XML_NAMESPACE_REPORT ); + mpNamespaceMap->Add( GetXMLToken(XML_NP_TABLE), GetXMLToken(XML_N_TABLE), XML_NAMESPACE_TABLE ); + mpNamespaceMap->Add( GetXMLToken(XML_NP_NUMBER),GetXMLToken(XML_N_NUMBER), XML_NAMESPACE_NUMBER ); + mpNamespaceMap->Add( GetXMLToken(XML_NP_OOOW), GetXMLToken(XML_N_OOOW), XML_NAMESPACE_OOOW ); + mpNamespaceMap->Add( GetXMLToken(XML_NP_OOOC), GetXMLToken(XML_N_OOOC), XML_NAMESPACE_OOOC ); + mpNamespaceMap->Add( GetXMLToken(XML_NP_OF), GetXMLToken(XML_N_OF), XML_NAMESPACE_OF ); + + if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) + { + mpNamespaceMap->Add( + GetXMLToken(XML_NP_TABLE_EXT), GetXMLToken(XML_N_TABLE_EXT), XML_NAMESPACE_TABLE_EXT); + mpNamespaceMap->Add( + GetXMLToken(XML_NP_CALC_EXT), GetXMLToken(XML_N_CALC_EXT), XML_NAMESPACE_CALC_EXT); + mpNamespaceMap->Add( + GetXMLToken(XML_NP_DRAW_EXT), GetXMLToken(XML_N_DRAW_EXT), XML_NAMESPACE_DRAW_EXT); + mpNamespaceMap->Add( + GetXMLToken(XML_NP_LO_EXT), GetXMLToken(XML_N_LO_EXT), + XML_NAMESPACE_LO_EXT); + mpNamespaceMap->Add( GetXMLToken(XML_NP_FIELD), GetXMLToken(XML_N_FIELD), XML_NAMESPACE_FIELD ); + } + } + if( getExportFlags() & (SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) ) + { + mpNamespaceMap->Add( GetXMLToken(XML_NP_MATH), GetXMLToken(XML_N_MATH), XML_NAMESPACE_MATH ); + mpNamespaceMap->Add( GetXMLToken(XML_NP_FORM), GetXMLToken(XML_N_FORM), XML_NAMESPACE_FORM ); + } + if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::SCRIPTS) ) + { + mpNamespaceMap->Add( GetXMLToken(XML_NP_SCRIPT), GetXMLToken(XML_N_SCRIPT), XML_NAMESPACE_SCRIPT ); + mpNamespaceMap->Add( GetXMLToken(XML_NP_DOM), GetXMLToken(XML_N_DOM), XML_NAMESPACE_DOM ); + } + if( getExportFlags() & SvXMLExportFlags::CONTENT ) + { + mpNamespaceMap->Add( GetXMLToken(XML_NP_XFORMS_1_0), GetXMLToken(XML_N_XFORMS_1_0), XML_NAMESPACE_XFORMS ); + mpNamespaceMap->Add( GetXMLToken(XML_NP_XSD), GetXMLToken(XML_N_XSD), XML_NAMESPACE_XSD ); + mpNamespaceMap->Add( GetXMLToken(XML_NP_XSI), GetXMLToken(XML_N_XSI), XML_NAMESPACE_XSI ); + mpNamespaceMap->Add( GetXMLToken(XML_NP_FORMX), GetXMLToken(XML_N_FORMX), XML_NAMESPACE_FORMX ); + } + + // RDFa: needed for content and header/footer styles + if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) ) + { + mpNamespaceMap->Add( GetXMLToken(XML_NP_XHTML), + GetXMLToken(XML_N_XHTML), XML_NAMESPACE_XHTML ); + } + // GRDDL: to convert RDFa and meta.xml to RDF + if( getExportFlags() & (SvXMLExportFlags::META|SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) ) + { + mpNamespaceMap->Add( GetXMLToken(XML_NP_GRDDL), + GetXMLToken(XML_N_GRDDL), XML_NAMESPACE_GRDDL ); + } + // CSS Text Level 3 for distributed text justification. + if ( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES) ) + { + mpNamespaceMap->Add( + GetXMLToken(XML_NP_CSS3TEXT), GetXMLToken(XML_N_CSS3TEXT), XML_NAMESPACE_CSS3TEXT ); + } + + if (mxModel.is() && !mxEventListener.is()) + { + mxEventListener.set( new SvXMLExportEventListener(this)); + mxModel->addEventListener(mxEventListener); + } + + // Determine model type (#i51726#) + DetermineModelType_(); +} + +// Shapes in Writer cannot be named via context menu (#i51726#) +void SvXMLExport::DetermineModelType_() +{ + meModelType = SvtModuleOptions::EFactory::UNKNOWN_FACTORY; + + if ( mxModel.is() ) + { + meModelType = SvtModuleOptions::ClassifyFactoryByModel( mxModel ); + } +} + +SvXMLExport::SvXMLExport( + sal_Int16 const eDefaultMeasureUnit /*css::util::MeasureUnit*/, + const uno::Reference< uno::XComponentContext >& xContext, + OUString const & implementationName, + const enum XMLTokenEnum eClass, SvXMLExportFlags nExportFlags ) +: mpImpl( new SvXMLExport_Impl ), + m_xContext(xContext), m_implementationName(implementationName), + mxAttrList( new SvXMLAttributeList ), + mpNamespaceMap( new SvXMLNamespaceMap ), + maUnitConv( xContext, util::MeasureUnit::MM_100TH, eDefaultMeasureUnit ), + meClass( eClass ), + mnExportFlags( nExportFlags ), + mnErrorFlags( SvXMLErrorFlags::NO ), + msWS( GetXMLToken(XML_WS) ), + mbSaveLinkedSections(true), + mbAutoStylesCollected(false) +{ + SAL_WARN_IF( !xContext.is(), "xmloff.core", "got no service manager" ); + InitCtor_(); +} + +SvXMLExport::SvXMLExport( + const css::uno::Reference< css::uno::XComponentContext >& xContext, + OUString const & implementationName, + const OUString &rFileName, + sal_Int16 const eDefaultMeasureUnit /*css::util::MeasureUnit*/, + const uno::Reference< xml::sax::XDocumentHandler > & rHandler) +: mpImpl( new SvXMLExport_Impl ), + m_xContext(xContext), m_implementationName(implementationName), + mxHandler( rHandler ), + mxExtHandler( rHandler, uno::UNO_QUERY ), + mxAttrList( new SvXMLAttributeList ), + msOrigFileName( rFileName ), + mpNamespaceMap( new SvXMLNamespaceMap ), + maUnitConv( xContext, util::MeasureUnit::MM_100TH, eDefaultMeasureUnit ), + meClass( XML_TOKEN_INVALID ), + mnExportFlags( SvXMLExportFlags::NONE ), + mnErrorFlags( SvXMLErrorFlags::NO ), + msWS( GetXMLToken(XML_WS) ), + mbSaveLinkedSections(true), + mbAutoStylesCollected(false) +{ + SAL_WARN_IF( !xContext.is(), "xmloff.core", "got no service manager" ); + mpImpl->SetSchemeOf( msOrigFileName ); + InitCtor_(); + + if (mxNumberFormatsSupplier.is()) + mpNumExport.reset( new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier) ); +} + +SvXMLExport::SvXMLExport( + const css::uno::Reference< css::uno::XComponentContext >& xContext, + OUString const & implementationName, + const OUString &rFileName, + const uno::Reference< xml::sax::XDocumentHandler > & rHandler, + const Reference< XModel >& rModel, + FieldUnit const eDefaultFieldUnit, + SvXMLExportFlags nExportFlag) +: mpImpl( new SvXMLExport_Impl ), + m_xContext(xContext), m_implementationName(implementationName), + mxModel( rModel ), + mxHandler( rHandler ), + mxExtHandler( rHandler, uno::UNO_QUERY ), + mxNumberFormatsSupplier (rModel, uno::UNO_QUERY), + mxAttrList( new SvXMLAttributeList ), + msOrigFileName( rFileName ), + mpNamespaceMap( new SvXMLNamespaceMap ), + maUnitConv( xContext, + util::MeasureUnit::MM_100TH, + SvXMLUnitConverter::GetMeasureUnit(eDefaultFieldUnit) ), + meClass( XML_TOKEN_INVALID ), + mnExportFlags( nExportFlag ), + mnErrorFlags( SvXMLErrorFlags::NO ), + msWS( GetXMLToken(XML_WS) ), + mbSaveLinkedSections(true), + mbAutoStylesCollected(false) +{ + SAL_WARN_IF(!xContext.is(), "xmloff.core", "got no service manager" ); + mpImpl->SetSchemeOf( msOrigFileName ); + InitCtor_(); + + if (mxNumberFormatsSupplier.is()) + mpNumExport.reset( new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier) ); +} + +SvXMLExport::~SvXMLExport() +{ + mpXMLErrors.reset(); + mpImageMapExport.reset(); + mpEventExport.reset(); + mpNamespaceMap.reset(); + if (mpProgressBarHelper || mpNumExport) + { + if (mxExportInfo.is()) + { + uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxExportInfo->getPropertySetInfo(); + if (xPropertySetInfo.is()) + { + if (mpProgressBarHelper) + { + OUString sProgressMax(XML_PROGRESSMAX); + OUString sProgressCurrent(XML_PROGRESSCURRENT); + OUString sRepeat(XML_PROGRESSREPEAT); + if (xPropertySetInfo->hasPropertyByName(sProgressMax) && + xPropertySetInfo->hasPropertyByName(sProgressCurrent)) + { + sal_Int32 nProgressMax(mpProgressBarHelper->GetReference()); + sal_Int32 nProgressCurrent(mpProgressBarHelper->GetValue()); + mxExportInfo->setPropertyValue(sProgressMax, uno::Any(nProgressMax)); + mxExportInfo->setPropertyValue(sProgressCurrent, uno::Any(nProgressCurrent)); + } + if (xPropertySetInfo->hasPropertyByName(sRepeat)) + mxExportInfo->setPropertyValue(sRepeat, css::uno::makeAny(mpProgressBarHelper->GetRepeat())); + } + if (mpNumExport && (mnExportFlags & (SvXMLExportFlags::AUTOSTYLES | SvXMLExportFlags::STYLES))) + { + OUString sWrittenNumberFormats(XML_WRITTENNUMBERSTYLES); + if (xPropertySetInfo->hasPropertyByName(sWrittenNumberFormats)) + { + mxExportInfo->setPropertyValue(sWrittenNumberFormats, Any(mpNumExport->GetWasUsed())); + } + } + } + } + mpProgressBarHelper.reset(); + mpNumExport.reset(); + } + + if (mxEventListener.is() && mxModel.is()) + mxModel->removeEventListener(mxEventListener); +} + +// XExporter +void SAL_CALL SvXMLExport::setSourceDocument( const uno::Reference< lang::XComponent >& xDoc ) +{ + mxModel.set( xDoc, UNO_QUERY ); + if( !mxModel.is() ) + throw lang::IllegalArgumentException(); + if (mxModel.is() && ! mxEventListener.is()) + { + mxEventListener.set( new SvXMLExportEventListener(this)); + mxModel->addEventListener(mxEventListener); + } + + if(!mxNumberFormatsSupplier.is() ) + { + mxNumberFormatsSupplier.set(mxModel, css::uno::UNO_QUERY); + if(mxNumberFormatsSupplier.is() && mxHandler.is()) + mpNumExport.reset( new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier) ); + } + if (mxExportInfo.is()) + { + uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxExportInfo->getPropertySetInfo(); + if (xPropertySetInfo.is()) + { + OUString sUsePrettyPrinting(XML_USEPRETTYPRINTING); + if (xPropertySetInfo->hasPropertyByName(sUsePrettyPrinting)) + { + uno::Any aAny = mxExportInfo->getPropertyValue(sUsePrettyPrinting); + if (::cppu::any2bool(aAny)) + mnExportFlags |= SvXMLExportFlags::PRETTY; + else + mnExportFlags &= ~SvXMLExportFlags::PRETTY; + } + + if (mpNumExport && (mnExportFlags & (SvXMLExportFlags::AUTOSTYLES | SvXMLExportFlags::STYLES))) + { + OUString sWrittenNumberFormats(XML_WRITTENNUMBERSTYLES); + if (xPropertySetInfo->hasPropertyByName(sWrittenNumberFormats)) + { + uno::Any aAny = mxExportInfo->getPropertyValue(sWrittenNumberFormats); + uno::Sequence<sal_Int32> aWasUsed; + if(aAny >>= aWasUsed) + mpNumExport->SetWasUsed(aWasUsed); + } + } + } + } + + // namespaces for user defined attributes + Reference< XMultiServiceFactory > xFactory( mxModel, UNO_QUERY ); + if( xFactory.is() ) + { + try + { + Reference < XInterface > xIfc = + xFactory->createInstance("com.sun.star.xml.NamespaceMap"); + if( xIfc.is() ) + { + Reference< XNameAccess > xNamespaceMap( xIfc, UNO_QUERY ); + if( xNamespaceMap.is() ) + { + const Sequence< OUString > aPrefixes( xNamespaceMap->getElementNames() ); + for( OUString const & prefix : aPrefixes ) + { + OUString aURL; + if( xNamespaceMap->getByName( prefix ) >>= aURL ) + GetNamespaceMap_().Add( prefix, aURL ); + } + } + } + } + catch(const css::uno::Exception&) + { + } + } + + // Determine model type (#i51726#) + DetermineModelType_(); +} + +// XInitialize +void SAL_CALL SvXMLExport::initialize( const uno::Sequence< uno::Any >& aArguments ) +{ + // #93186# we need to queryInterface every single Any with any expected outcome. This variable hold the queryInterface results. + + for( const auto& rAny : aArguments ) + { + Reference<XInterface> xValue; + rAny >>= xValue; + + // status indicator + uno::Reference<task::XStatusIndicator> xTmpStatus( xValue, UNO_QUERY ); + if ( xTmpStatus.is() ) + mxStatusIndicator = xTmpStatus; + + // graphic storage handler + uno::Reference<document::XGraphicStorageHandler> xGraphicStorageHandler(xValue, UNO_QUERY); + if (xGraphicStorageHandler.is()) + mxGraphicStorageHandler = xGraphicStorageHandler; + + // object resolver + uno::Reference<document::XEmbeddedObjectResolver> xTmpObjectResolver( + xValue, UNO_QUERY ); + if ( xTmpObjectResolver.is() ) + mxEmbeddedResolver = xTmpObjectResolver; + + // document handler + uno::Reference<xml::sax::XDocumentHandler> xTmpDocHandler( + xValue, UNO_QUERY ); + if( xTmpDocHandler.is() ) + { + mxHandler = xTmpDocHandler; + rAny >>= mxExtHandler; + + if (mxNumberFormatsSupplier.is() && mpNumExport == nullptr) + mpNumExport.reset( new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier) ); + } + + // property set to transport data across + uno::Reference<beans::XPropertySet> xTmpPropertySet( + xValue, UNO_QUERY ); + if( xTmpPropertySet.is() ) + mxExportInfo = xTmpPropertySet; + } + + if( !mxExportInfo.is() ) + return; + + uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = + mxExportInfo->getPropertySetInfo(); + OUString sPropName( + "BaseURI" ); + if( xPropertySetInfo->hasPropertyByName(sPropName) ) + { + uno::Any aAny = mxExportInfo->getPropertyValue(sPropName); + aAny >>= msOrigFileName; + mpImpl->msPackageURI = msOrigFileName; + mpImpl->SetSchemeOf( msOrigFileName ); + } + OUString sRelPath; + sPropName = "StreamRelPath"; + if( xPropertySetInfo->hasPropertyByName(sPropName) ) + { + uno::Any aAny = mxExportInfo->getPropertyValue(sPropName); + aAny >>= sRelPath; + } + OUString sName; + sPropName = "StreamName"; + if( xPropertySetInfo->hasPropertyByName(sPropName) ) + { + uno::Any aAny = mxExportInfo->getPropertyValue(sPropName); + aAny >>= sName; + } + if( !msOrigFileName.isEmpty() && !sName.isEmpty() ) + { + INetURLObject aBaseURL( msOrigFileName ); + if( !sRelPath.isEmpty() ) + aBaseURL.insertName( sRelPath ); + aBaseURL.insertName( sName ); + msOrigFileName = aBaseURL.GetMainURL(INetURLObject::DecodeMechanism::ToIUri); + } + mpImpl->mStreamName = sName; // Note: may be empty (XSLT) + + // Written OpenDocument file format doesn't fit to the created text document (#i69627#) + const OUString sOutlineStyleAsNormalListStyle( + "OutlineStyleAsNormalListStyle" ); + if( xPropertySetInfo->hasPropertyByName( sOutlineStyleAsNormalListStyle ) ) + { + uno::Any aAny = mxExportInfo->getPropertyValue( sOutlineStyleAsNormalListStyle ); + aAny >>= mpImpl->mbOutlineStyleAsNormalListStyle; + } + + OUString sTargetStorage( "TargetStorage" ); + if( xPropertySetInfo->hasPropertyByName( sTargetStorage ) ) + mxExportInfo->getPropertyValue( sTargetStorage ) >>= mpImpl->mxTargetStorage; + + const OUString sExportTextNumberElement( + "ExportTextNumberElement" ); + if( xPropertySetInfo->hasPropertyByName( sExportTextNumberElement ) ) + { + uno::Any aAny = mxExportInfo->getPropertyValue( sExportTextNumberElement ); + aAny >>= mpImpl->mbExportTextNumberElement; + } +} + +// XFilter +sal_Bool SAL_CALL SvXMLExport::filter( const uno::Sequence< beans::PropertyValue >& aDescriptor ) +{ + // check for xHandler first... should have been supplied in initialize + if( !mxHandler.is() ) + return false; + + try + { + const SvXMLExportFlags nTest = + SvXMLExportFlags::META|SvXMLExportFlags::STYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::SETTINGS; + if( (mnExportFlags & nTest) == nTest && msOrigFileName.isEmpty() ) + { + // evaluate descriptor only for flat files and if a base URI + // has not been provided already + + for( const auto& rProp : aDescriptor ) + { + const OUString& rPropName = rProp.Name; + const Any& rValue = rProp.Value; + + if ( rPropName == "FileName" ) + { + if( !(rValue >>= msOrigFileName ) ) + return false; + } + else if ( rPropName == "FilterName" ) + { + if( !(rValue >>= msFilterName ) ) + return false; + } + } + } + + for( const auto& rProp : aDescriptor ) + { + const OUString& rPropName = rProp.Name; + const Any& rValue = rProp.Value; + + if (rPropName == "SourceShellID") + { + if (!(rValue >>= mpImpl->maSrcShellID)) + return false; + } + else if (rPropName == "DestinationShellID") + { + if (!(rValue >>= mpImpl->maDestShellID)) + return false; + } + else if( rPropName == "ImageFilter") + { + if (!(rValue >>= msImgFilterName)) + return false; + } + } + + + exportDoc( meClass ); + } + catch(const uno::Exception& e) + { + // We must catch exceptions, because according to the + // API definition export must not throw one! + css::uno::Any ex(cppu::getCaughtException()); + OUString sMessage( ex.getValueTypeName() + ": \"" + e.Message + "\""); + if (e.Context.is()) + { + const char* pContext = typeid(*e.Context).name(); + sMessage += " (context: " + OUString::createFromAscii(pContext) + " )"; + } + SetError( XMLERROR_FLAG_ERROR | XMLERROR_FLAG_SEVERE | XMLERROR_API, + Sequence<OUString>(), sMessage, nullptr ); + } + + // return true only if no error occurred + return (mnErrorFlags & (SvXMLErrorFlags::DO_NOTHING|SvXMLErrorFlags::ERROR_OCCURRED)) == SvXMLErrorFlags::NO; +} + +void SAL_CALL SvXMLExport::cancel() +{ + // stop export + Sequence<OUString> aEmptySeq; + SetError(XMLERROR_CANCEL|XMLERROR_FLAG_SEVERE, aEmptySeq); +} + +OUString SAL_CALL SvXMLExport::getName( ) +{ + return msFilterName; +} + +void SAL_CALL SvXMLExport::setName( const OUString& ) +{ + // do nothing, because it is not possible to set the FilterName +} + +// XServiceInfo +OUString SAL_CALL SvXMLExport::getImplementationName( ) +{ + return m_implementationName; +} + +sal_Bool SAL_CALL SvXMLExport::supportsService( const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + +uno::Sequence< OUString > SAL_CALL SvXMLExport::getSupportedServiceNames( ) +{ + return { "com.sun.star.document.ExportFilter", "com.sun.star.xml.XMLExportFilter" }; +} + +OUString +SvXMLExport::EnsureNamespace(OUString const & i_rNamespace) +{ + OUString const aPreferredPrefix("gen"); + OUString sPrefix; + sal_uInt16 nKey( GetNamespaceMap_().GetKeyByName( i_rNamespace ) ); + if( XML_NAMESPACE_UNKNOWN == nKey ) + { + // There is no prefix for the namespace, so + // we have to generate one and have to add it. + sPrefix = aPreferredPrefix; + nKey = GetNamespaceMap_().GetKeyByPrefix( sPrefix ); + sal_Int32 n( 0 ); + OUStringBuffer buf; + while( nKey != USHRT_MAX ) + { + buf.append( aPreferredPrefix ); + buf.append( ++n ); + sPrefix = buf.makeStringAndClear(); + nKey = GetNamespaceMap_().GetKeyByPrefix( sPrefix ); + } + + if (mpImpl->mNamespaceMaps.empty() + || (mpImpl->mNamespaceMaps.top().second != mpImpl->mDepth)) + { + // top was created for lower depth... need a new namespace map! + auto pNew = new SvXMLNamespaceMap( *mpNamespaceMap ); + mpImpl->mNamespaceMaps.push( + ::std::make_pair(std::move(mpNamespaceMap), mpImpl->mDepth) ); + mpNamespaceMap.reset( pNew ); + } + + // add the namespace to the map and as attribute + mpNamespaceMap->Add( sPrefix, i_rNamespace ); + buf.append( GetXMLToken(XML_XMLNS) ); + buf.append( ':' ); + buf.append( sPrefix ); + AddAttribute( buf.makeStringAndClear(), i_rNamespace ); + } + else + { + // If there is a prefix for the namespace, reuse that. + sPrefix = GetNamespaceMap_().GetPrefixByKey( nKey ); + } + return sPrefix; +} + +void SvXMLExport::AddAttributeASCII( sal_uInt16 nPrefixKey, + const char *pName, + const char *pValue ) +{ + OUString sName( OUString::createFromAscii( pName ) ); + OUString sValue( OUString::createFromAscii( pValue ) ); + + mxAttrList->AddAttribute( + GetNamespaceMap_().GetQNameByKey( nPrefixKey, sName ), sValue ); +} + +void SvXMLExport::AddAttribute( sal_uInt16 nPrefixKey, const char *pName, + const OUString& rValue ) +{ + OUString sName( OUString::createFromAscii( pName ) ); + + mxAttrList->AddAttribute( + GetNamespaceMap_().GetQNameByKey( nPrefixKey, sName ), rValue ); +} + +void SvXMLExport::AddAttribute( sal_uInt16 nPrefixKey, const OUString& rName, + const OUString& rValue ) +{ + mxAttrList->AddAttribute( + GetNamespaceMap_().GetQNameByKey( nPrefixKey, rName ), rValue ); +} + +void SvXMLExport::AddAttribute( sal_uInt16 nPrefixKey, + enum XMLTokenEnum eName, + const OUString& rValue ) +{ + mxAttrList->AddAttribute( + GetNamespaceMap_().GetQNameByKey( nPrefixKey, GetXMLToken(eName) ), + rValue ); +} + +void SvXMLExport::AddAttribute( sal_uInt16 nPrefixKey, + enum XMLTokenEnum eName, + enum XMLTokenEnum eValue) +{ + mxAttrList->AddAttribute( + GetNamespaceMap_().GetQNameByKey( nPrefixKey, GetXMLToken(eName) ), + GetXMLToken(eValue) ); +} + +void SvXMLExport::AddAttribute( const OUString& rQName, + const OUString& rValue ) +{ + mxAttrList->AddAttribute( + rQName, + rValue ); +} + +void SvXMLExport::AddAttribute( const OUString& rQName, + enum ::xmloff::token::XMLTokenEnum eValue ) +{ + mxAttrList->AddAttribute( + rQName, + GetXMLToken(eValue) ); +} + +void SvXMLExport::AddLanguageTagAttributes( sal_uInt16 nPrefix, sal_uInt16 nPrefixRfc, + const css::lang::Locale& rLocale, bool bWriteEmpty ) +{ + if (rLocale.Variant.isEmpty()) + { + // Per convention The BCP 47 string is always stored in Variant, if + // that is empty we have a plain language-country combination, no need + // to convert to LanguageTag first. Also catches the case of empty + // locale denoting system locale. + xmloff::token::XMLTokenEnum eLanguage, eCountry; + eLanguage = XML_LANGUAGE; + eCountry = XML_COUNTRY; + if (bWriteEmpty || !rLocale.Language.isEmpty()) + AddAttribute( nPrefix, eLanguage, rLocale.Language); + if (bWriteEmpty || !rLocale.Country.isEmpty()) + AddAttribute( nPrefix, eCountry, rLocale.Country); + } + else + { + LanguageTag aLanguageTag( rLocale); + AddLanguageTagAttributes( nPrefix, nPrefixRfc, aLanguageTag, bWriteEmpty); + } +} + +void SvXMLExport::AddLanguageTagAttributes( sal_uInt16 nPrefix, sal_uInt16 nPrefixRfc, + const LanguageTag& rLanguageTag, bool bWriteEmpty ) +{ + if (rLanguageTag.isIsoODF()) + { + if (bWriteEmpty || !rLanguageTag.isSystemLocale()) + { + AddAttribute( nPrefix, XML_LANGUAGE, rLanguageTag.getLanguage()); + if (rLanguageTag.hasScript() && getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012) + AddAttribute( nPrefix, XML_SCRIPT, rLanguageTag.getScript()); + if (bWriteEmpty || !rLanguageTag.getCountry().isEmpty()) + AddAttribute( nPrefix, XML_COUNTRY, rLanguageTag.getCountry()); + } + } + else + { + if (getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012) + AddAttribute( nPrefixRfc, XML_RFC_LANGUAGE_TAG, rLanguageTag.getBcp47()); + // Also in case of non-pure-ISO tag store best matching fo: attributes + // for consumers not handling *:rfc-language-tag, ensuring that only + // valid ISO codes are stored. Here the bWriteEmpty parameter has no + // meaning. + OUString aLanguage, aScript, aCountry; + rLanguageTag.getIsoLanguageScriptCountry( aLanguage, aScript, aCountry); + if (!aLanguage.isEmpty()) + { + AddAttribute( nPrefix, XML_LANGUAGE, aLanguage); + if (!aScript.isEmpty() && getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012) + AddAttribute( nPrefix, XML_SCRIPT, aScript); + if (!aCountry.isEmpty()) + AddAttribute( nPrefix, XML_COUNTRY, aCountry); + } + } +} + +void SvXMLExport::AddAttributeList( const uno::Reference< xml::sax::XAttributeList >& xAttrList ) +{ + if( xAttrList.is()) + mxAttrList->AppendAttributeList( xAttrList ); +} + +void SvXMLExport::ClearAttrList() +{ + mxAttrList->Clear(); +} + +#ifdef DBG_UTIL +void SvXMLExport::CheckAttrList() +{ + SAL_WARN_IF( mxAttrList->getLength(), "xmloff.core", "XMLExport::CheckAttrList: list is not empty" ); +} +#endif + +void SvXMLExport::ImplExportMeta() +{ + CheckAttrList(); + + ExportMeta_(); +} + +void SvXMLExport::ImplExportSettings() +{ + CheckAttrList(); + + ::std::vector< SettingsGroup > aSettings; + sal_Int32 nSettingsCount = 0; + + // view settings + uno::Sequence< beans::PropertyValue > aViewSettings; + GetViewSettingsAndViews( aViewSettings ); + aSettings.emplace_back( XML_VIEW_SETTINGS, aViewSettings ); + nSettingsCount += aViewSettings.getLength(); + + // configuration settings + uno::Sequence<beans::PropertyValue> aConfigSettings; + GetConfigurationSettings( aConfigSettings ); + aSettings.emplace_back( XML_CONFIGURATION_SETTINGS, aConfigSettings ); + nSettingsCount += aConfigSettings.getLength(); + + // any document specific settings + nSettingsCount += GetDocumentSpecificSettings( aSettings ); + + { + SvXMLElementExport aElem( *this, + nSettingsCount != 0, + XML_NAMESPACE_OFFICE, XML_SETTINGS, + true, true ); + + SettingsExportFacade aSettingsExportContext( *this ); + XMLSettingsExportHelper aSettingsExportHelper( aSettingsExportContext ); + + for (auto const& settings : aSettings) + { + if ( !settings.aSettings.hasElements() ) + continue; + + const OUString& sSettingsName( GetXMLToken( settings.eGroupName ) ); + OUString sQName = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OOO, sSettingsName ); + aSettingsExportHelper.exportAllSettings( settings.aSettings, sQName ); + } + } +} + +void SvXMLExport::ImplExportStyles() +{ + CheckAttrList(); + + { + // <style:styles> + SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_STYLES, + true, true ); + + ExportStyles_( false ); + } + + // transfer style names (+ families) TO other components (if appropriate) + if( ( !( mnExportFlags & SvXMLExportFlags::CONTENT ) ) && mxExportInfo.is() ) + { + static OUString sStyleNames( "StyleNames" ); + static OUString sStyleFamilies( "StyleFamilies" ); + uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxExportInfo->getPropertySetInfo(); + if ( xPropertySetInfo->hasPropertyByName( sStyleNames ) && xPropertySetInfo->hasPropertyByName( sStyleFamilies ) ) + { + Sequence<sal_Int32> aStyleFamilies; + Sequence<OUString> aStyleNames; + mxAutoStylePool->GetRegisteredNames( aStyleFamilies, aStyleNames ); + mxExportInfo->setPropertyValue( sStyleNames, makeAny( aStyleNames ) ); + mxExportInfo->setPropertyValue( sStyleFamilies, + makeAny( aStyleFamilies ) ); + } + } +} + +void SvXMLExport::ImplExportAutoStyles() +{ + // transfer style names (+ families) FROM other components (if appropriate) + OUString sStyleNames( "StyleNames" ); + OUString sStyleFamilies( "StyleFamilies" ); + if( ( !( mnExportFlags & SvXMLExportFlags::STYLES ) ) + && mxExportInfo.is() + && mxExportInfo->getPropertySetInfo()->hasPropertyByName( sStyleNames ) + && mxExportInfo->getPropertySetInfo()->hasPropertyByName( sStyleFamilies ) ) + { + Sequence<sal_Int32> aStyleFamilies; + mxExportInfo->getPropertyValue( sStyleFamilies ) >>= aStyleFamilies; + Sequence<OUString> aStyleNames; + mxExportInfo->getPropertyValue( sStyleNames ) >>= aStyleNames; + mxAutoStylePool->RegisterNames( aStyleFamilies, aStyleNames ); + } + + { + // <style:automatic-styles> + SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, + XML_AUTOMATIC_STYLES, true, true ); + + ExportAutoStyles_(); + } +} + +void SvXMLExport::ImplExportMasterStyles() +{ + // <style:master-styles> + SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_MASTER_STYLES, + true, true ); + + ExportMasterStyles_(); +} + +void SvXMLExport::ImplExportContent() +{ + CheckAttrList(); + + CheckAttrList(); + + { + SvXMLElementExport aElement( *this, XML_NAMESPACE_OFFICE, XML_BODY, + true, true ); + { + XMLTokenEnum eClass = meClass; + if( XML_TEXT_GLOBAL == eClass ) + { + AddAttribute( XML_NAMESPACE_TEXT, XML_GLOBAL, + GetXMLToken( XML_TRUE ) ); + eClass = XML_TEXT; + } + if ( XML_GRAPHICS == eClass ) + eClass = XML_DRAWING; + // <office:body ...> + SetBodyAttributes(); + SvXMLElementExport aElem( *this, meClass != XML_TOKEN_INVALID, + XML_NAMESPACE_OFFICE, eClass, + true, true ); + + ExportContent_(); + } + } +} + +void SvXMLExport::SetBodyAttributes() +{ +} + +static void +lcl_AddGrddl(SvXMLExport const & rExport, const SvXMLExportFlags /*nExportMode*/) +{ + // check version >= 1.2 + switch (rExport.getSaneDefaultVersion()) { + case SvtSaveOptions::ODFSVER_011: // fall through + case SvtSaveOptions::ODFSVER_010: return; + default: break; + } + + // #i115030#: disabled, the XSLT is not finished, and not available via HTTP +#if 0 + if (SvXMLExportFlags::SETTINGS != nExportMode) // meta, content, styles + { + rExport.AddAttribute( XML_NAMESPACE_GRDDL, XML_TRANSFORMATION, + OUString("http://FIXME") ); + } +#endif +} + +void SvXMLExport::addChaffWhenEncryptedStorage() +{ + uno::Reference< embed::XEncryptionProtectedSource2 > xEncr(mpImpl->mxTargetStorage, uno::UNO_QUERY); + + if (xEncr.is() && xEncr->hasEncryptionData() && mxExtHandler.is()) + { + mxExtHandler->comment(OStringToOUString(comphelper::xml::makeXMLChaff(), RTL_TEXTENCODING_ASCII_US)); + } +} + +auto SvXMLExport::GetODFVersionAttributeValue() const -> char const* +{ + char const* pVersion(nullptr); + switch (getSaneDefaultVersion()) + { + case SvtSaveOptions::ODFSVER_013_EXTENDED: [[fallthrough]]; + case SvtSaveOptions::ODFSVER_013: pVersion = "1.3"; break; + case SvtSaveOptions::ODFSVER_012_EXTENDED: [[fallthrough]]; + case SvtSaveOptions::ODFSVER_012_EXT_COMPAT: [[fallthrough]]; + case SvtSaveOptions::ODFSVER_012: pVersion = "1.2"; break; + case SvtSaveOptions::ODFSVER_011: pVersion = "1.1"; break; + case SvtSaveOptions::ODFSVER_010: break; + + default: + assert(!"xmloff::SvXMLExport::exportDoc(), unexpected odf default version!"); + } + return pVersion; +} + +ErrCode SvXMLExport::exportDoc( enum ::xmloff::token::XMLTokenEnum eClass ) +{ + bool bOwnGraphicResolver = false; + bool bOwnEmbeddedResolver = false; + + if (!mxGraphicStorageHandler.is() || !mxEmbeddedResolver.is()) + { + Reference< XMultiServiceFactory > xFactory( mxModel, UNO_QUERY ); + if( xFactory.is() ) + { + try + { + if (!mxGraphicStorageHandler.is()) + { + mxGraphicStorageHandler.set(xFactory->createInstance( "com.sun.star.document.ExportGraphicStorageHandler"), UNO_QUERY); + bOwnGraphicResolver = mxGraphicStorageHandler.is(); + } + + if( !mxEmbeddedResolver.is() ) + { + mxEmbeddedResolver.set( + xFactory->createInstance( "com.sun.star.document.ExportEmbeddedObjectResolver" ), UNO_QUERY); + bOwnEmbeddedResolver = mxEmbeddedResolver.is(); + } + } + catch(const css::uno::Exception&) + { + } + } + } + if( (getExportFlags() & SvXMLExportFlags::OASIS) == SvXMLExportFlags::NONE ) + { + try + { + static ::comphelper::PropertyMapEntry const aInfoMap[] = + { + { OUString("Class"), 0, + ::cppu::UnoType<OUString>::get(), + PropertyAttribute::MAYBEVOID, 0}, + { OUString(), 0, css::uno::Type(), 0, 0 } + }; + Reference< XPropertySet > xConvPropSet( + ::comphelper::GenericPropertySet_CreateInstance( + new ::comphelper::PropertySetInfo( aInfoMap ) ) ); + + xConvPropSet->setPropertyValue( "Class", Any(GetXMLToken( eClass )) ); + + Reference< XPropertySet > xPropSet = + mxExportInfo.is() + ? PropertySetMerger_CreateInstance( mxExportInfo, + xConvPropSet ) + : xConvPropSet; + + Sequence<Any> aArgs( 3 ); + aArgs[0] <<= mxHandler; + aArgs[1] <<= xPropSet; + aArgs[2] <<= mxModel; + + // get filter component + Reference< xml::sax::XDocumentHandler > xTmpDocHandler( + m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext("com.sun.star.comp.Oasis2OOoTransformer", aArgs, m_xContext), + UNO_QUERY); + SAL_WARN_IF(!xTmpDocHandler.is(), "xmloff.core", "can't instantiate OASIS transformer component" ); + if( xTmpDocHandler.is() ) + { + mxHandler = xTmpDocHandler; + mxExtHandler.set( mxHandler, UNO_QUERY ); + } + } + catch(const css::uno::Exception&) + { + } + } + + mxHandler->startDocument(); + + addChaffWhenEncryptedStorage(); + + // <office:document ...> + CheckAttrList(); + + // namespace attributes + // ( The namespace decls should be first attributes in the element; + // some faulty XML parsers (JAXP1.1) have a problem with this, + // also it's more elegant ) + sal_uInt16 nPos = mpNamespaceMap->GetFirstKey(); + while( USHRT_MAX != nPos ) + { + mxAttrList->AddAttribute( mpNamespaceMap->GetAttrNameByKey( nPos ), + mpNamespaceMap->GetNameByKey( nPos ) ); + nPos = mpNamespaceMap->GetNextKey( nPos ); + } + + // office:version = ... + const char*const pVersion = GetODFVersionAttributeValue(); + + if (pVersion) + { + AddAttribute( XML_NAMESPACE_OFFICE, XML_VERSION, + OUString::createFromAscii(pVersion) ); + } + + { + enum XMLTokenEnum eRootService = XML_TOKEN_INVALID; + const SvXMLExportFlags nExportMode = mnExportFlags & (SvXMLExportFlags::META|SvXMLExportFlags::STYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::SETTINGS); + + lcl_AddGrddl(*this, nExportMode); + + if( SvXMLExportFlags::META == nExportMode ) + { + // export only meta + eRootService = XML_DOCUMENT_META; + } + else if ( SvXMLExportFlags::SETTINGS == nExportMode ) + { + // export only settings + eRootService = XML_DOCUMENT_SETTINGS; + } + else if( SvXMLExportFlags::STYLES == nExportMode ) + { + // export only styles + eRootService = XML_DOCUMENT_STYLES; + } + else if( SvXMLExportFlags::CONTENT == nExportMode ) + { + // export only content + eRootService = XML_DOCUMENT_CONTENT; + } + else + { + // the god'ol one4all element + eRootService = XML_DOCUMENT; + // office:mimetype = ... (only for stream containing the content) + if( eClass != XML_TOKEN_INVALID ) + { + OUString aTmp = "application/vnd.oasis.opendocument." + GetXMLToken( eClass ); + AddAttribute( XML_NAMESPACE_OFFICE, XML_MIMETYPE, aTmp ); + } + } + + SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, eRootService, true, true ); + + // meta information + if( mnExportFlags & SvXMLExportFlags::META ) + ImplExportMeta(); + + // settings + if( mnExportFlags & SvXMLExportFlags::SETTINGS ) + ImplExportSettings(); + + // scripts + if( mnExportFlags & SvXMLExportFlags::SCRIPTS ) + ExportScripts_(); + + // font declarations + if( mnExportFlags & SvXMLExportFlags::FONTDECLS ) + ExportFontDecls_(); + + // styles + if( mnExportFlags & SvXMLExportFlags::STYLES ) + ImplExportStyles(); + + // autostyles + if( mnExportFlags & SvXMLExportFlags::AUTOSTYLES ) + ImplExportAutoStyles(); + + // masterstyles + if( mnExportFlags & SvXMLExportFlags::MASTERSTYLES ) + ImplExportMasterStyles(); + + // content + if( mnExportFlags & SvXMLExportFlags::CONTENT ) + ImplExportContent(); + } + + mxHandler->endDocument(); + + if( bOwnGraphicResolver ) + { + uno::Reference<XComponent> xComp(mxGraphicStorageHandler, UNO_QUERY); + xComp->dispose(); + } + + if( bOwnEmbeddedResolver ) + { + Reference< XComponent > xComp( mxEmbeddedResolver, UNO_QUERY ); + xComp->dispose(); + } + + return ERRCODE_NONE; +} + +void SvXMLExport::ResetNamespaceMap() +{ + mpNamespaceMap.reset( new SvXMLNamespaceMap ); +} + +OUString const & SvXMLExport::GetSourceShellID() const +{ + return mpImpl->maSrcShellID; +} + +OUString const & SvXMLExport::GetDestinationShellID() const +{ + return mpImpl->maDestShellID; +} + +void SvXMLExport::ExportMeta_() +{ + OUString generator( ::utl::DocInfoHelper::GetGeneratorString() ); + Reference< XDocumentPropertiesSupplier > xDocPropsSupplier(mxModel, + UNO_QUERY); + if (xDocPropsSupplier.is()) { + Reference<XDocumentProperties> xDocProps( + xDocPropsSupplier->getDocumentProperties()); + if (!xDocProps.is()) throw; + // update generator here + xDocProps->setGenerator(generator); + rtl::Reference<SvXMLMetaExport> pMeta = new SvXMLMetaExport(*this, xDocProps); + pMeta->Export(); + } else { + // office:meta + SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_META, + true, true ); + { + // BM: #i60323# export generator even if xInfoProp is empty (which is the + // case for charts). The generator does not depend on xInfoProp + SvXMLElementExport anElem( *this, XML_NAMESPACE_META, XML_GENERATOR, + true, true ); + Characters(generator); + } + } +} + +void SvXMLExport::ExportScripts_() +{ + SvXMLElementExport aElement( *this, XML_NAMESPACE_OFFICE, XML_SCRIPTS, true, true ); + + // export Basic macros (only for FlatXML) + if ( mnExportFlags & SvXMLExportFlags::EMBEDDED ) + { + OUString aValue( GetNamespaceMap().GetPrefixByKey( XML_NAMESPACE_OOO ) + ":Basic" ); + AddAttribute( XML_NAMESPACE_SCRIPT, XML_LANGUAGE, aValue ); + + SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_SCRIPT, true, true ); + + // initialize Basic + if ( mxModel.is() ) + { + Reference< beans::XPropertySet > xPSet( mxModel, UNO_QUERY ); + if ( xPSet.is() ) + xPSet->getPropertyValue("BasicLibraries"); + } + + Reference < XDocumentHandler > xHdl( new XMLBasicExportFilter( mxHandler ) ); + Reference< document::XXMLBasicExporter > xExporter = document::XMLOasisBasicExporter::createWithHandler( m_xContext, xHdl ); + + xExporter->setSourceDocument( mxModel ); + Sequence< PropertyValue > aMediaDesc( 0 ); + xExporter->filter( aMediaDesc ); + } + + // export document events + Reference< document::XEventsSupplier > xEvents( GetModel(), UNO_QUERY ); + GetEventExport().Export( xEvents ); +} + +void SvXMLExport::ExportFontDecls_() +{ + if( mxFontAutoStylePool.is() ) + mxFontAutoStylePool->exportXML(); +} + +void SvXMLExport::ExportStyles_( bool ) +{ + uno::Reference< lang::XMultiServiceFactory > xFact( GetModel(), uno::UNO_QUERY ); + if( xFact.is()) + { + // export (fill-)gradient-styles + try + { + uno::Reference< container::XNameAccess > xGradient( xFact->createInstance("com.sun.star.drawing.GradientTable"), uno::UNO_QUERY ); + if( xGradient.is() ) + { + XMLGradientStyleExport aGradientStyle( *this ); + + if( xGradient->hasElements() ) + { + const uno::Sequence< OUString > aNamesSeq ( xGradient->getElementNames() ); + for( const OUString& rStrName : aNamesSeq ) + { + try + { + uno::Any aValue = xGradient->getByName( rStrName ); + + aGradientStyle.exportXML( rStrName, aValue ); + } + catch(const container::NoSuchElementException&) + { + } + } + } + } + } + catch(const lang::ServiceNotRegisteredException&) + { + } + + // export (fill-)hatch-styles + try + { + uno::Reference< container::XNameAccess > xHatch( xFact->createInstance("com.sun.star.drawing.HatchTable"), uno::UNO_QUERY ); + if( xHatch.is() ) + { + XMLHatchStyleExport aHatchStyle( *this ); + + if( xHatch->hasElements() ) + { + const uno::Sequence< OUString > aNamesSeq ( xHatch->getElementNames() ); + for( const OUString& rStrName : aNamesSeq ) + { + try + { + uno::Any aValue = xHatch->getByName( rStrName ); + + aHatchStyle.exportXML( rStrName, aValue ); + } + catch(const container::NoSuchElementException&) + {} + } + } + } + } + catch(const lang::ServiceNotRegisteredException&) + { + } + + // export (fill-)bitmap-styles + try + { + uno::Reference< container::XNameAccess > xBitmap( xFact->createInstance("com.sun.star.drawing.BitmapTable"), uno::UNO_QUERY ); + if( xBitmap.is() ) + { + if( xBitmap->hasElements() ) + { + const uno::Sequence< OUString > aNamesSeq ( xBitmap->getElementNames() ); + for( const OUString& rStrName : aNamesSeq ) + { + try + { + uno::Any aValue = xBitmap->getByName( rStrName ); + + XMLImageStyle::exportXML( rStrName, aValue, *this ); + } + catch(const container::NoSuchElementException&) + { + } + } + } + } + } + catch(const lang::ServiceNotRegisteredException&) + { + } + + // export transparency-gradient -styles + try + { + uno::Reference< container::XNameAccess > xTransGradient( xFact->createInstance("com.sun.star.drawing.TransparencyGradientTable"), uno::UNO_QUERY ); + if( xTransGradient.is() ) + { + XMLTransGradientStyleExport aTransGradientstyle( *this ); + + if( xTransGradient->hasElements() ) + { + const uno::Sequence< OUString > aNamesSeq ( xTransGradient->getElementNames() ); + for( const OUString& rStrName : aNamesSeq ) + { + try + { + uno::Any aValue = xTransGradient->getByName( rStrName ); + + aTransGradientstyle.exportXML( rStrName, aValue ); + } + catch(const container::NoSuchElementException&) + { + } + } + } + } + } + catch(const lang::ServiceNotRegisteredException&) + { + } + + // export marker-styles + try + { + uno::Reference< container::XNameAccess > xMarker( xFact->createInstance("com.sun.star.drawing.MarkerTable"), uno::UNO_QUERY ); + if( xMarker.is() ) + { + XMLMarkerStyleExport aMarkerStyle( *this ); + + if( xMarker->hasElements() ) + { + const uno::Sequence< OUString > aNamesSeq ( xMarker->getElementNames() ); + for( const OUString& rStrName : aNamesSeq ) + { + try + { + uno::Any aValue = xMarker->getByName( rStrName ); + + aMarkerStyle.exportXML( rStrName, aValue ); + } + catch(const container::NoSuchElementException&) + { + } + } + } + } + } + catch(const lang::ServiceNotRegisteredException&) + { + } + + // export dash-styles + try + { + uno::Reference< container::XNameAccess > xDashes( xFact->createInstance("com.sun.star.drawing.DashTable"), uno::UNO_QUERY ); + if( xDashes.is() ) + { + XMLDashStyleExport aDashStyle( *this ); + + if( xDashes->hasElements() ) + { + const uno::Sequence< OUString > aNamesSeq ( xDashes->getElementNames() ); + for( const OUString& rStrName : aNamesSeq ) + { + try + { + uno::Any aValue = xDashes->getByName( rStrName ); + + aDashStyle.exportXML( rStrName, aValue ); + } + catch(const container::NoSuchElementException&) + { + } + } + } + } + } + catch(const lang::ServiceNotRegisteredException&) + { + } + } +} + +XMLTextParagraphExport* SvXMLExport::CreateTextParagraphExport() +{ + return new XMLTextParagraphExport( *this, *GetAutoStylePool() ); +} + +XMLShapeExport* SvXMLExport::CreateShapeExport() +{ + return new XMLShapeExport(*this); +} + +SvXMLAutoStylePoolP* SvXMLExport::CreateAutoStylePool() +{ + return new SvXMLAutoStylePoolP(*this); +} + +void SvXMLExport::collectAutoStyles() +{ +} + +XMLPageExport* SvXMLExport::CreatePageExport() +{ + return new XMLPageExport( *this ); +} + +SchXMLExportHelper* SvXMLExport::CreateChartExport() +{ + return new SchXMLExportHelper(*this, *GetAutoStylePool()); +} + +XMLFontAutoStylePool* SvXMLExport::CreateFontAutoStylePool() +{ + return new XMLFontAutoStylePool( *this ); +} + +xmloff::OFormLayerXMLExport* SvXMLExport::CreateFormExport() +{ + return new xmloff::OFormLayerXMLExport(*this); +} + +void SvXMLExport::GetViewSettingsAndViews(uno::Sequence<beans::PropertyValue>& rProps) +{ + GetViewSettings(rProps); + uno::Reference<document::XViewDataSupplier> xViewDataSupplier(GetModel(), uno::UNO_QUERY); + if(xViewDataSupplier.is()) + { + uno::Reference<container::XIndexAccess> xIndexAccess; + xViewDataSupplier->setViewData( xIndexAccess ); // make sure we get a newly created sequence + xIndexAccess = xViewDataSupplier->getViewData(); + bool bAdd = false; + uno::Any aAny; + if(xIndexAccess.is() && xIndexAccess->hasElements() ) + { + sal_Int32 nCount = xIndexAccess->getCount(); + for (sal_Int32 i = 0; i < nCount; i++) + { + aAny = xIndexAccess->getByIndex(i); + uno::Sequence<beans::PropertyValue> aProps; + if( aAny >>= aProps ) + { + if( aProps.hasElements() ) + { + bAdd = true; + break; + } + } + } + } + + if( bAdd ) + { + sal_Int32 nOldLength(rProps.getLength()); + rProps.realloc(nOldLength + 1); + beans::PropertyValue aProp; + aProp.Name = "Views"; + aProp.Value <<= xIndexAccess; + rProps[nOldLength] = aProp; + } + } +} + +void SvXMLExport::GetViewSettings(uno::Sequence<beans::PropertyValue>&) +{ +} + +void SvXMLExport::GetConfigurationSettings(uno::Sequence<beans::PropertyValue>&) +{ +} + +sal_Int32 SvXMLExport::GetDocumentSpecificSettings( ::std::vector< SettingsGroup >& ) +{ + return 0; +} + +void SvXMLExport::collectDataStyles(bool bFromUsedStyles) +{ + Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(GetModel(), uno::UNO_QUERY); + if (!xStyleFamiliesSupplier.is()) + return; + + Reference<container::XNameAccess> xStylesFamilies(xStyleFamiliesSupplier->getStyleFamilies()); + if (!xStylesFamilies.is()) + return; + + Reference<container::XIndexAccess> xCellStyles(xStylesFamilies->getByName("CellStyles"), uno::UNO_QUERY); + if (!xCellStyles.is()) + return; + + sal_Int32 nCount(xCellStyles->getCount()); + for (sal_Int32 i = 0; i < nCount; ++i) + { + Reference<style::XStyle> xStyle(xCellStyles->getByIndex(i), uno::UNO_QUERY); + if (bFromUsedStyles && !xStyle->isInUse()) + continue; + + Reference<beans::XPropertySet> xCellProperties(xStyle, uno::UNO_QUERY); + if (xCellProperties.is()) + { + sal_Int32 nNumberFormat = 0; + if (xCellProperties->getPropertyValue("NumberFormat") >>= nNumberFormat) + addDataStyle(nNumberFormat); + } + } +} + +void SvXMLExport::addDataStyle(const sal_Int32 nNumberFormat, bool /*bTimeFormat*/ ) +{ + if(mpNumExport) + mpNumExport->SetUsed(nNumberFormat); +} + +void SvXMLExport::exportDataStyles() +{ + if(mpNumExport) + mpNumExport->Export(false); +} + +void SvXMLExport::exportAutoDataStyles() +{ + if(mpNumExport) + mpNumExport->Export(true); + + if (mxFormExport.is()) + mxFormExport->exportAutoControlNumberStyles(); +} + +OUString SvXMLExport::getDataStyleName(const sal_Int32 nNumberFormat, bool /*bTimeFormat*/ ) const +{ + OUString sTemp; + if(mpNumExport) + sTemp = mpNumExport->GetStyleName(nNumberFormat); + return sTemp; +} + +void SvXMLExport::exportAnnotationMeta(const uno::Reference<drawing::XShape>&) +{ +} + +sal_Int32 SvXMLExport::dataStyleForceSystemLanguage(sal_Int32 nFormat) const +{ + return ( mpNumExport != nullptr ) + ? mpNumExport->ForceSystemLanguage( nFormat ) : nFormat; +} + +OUString SvXMLExport::AddEmbeddedXGraphic(uno::Reference<graphic::XGraphic> const & rxGraphic, OUString & rOutMimeType, OUString const & rRequestedName) +{ + OUString sURL; + + Graphic aGraphic(rxGraphic); + OUString aOriginURL = aGraphic.getOriginURL(); + + if (!aOriginURL.isEmpty()) + { + sURL = GetRelativeReference(aOriginURL); + } + else + { + if (mxGraphicStorageHandler.is()) + { + if (!(getExportFlags() & SvXMLExportFlags::EMBEDDED)) + sURL = mxGraphicStorageHandler->saveGraphicByName(rxGraphic, rOutMimeType, rRequestedName); + } + } + return sURL; +} + +bool SvXMLExport::GetGraphicMimeTypeFromStream(uno::Reference<graphic::XGraphic> const & rxGraphic, OUString & rOutMimeType) +{ + if (mxGraphicStorageHandler.is()) + { + Reference<XInputStream> xInputStream(mxGraphicStorageHandler->createInputStream(rxGraphic)); + if (xInputStream.is()) + { + rOutMimeType = comphelper::GraphicMimeTypeHelper::GetMimeTypeForImageStream(xInputStream); + return true; + } + } + + return false; +} + +bool SvXMLExport::AddEmbeddedXGraphicAsBase64(uno::Reference<graphic::XGraphic> const & rxGraphic) +{ + if ((getExportFlags() & SvXMLExportFlags::EMBEDDED) && + mxGraphicStorageHandler.is()) + { + Reference<XInputStream> xInputStream(mxGraphicStorageHandler->createInputStream(rxGraphic)); + if (xInputStream.is()) + { + Graphic aGraphic(rxGraphic); + if (aGraphic.getOriginURL().isEmpty()) // don't add the base64 if the origin URL is set (image is from an external URL) + { + XMLBase64Export aBase64Exp(*this); + return aBase64Exp.exportOfficeBinaryDataElement(xInputStream); + } + } + } + + return false; +} + +OUString SvXMLExport::AddEmbeddedObject( const OUString& rEmbeddedObjectURL ) +{ + OUString sRet; + bool bSupportedURL = rEmbeddedObjectURL.startsWith(XML_EMBEDDEDOBJECT_URL_BASE) || + rEmbeddedObjectURL.startsWith(XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE); + if (bSupportedURL && mxEmbeddedResolver.is()) + { + sRet = mxEmbeddedResolver->resolveEmbeddedObjectURL(rEmbeddedObjectURL); + } + else + sRet = GetRelativeReference( rEmbeddedObjectURL ); + + return sRet; +} + +bool SvXMLExport::AddEmbeddedObjectAsBase64( const OUString& rEmbeddedObjectURL ) +{ + bool bRet = false; + bool bSupportedURL = rEmbeddedObjectURL.startsWith(XML_EMBEDDEDOBJECT_URL_BASE) || + rEmbeddedObjectURL.startsWith(XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE); + if (bSupportedURL && mxEmbeddedResolver.is()) + { + Reference < XNameAccess > xNA( mxEmbeddedResolver, UNO_QUERY ); + if( xNA.is() ) + { + Any aAny = xNA->getByName( rEmbeddedObjectURL ); + Reference < XInputStream > xIn; + aAny >>= xIn; + if( xIn.is() ) + { + XMLBase64Export aBase64Exp( *this ); + bRet = aBase64Exp.exportOfficeBinaryDataElement( xIn ); + } + } + } + + return bRet; +} + +OUString SvXMLExport::EncodeStyleName( + const OUString& rName, + bool *pEncoded ) const +{ + return GetMM100UnitConverter().encodeStyleName( rName, pEncoded ); +} + +ProgressBarHelper* SvXMLExport::GetProgressBarHelper() +{ + if (!mpProgressBarHelper) + { + mpProgressBarHelper.reset( new ProgressBarHelper(mxStatusIndicator, true) ); + + if (mxExportInfo.is()) + { + uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxExportInfo->getPropertySetInfo(); + if (xPropertySetInfo.is()) + { + OUString sProgressRange(XML_PROGRESSRANGE); + OUString sProgressMax(XML_PROGRESSMAX); + OUString sProgressCurrent(XML_PROGRESSCURRENT); + OUString sRepeat(XML_PROGRESSREPEAT); + if (xPropertySetInfo->hasPropertyByName(sProgressMax) && + xPropertySetInfo->hasPropertyByName(sProgressCurrent) && + xPropertySetInfo->hasPropertyByName(sProgressRange)) + { + uno::Any aAny; + sal_Int32 nProgressMax(0); + sal_Int32 nProgressCurrent(0); + sal_Int32 nProgressRange(0); + aAny = mxExportInfo->getPropertyValue(sProgressRange); + if (aAny >>= nProgressRange) + mpProgressBarHelper->SetRange(nProgressRange); + aAny = mxExportInfo->getPropertyValue(sProgressMax); + if (aAny >>= nProgressMax) + mpProgressBarHelper->SetReference(nProgressMax); + aAny = mxExportInfo->getPropertyValue(sProgressCurrent); + if (aAny >>= nProgressCurrent) + mpProgressBarHelper->SetValue(nProgressCurrent); + } + if (xPropertySetInfo->hasPropertyByName(sRepeat)) + { + uno::Any aAny = mxExportInfo->getPropertyValue(sRepeat); + if (aAny.getValueType() == cppu::UnoType<bool>::get()) + mpProgressBarHelper->SetRepeat(::cppu::any2bool(aAny)); + else { + SAL_WARN("xmloff.core", "why is it no boolean?" ); + } + } + } + } + } + return mpProgressBarHelper.get(); +} + +XMLEventExport& SvXMLExport::GetEventExport() +{ + if( nullptr == mpEventExport) + { + // create EventExport on demand + mpEventExport.reset( new XMLEventExport(*this) ); + + // and register standard handlers + names + mpEventExport->AddHandler("StarBasic", std::make_unique<XMLStarBasicExportHandler>()); + mpEventExport->AddHandler("Script", std::make_unique<XMLScriptExportHandler>()); + mpEventExport->AddTranslationTable(aStandardEventTable); + } + + return *mpEventExport; +} + +XMLImageMapExport& SvXMLExport::GetImageMapExport() +{ + // image map export, create on-demand + if( nullptr == mpImageMapExport ) + { + mpImageMapExport.reset( new XMLImageMapExport(*this) ); + } + + return *mpImageMapExport; +} + +// XUnoTunnel & co +UNO3_GETIMPLEMENTATION_IMPL(SvXMLExport); + +void SvXMLExport::ExportEmbeddedOwnObject( Reference< XComponent > const & rComp ) +{ + OUString sFilterService; + + Reference < lang::XServiceInfo > xServiceInfo( rComp, UNO_QUERY ); + if( xServiceInfo.is() ) + { + const XMLServiceMapEntry_Impl *pEntry = aServiceMap; + while( pEntry->sModelService ) + { + OUString sModelService( pEntry->sModelService, + pEntry->nModelServiceLen, + RTL_TEXTENCODING_ASCII_US ); + if( xServiceInfo->supportsService( sModelService ) ) + { + sFilterService = OUString( pEntry->sFilterService, + pEntry->nFilterServiceLen, + RTL_TEXTENCODING_ASCII_US ); + break; + } + pEntry++; + } + } + + SAL_WARN_IF( !sFilterService.getLength(), "xmloff.core", "no export filter for own object" ); + + if( sFilterService.isEmpty() ) + return; + + Reference < XDocumentHandler > xHdl = + new XMLEmbeddedObjectExportFilter( mxHandler ); + + Sequence < Any > aArgs( 1 ); + aArgs[0] <<= xHdl; + + Reference< document::XExporter > xExporter( + m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(sFilterService, aArgs, m_xContext), + UNO_QUERY); + SAL_WARN_IF( !xExporter.is(), "xmloff.core", "can't instantiate export filter component for own object" ); + if( !xExporter.is() ) + return; + + xExporter->setSourceDocument( rComp ); + + Reference<XFilter> xFilter( xExporter, UNO_QUERY ); + + Sequence < PropertyValue > aMediaDesc( 0 ); + xFilter->filter( aMediaDesc ); +} + +OUString SvXMLExport::GetRelativeReference(const OUString& rValue) +{ + OUString sValue( rValue ); + // #i65474# handling of fragment URLs ("#...") is undefined + // they are stored 'as is' + uno::Reference< uri::XUriReference > xUriRef; + if(!sValue.isEmpty() && sValue[0] != '#') + { + try + { + xUriRef = mpImpl->mxUriReferenceFactory->parse( rValue ); + if( xUriRef.is() && !xUriRef->isAbsolute() ) + { + //#i61943# relative URLs need special handling + INetURLObject aTemp( mpImpl->msPackageURI ); + bool bWasAbsolute = false; + sValue = aTemp.smartRel2Abs(sValue, bWasAbsolute ).GetMainURL(INetURLObject::DecodeMechanism::ToIUri); + } + } + catch(const uno::Exception&) + { + } + } + if( xUriRef.is() )//no conversion for empty values or for fragments + { + //conversion for matching schemes only + if( xUriRef->getScheme() == mpImpl->msPackageURIScheme ) + { + sValue = INetURLObject::GetRelURL( msOrigFileName, sValue ); + } + } + return sValue; +} + +void SvXMLExport::StartElement(sal_uInt16 nPrefix, + enum ::xmloff::token::XMLTokenEnum eName, + bool bIgnWSOutside ) +{ + StartElement(GetNamespaceMap_().GetQNameByKey( nPrefix, + GetXMLToken(eName) ), bIgnWSOutside); +} + +void SvXMLExport::StartElement(const OUString& rName, + bool bIgnWSOutside ) +{ + if ((mnErrorFlags & SvXMLErrorFlags::DO_NOTHING) != SvXMLErrorFlags::DO_NOTHING) + { + try + { + if( bIgnWSOutside && ((mnExportFlags & SvXMLExportFlags::PRETTY) == SvXMLExportFlags::PRETTY)) + mxHandler->ignorableWhitespace( msWS ); + mxHandler->startElement( rName, GetXAttrList() ); + } + catch (const SAXInvalidCharacterException& e) + { + Sequence<OUString> aPars { rName }; + SetError( XMLERROR_SAX|XMLERROR_FLAG_WARNING, aPars, e.Message, nullptr ); + } + catch (const SAXException& e) + { + Sequence<OUString> aPars { rName }; + SetError( XMLERROR_SAX|XMLERROR_FLAG_ERROR|XMLERROR_FLAG_SEVERE, + aPars, e.Message, nullptr ); + } + } + ClearAttrList(); + ++mpImpl->mDepth; // increment nesting depth counter +} + +void SvXMLExport::Characters(const OUString& rChars) +{ + if ((mnErrorFlags & SvXMLErrorFlags::DO_NOTHING) != SvXMLErrorFlags::DO_NOTHING) + { + try + { + mxHandler->characters(rChars); + } + catch (const SAXInvalidCharacterException& e) + { + Sequence<OUString> aPars { rChars }; + SetError( XMLERROR_SAX|XMLERROR_FLAG_WARNING, aPars, e.Message, nullptr ); + } + catch (const SAXException& e) + { + Sequence<OUString> aPars { rChars }; + SetError( XMLERROR_SAX|XMLERROR_FLAG_ERROR|XMLERROR_FLAG_SEVERE, + aPars, e.Message, nullptr ); + } + } +} + +void SvXMLExport::EndElement(sal_uInt16 nPrefix, + enum ::xmloff::token::XMLTokenEnum eName, + bool bIgnWSInside ) +{ + EndElement(GetNamespaceMap_().GetQNameByKey( nPrefix, GetXMLToken(eName) ), + bIgnWSInside); +} + +void SvXMLExport::EndElement(const OUString& rName, + bool bIgnWSInside ) +{ + // decrement nesting depth counter & (maybe) restore namespace map + --mpImpl->mDepth; + if (!mpImpl->mNamespaceMaps.empty() && + (mpImpl->mNamespaceMaps.top().second == mpImpl->mDepth)) + { + mpNamespaceMap = std::move(mpImpl->mNamespaceMaps.top().first); + mpImpl->mNamespaceMaps.pop(); + } + SAL_WARN_IF(!mpImpl->mNamespaceMaps.empty() && + (mpImpl->mNamespaceMaps.top().second >= mpImpl->mDepth), "xmloff.core", "SvXMLExport: NamespaceMaps corrupted"); + + if ((mnErrorFlags & SvXMLErrorFlags::DO_NOTHING) != SvXMLErrorFlags::DO_NOTHING) + { + try + { + if( bIgnWSInside && ((mnExportFlags & SvXMLExportFlags::PRETTY) == SvXMLExportFlags::PRETTY)) + mxHandler->ignorableWhitespace( msWS ); + mxHandler->endElement( rName ); + } + catch (const SAXException& e) + { + Sequence<OUString> aPars { rName }; + SetError( XMLERROR_SAX|XMLERROR_FLAG_ERROR|XMLERROR_FLAG_SEVERE, + aPars, e.Message, nullptr ); + } + } +} + +void SvXMLExport::IgnorableWhitespace() +{ + if ((mnExportFlags & SvXMLExportFlags::PRETTY) != SvXMLExportFlags::PRETTY) + return; + + if ((mnErrorFlags & SvXMLErrorFlags::DO_NOTHING) != SvXMLErrorFlags::DO_NOTHING) + { + try + { + mxHandler->ignorableWhitespace( msWS ); + } + catch (const SAXException& e) + { + Sequence<OUString> aPars(0); + SetError( XMLERROR_SAX|XMLERROR_FLAG_ERROR|XMLERROR_FLAG_SEVERE, + aPars, e.Message, nullptr ); + } + } +} + +void SvXMLExport::SetError( + sal_Int32 nId, + const Sequence<OUString>& rMsgParams, + const OUString& rExceptionMessage, + const Reference<XLocator>& rLocator ) +{ + // allow multi-threaded access to the cancel() method + static osl::Mutex aMutex; + osl::MutexGuard aGuard(aMutex); + + // maintain error flags + if ( ( nId & XMLERROR_FLAG_ERROR ) != 0 ) + mnErrorFlags |= SvXMLErrorFlags::ERROR_OCCURRED; + if ( ( nId & XMLERROR_FLAG_WARNING ) != 0 ) + mnErrorFlags |= SvXMLErrorFlags::WARNING_OCCURRED; + if ( ( nId & XMLERROR_FLAG_SEVERE ) != 0 ) + mnErrorFlags |= SvXMLErrorFlags::DO_NOTHING; + + // create error list on demand + if ( mpXMLErrors == nullptr ) + mpXMLErrors.reset( new XMLErrors() ); + + // save error information + mpXMLErrors->AddRecord( nId, rMsgParams, rExceptionMessage, rLocator ); +} + +void SvXMLExport::SetError( + sal_Int32 nId, + const Sequence<OUString>& rMsgParams) +{ + SetError( nId, rMsgParams, "", nullptr ); +} + +void SvXMLExport::DisposingModel() +{ + mxModel.clear(); + // Shapes in Writer cannot be named via context menu (#i51726#) + meModelType = SvtModuleOptions::EFactory::UNKNOWN_FACTORY; + mxEventListener.clear(); +} + + +::comphelper::UnoInterfaceToUniqueIdentifierMapper& SvXMLExport::getInterfaceToIdentifierMapper() +{ + return mpImpl->maInterfaceToIdentifierMapper; +} + +// Written OpenDocument file format doesn't fit to the created text document (#i69627#) +bool SvXMLExport::writeOutlineStyleAsNormalListStyle() const +{ + return mpImpl->mbOutlineStyleAsNormalListStyle; +} + +uno::Reference< embed::XStorage > const & SvXMLExport::GetTargetStorage() const +{ + return mpImpl->mxTargetStorage; +} + +SvtSaveOptions::ODFSaneDefaultVersion SvXMLExport::getSaneDefaultVersion() const +{ + if( mpImpl ) + return mpImpl->maSaveOptions.GetODFSaneDefaultVersion(); + + // fatal error, use current version as default + return SvtSaveOptions::ODFSVER_LATEST; +} + +void +SvXMLExport::AddAttributeIdLegacy( + sal_uInt16 const nLegacyPrefix, OUString const& rValue) +{ + switch (getSaneDefaultVersion()) { + case SvtSaveOptions::ODFSVER_011: // fall through + case SvtSaveOptions::ODFSVER_010: break; + default: // ODF 1.2: xml:id + AddAttribute(XML_NAMESPACE_XML, XML_ID, rValue); + } + // in ODF 1.1 this was form:id, anim:id, draw:id, or text:id + // backward compatibility: in ODF 1.2 write _both_ id attrs + AddAttribute(nLegacyPrefix, XML_ID, rValue); + // FIXME: this function simply assumes that rValue is unique +} + +void +SvXMLExport::AddAttributeXmlId(uno::Reference<uno::XInterface> const & i_xIfc) +{ + // check version >= 1.2 + switch (getSaneDefaultVersion()) { + case SvtSaveOptions::ODFSVER_011: // fall through + case SvtSaveOptions::ODFSVER_010: return; + default: break; + } + const uno::Reference<rdf::XMetadatable> xMeta(i_xIfc, + uno::UNO_QUERY); +//FIXME not yet... + if ( xMeta.is() ) + { + const beans::StringPair mdref( xMeta->getMetadataReference() ); + if ( !mdref.Second.isEmpty() ) + { + const OUString streamName = mpImpl->mStreamName; + if ( !streamName.isEmpty() ) + { + if ( streamName == mdref.First ) + { + AddAttribute( XML_NAMESPACE_XML, XML_ID, mdref.Second ); + } + else + { + SAL_WARN("xmloff.core","SvXMLExport::AddAttributeXmlId: invalid stream name"); + } + } + else + { + // FIXME: this is ugly + // there is no stream name (e.g. XSLT, flat-xml format)! + // but how do we ensure uniqueness in this case? + // a) just omit styles.xml ids -- they are unlikely anyway... + // b) somehow find out whether we are currently exporting styles + // or content, and prefix "s" or "c" => unique + if ( mdref.First == "content.xml" ) + { + AddAttribute( XML_NAMESPACE_XML, XML_ID, mdref.Second ); + } + else + { + SAL_INFO("xmloff.core", "SvXMLExport::AddAttributeXmlId: no stream name given: dropping styles.xml xml:id"); + } + } + } + } +} + +void +SvXMLExport::AddAttributesRDFa( + uno::Reference<text::XTextContent> const & i_xTextContent) +{ + // check version >= 1.2 + switch (getSaneDefaultVersion()) { + case SvtSaveOptions::ODFSVER_011: // fall through + case SvtSaveOptions::ODFSVER_010: return; + default: break; + } + + const uno::Reference<rdf::XMetadatable> xMeta( + i_xTextContent, uno::UNO_QUERY); + if (!xMeta.is() || xMeta->getMetadataReference().Second.isEmpty()) + { + return; // no xml:id => no RDFa + } + + if (!mpImpl->mpRDFaHelper) + { + mpImpl->mpRDFaHelper.reset( new ::xmloff::RDFaExportHelper(*this) ); + } + mpImpl->mpRDFaHelper->AddRDFa(xMeta); +} + +bool SvXMLExport::exportTextNumberElement() const +{ + return mpImpl->mbExportTextNumberElement; +} + +bool SvXMLExport::SetNullDateOnUnitConverter() +{ + // if the null date has already been set, don't set it again (performance) + if (!mpImpl->mbNullDateInitialized) + mpImpl->mbNullDateInitialized = GetMM100UnitConverter().setNullDate(GetModel()); + + return mpImpl->mbNullDateInitialized; +} + +OUString const & SvXMLExport::GetImageFilterName() const +{ + return msImgFilterName; +} + +void SvXMLElementExport::StartElement( + const sal_uInt16 nPrefixKey, + const OUString& rLName, + const bool bIgnoreWhitespaceOutside ) +{ + maElementName = mrExport.GetNamespaceMap().GetQNameByKey(nPrefixKey, rLName); + mrExport.StartElement(maElementName, bIgnoreWhitespaceOutside); +} + +SvXMLElementExport::SvXMLElementExport( + SvXMLExport& rExp, + sal_uInt16 nPrefixKey, + const char *pLName, + bool bIWSOutside, + bool bIWSInside ) + : mrExport( rExp ) + , maElementName() + , mbIgnoreWhitespaceInside( bIWSInside ) + , mbDoSomething( true ) +{ + const OUString sLName( OUString::createFromAscii( pLName ) ); + StartElement( nPrefixKey, sLName, bIWSOutside ); +} + +SvXMLElementExport::SvXMLElementExport( + SvXMLExport& rExp, + sal_uInt16 nPrefixKey, + const OUString& rLName, + bool bIWSOutside, + bool bIWSInside ) + : mrExport( rExp ) + , maElementName() + , mbIgnoreWhitespaceInside( bIWSInside ) + , mbDoSomething( true ) +{ + StartElement( nPrefixKey, rLName, bIWSOutside ); +} + +SvXMLElementExport::SvXMLElementExport( + SvXMLExport& rExp, + sal_uInt16 nPrefixKey, + enum XMLTokenEnum eLName, + bool bIWSOutside, + bool bIWSInside ) + : mrExport( rExp ) + , maElementName() + , mbIgnoreWhitespaceInside( bIWSInside ) + , mbDoSomething( true ) +{ + StartElement( nPrefixKey, GetXMLToken(eLName), bIWSOutside ); +} + +SvXMLElementExport::SvXMLElementExport( + SvXMLExport& rExp, + bool bDoSth, + sal_uInt16 nPrefixKey, + enum XMLTokenEnum eLName, + bool bIWSOutside, + bool bIWSInside ) + : mrExport( rExp ) + , maElementName() + , mbIgnoreWhitespaceInside( bIWSInside ) + , mbDoSomething( bDoSth ) +{ + if ( mbDoSomething ) + StartElement( nPrefixKey, GetXMLToken( eLName ), bIWSOutside ); +} + +SvXMLElementExport::SvXMLElementExport( + SvXMLExport& rExp, + const OUString& rQName, + bool bIWSOutside, + bool bIWSInside ) + : mrExport( rExp ) + , maElementName() + , mbIgnoreWhitespaceInside( bIWSInside ) + , mbDoSomething( true ) +{ + maElementName = rQName; + rExp.StartElement( rQName, bIWSOutside ); +} + +SvXMLElementExport::~SvXMLElementExport() +{ + if ( mbDoSomething ) + { + mrExport.EndElement( maElementName, mbIgnoreWhitespaceInside ); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/xmlictxt.cxx b/xmloff/source/core/xmlictxt.cxx new file mode 100644 index 000000000..e24ee7bcc --- /dev/null +++ b/xmloff/source/core/xmlictxt.cxx @@ -0,0 +1,171 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <com/sun/star/xml/sax/XAttributeList.hpp> +#include <xmloff/xmlimp.hxx> +#include <xmloff/xmlictxt.hxx> +#include <sax/fastattribs.hxx> +#include <comphelper/attributelist.hxx> +#include <cppuhelper/queryinterface.hxx> + +using namespace ::com::sun::star; + +SvXMLImportContext::SvXMLImportContext( SvXMLImport& rImp, sal_uInt16 nPrfx, + const OUString& rLName ) + : m_nRefCount(0) + , mrImport(rImp) + , mnPrefix(nPrfx) + , maLocalName(rLName) + , mbPrefixAndLocalNameFilledIn(true) +{ +} + +SvXMLImportContext::SvXMLImportContext( SvXMLImport& rImp ) + : m_nRefCount(0) + , mrImport(rImp) + , mnPrefix(0) + , mbPrefixAndLocalNameFilledIn(false) +{ +} + +SvXMLImportContext::~SvXMLImportContext() +{ +} + +SvXMLImportContextRef SvXMLImportContext::CreateChildContext( sal_uInt16 /*nPrefix*/, + const OUString& /*rLocalName*/, + const uno::Reference<xml::sax::XAttributeList>& ) +{ + return nullptr; +} + +void SvXMLImportContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& ) +{ +} + +void SvXMLImportContext::EndElement() +{ +} + +void SvXMLImportContext::Characters( const OUString& ) +{ +} + +// css::xml::sax::XFastContextHandler: +void SAL_CALL SvXMLImportContext::startFastElement(sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList > & Attribs) +{ + mrImport.isFastContext = false; + const OUString& rPrefix = SvXMLImport::getNamespacePrefixFromToken(nElement, &GetImport().GetNamespaceMap()); + const OUString& rLocalName = SvXMLImport::getNameFromToken( nElement ); + startUnknownElement( SvXMLImport::aDefaultNamespace, (rPrefix.isEmpty())? rLocalName : rPrefix + SvXMLImport::aNamespaceSeparator + rLocalName, Attribs ); +} + +void SAL_CALL SvXMLImportContext::startUnknownElement(const OUString & /*rNamespace*/, const OUString & rElementName, + const uno::Reference< xml::sax::XFastAttributeList > & Attribs) +{ + if ( mrImport.maAttrList.is() ) + mrImport.maAttrList->Clear(); + else + mrImport.maAttrList = new comphelper::AttributeList; + + mrImport.maNamespaceHandler->addNSDeclAttributes( mrImport.maAttrList ); + + if ( Attribs.is() ) + { + for( auto &it : sax_fastparser::castToFastAttributeList( Attribs ) ) + { + sal_Int32 nToken = it.getToken(); + const OUString& rAttrNamespacePrefix = SvXMLImport::getNamespacePrefixFromToken(nToken, &GetImport().GetNamespaceMap()); + OUString sAttrName = SvXMLImport::getNameFromToken( nToken ); + if ( !rAttrNamespacePrefix.isEmpty() ) + sAttrName = rAttrNamespacePrefix + SvXMLImport::aNamespaceSeparator + sAttrName; + + mrImport.maAttrList->AddAttribute( sAttrName, "CDATA", it.toString() ); + } + + const uno::Sequence< xml::Attribute > unknownAttribs = Attribs->getUnknownAttributes(); + for ( const auto& rUnknownAttrib : unknownAttribs ) + { + const OUString& rAttrValue = rUnknownAttrib.Value; + const OUString& rAttrName = rUnknownAttrib.Name; + // note: rAttrName is expected to be namespace-prefixed here + mrImport.maAttrList->AddAttribute( rAttrName, "CDATA", rAttrValue ); + } + } + mrImport.startElement( rElementName, mrImport.maAttrList.get() ); +} + +void SAL_CALL SvXMLImportContext::endFastElement(sal_Int32 nElement) +{ + mrImport.isFastContext = false; + const OUString& rPrefix = SvXMLImport::getNamespacePrefixFromToken(nElement, &GetImport().GetNamespaceMap()); + const OUString& rLocalName = SvXMLImport::getNameFromToken( nElement ); + endUnknownElement( SvXMLImport::aDefaultNamespace, (rPrefix.isEmpty())? rLocalName : rPrefix + SvXMLImport::aNamespaceSeparator + rLocalName ); +} + +void SAL_CALL SvXMLImportContext::endUnknownElement (const OUString & /*rNamespace*/, const OUString & rElementName) +{ + mrImport.endElement( rElementName ); +} + +uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SvXMLImportContext::createFastChildContext + (sal_Int32 Element, const uno::Reference< xml::sax::XFastAttributeList > & Attribs) +{ + // Call CreateFastContext only if it's the first element of the document + if ( mrImport.maFastContexts.empty() ) + return mrImport.CreateFastContext( Element, Attribs ); + return nullptr; +} + +uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SvXMLImportContext::createUnknownChildContext + (const OUString &, const OUString &, const uno::Reference< xml::sax::XFastAttributeList > &) +{ + return this; +} + +void SAL_CALL SvXMLImportContext::characters(const OUString &rChars) +{ + mrImport.Characters( rChars ); +} + +// XInterface +css::uno::Any SAL_CALL SvXMLImportContext::queryInterface( const css::uno::Type& aType ) +{ + css::uno::Any a = ::cppu::queryInterface( + aType, + static_cast< XFastContextHandler* >(this), + static_cast< XTypeProvider* >(this), + static_cast< css::uno::XInterface* >(static_cast< XFastContextHandler* >(this))); + + return a; +} + +// XTypeProvider +css::uno::Sequence< css::uno::Type > SAL_CALL SvXMLImportContext::getTypes() +{ + return { cppu::UnoType<XFastContextHandler>::get(), + cppu::UnoType<XTypeProvider>::get() }; +} + +css::uno::Sequence< sal_Int8 > SAL_CALL SvXMLImportContext::getImplementationId() +{ + return css::uno::Sequence<sal_Int8>(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/xmlimp.cxx b/xmloff/source/core/xmlimp.cxx new file mode 100644 index 000000000..0c9e9d06c --- /dev/null +++ b/xmloff/source/core/xmlimp.cxx @@ -0,0 +1,2325 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <memory> + +#include <tools/diagnose_ex.h> +#include <sal/log.hxx> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <tools/urlobj.hxx> +#include <vcl/embeddedfontshelper.hxx> +#include <vcl/graph.hxx> +#include <xmloff/unointerfacetouniqueidentifiermapper.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmluconv.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/XMLFontStylesContext.hxx> +#include <xmloff/xmlictxt.hxx> +#include <xmloff/xmlimp.hxx> +#include <xmloff/xmlnumfi.hxx> +#include <XMLEventImportHelper.hxx> +#include <XMLStarBasicContextFactory.hxx> +#include <XMLScriptContextFactory.hxx> +#include <StyleMap.hxx> +#include <xmloff/ProgressBarHelper.hxx> +#include <xmloff/xmlerror.hxx> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/ServiceNotRegisteredException.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/util/MeasureUnit.hpp> +#include <com/sun/star/util/XNumberFormatsSupplier.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/document/XBinaryStreamResolver.hpp> +#include <com/sun/star/document/XStorageBasedDocument.hpp> +#include <com/sun/star/document/XGraphicStorageHandler.hpp> +#include <com/sun/star/document/XEmbeddedObjectResolver.hpp> +#include <com/sun/star/xml/sax/XLocator.hpp> +#include <com/sun/star/xml/sax/FastParser.hpp> +#include <com/sun/star/xml/sax/SAXException.hpp> +#include <com/sun/star/packages/zip/ZipIOException.hpp> +#include <comphelper/fileformat.h> +#include <comphelper/namecontainer.hxx> +#include <comphelper/servicehelper.hxx> +#include <cppuhelper/implbase.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <comphelper/extract.hxx> +#include <comphelper/documentconstants.hxx> +#include <comphelper/documentinfo.hxx> +#include <comphelper/storagehelper.hxx> +#include <comphelper/attributelist.hxx> +#include <unotools/fontcvt.hxx> +#include <fasttokenhandler.hxx> +#include <vcl/GraphicExternalLink.hxx> + +#include <com/sun/star/rdf/XMetadatable.hpp> +#include <com/sun/star/rdf/XRepositorySupplier.hpp> +#include <RDFaImportHelper.hxx> + +using ::com::sun::star::beans::XPropertySetInfo; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::document; +using namespace ::xmloff::token; + +rtl::Reference< FastTokenHandler > SvXMLImport::xTokenHandler( new FastTokenHandler() ); +std::unordered_map< sal_Int32, std::pair< OUString, OUString > > SvXMLImport::aNamespaceMap; +std::unordered_map< OUString, OUString > SvXMLImport::aNamespaceURIPrefixMap; +const OUString SvXMLImport::aDefaultNamespace = OUString(""); +const OUString SvXMLImport::aNamespaceSeparator = OUString(":"); +bool SvXMLImport::bIsNSMapsInitialized = false; + +namespace { + +class SvXMLImportEventListener : public cppu::WeakImplHelper< css::lang::XEventListener > +{ +private: + SvXMLImport* pImport; + +public: + explicit SvXMLImportEventListener(SvXMLImport* pImport); + + // XEventListener + virtual void SAL_CALL disposing(const lang::EventObject& rEventObject) override; +}; + +} + +SvXMLImportEventListener::SvXMLImportEventListener(SvXMLImport* pTempImport) + : pImport(pTempImport) +{ +} + +// XEventListener +void SAL_CALL SvXMLImportEventListener::disposing( const lang::EventObject& ) +{ + if (pImport) + { + pImport->DisposingModel(); + pImport = nullptr; + } +} + +namespace +{ + +OUString +getBuildIdsProperty(uno::Reference<beans::XPropertySet> const& xImportInfo) +{ + if (xImportInfo.is()) + { + try + { + Reference< XPropertySetInfo > const xSetInfo( + xImportInfo->getPropertySetInfo()); + if (xSetInfo.is() && xSetInfo->hasPropertyByName("BuildId")) + { + OUString aBuildId; + xImportInfo->getPropertyValue("BuildId") >>= aBuildId; + return aBuildId; + } + } + catch (Exception const&) + { + DBG_UNHANDLED_EXCEPTION("xmloff.core", "exception getting BuildId"); + } + } + return OUString(); +} + +class DocumentInfo +{ +private: + sal_uInt16 mnGeneratorVersion; + +public: + explicit DocumentInfo( const SvXMLImport& rImport ) + : mnGeneratorVersion( SvXMLImport::ProductVersionUnknown ) + { + OUString const buildIds( + getBuildIdsProperty(rImport.getImportInfo())); + if (!buildIds.isEmpty()) + { + sal_Int32 const ix = buildIds.indexOf(';'); + if (-1 != ix) + { + OUString const loVersion(buildIds.copy(ix + 1)); + if (!loVersion.isEmpty()) + { + if ('3' == loVersion[0]) + { + mnGeneratorVersion = SvXMLImport::LO_3x; + } + else if ('4' == loVersion[0]) + { + if (loVersion.getLength() > 1 + && (loVersion[1] == '0' || loVersion[1] == '1')) + { + mnGeneratorVersion = SvXMLImport::LO_41x; // 4.0/4.1 + } + else if (loVersion.getLength() > 1 && '2' == loVersion[1]) + { + mnGeneratorVersion = SvXMLImport::LO_42x; // 4.2 + } + else if (loVersion.getLength() > 1 && '3' == loVersion[1]) + { + mnGeneratorVersion = SvXMLImport::LO_43x; // 4.3 + } + else if (loVersion.getLength() > 1 && '4' == loVersion[1]) + { + mnGeneratorVersion = SvXMLImport::LO_44x; // 4.4 + } + } + else if ('5' == loVersion[0]) + { + mnGeneratorVersion = SvXMLImport::LO_5x; + } + else if ('6' == loVersion[0]) + { + mnGeneratorVersion = SvXMLImport::LO_6x; + } + else if ('7' == loVersion[0]) + { + mnGeneratorVersion = SvXMLImport::LO_7x; + } + else + { + SAL_INFO("xmloff.core", "unknown LO version: " << loVersion); + } + return; // ignore buildIds + } + } + } + sal_Int32 nUPD, nBuild; + if ( rImport.getBuildIds( nUPD, nBuild ) ) + { + if ( nUPD >= 640 && nUPD <= 645 ) + { + mnGeneratorVersion = SvXMLImport::OOo_1x; + } + else if ( nUPD == 680 ) + { + mnGeneratorVersion = SvXMLImport::OOo_2x; + } + else if ( nUPD == 300 && nBuild <= 9379 ) + { + mnGeneratorVersion = SvXMLImport::OOo_30x; + } + else if ( nUPD == 310 ) + { + mnGeneratorVersion = SvXMLImport::OOo_31x; + } + else if ( nUPD == 320 ) + { + mnGeneratorVersion = SvXMLImport::OOo_32x; + } + else if ( nUPD == 330 ) + { + mnGeneratorVersion = SvXMLImport::OOo_33x; + } + else if ( nUPD == 340 ) + { + mnGeneratorVersion = SvXMLImport::OOo_34x; + } + else if (nUPD == 400 || nUPD == 401) + { + mnGeneratorVersion = SvXMLImport::AOO_40x; + } + else if (nUPD >= 410) + { + // effectively this means "latest", see use + // in XMLGraphicsDefaultStyle::SetDefaults()! + mnGeneratorVersion = SvXMLImport::AOO_4x; + } + } + } + + sal_uInt16 getGeneratorVersion() const + { + return mnGeneratorVersion; + } +}; + +} + +class SvXMLImport_Impl +{ +public: + FontToSubsFontConverter hBatsFontConv; + FontToSubsFontConverter hMathFontConv; + + bool mbOwnGraphicResolver; + bool mbOwnEmbeddedResolver; + INetURLObject aBaseURL; + INetURLObject aDocBase; + + /// name of stream in package, e.g., "content.xml" + OUString mStreamName; + + OUString aODFVersion; + + bool mbIsOOoXML; + + // Boolean, indicating that position attributes + // of shapes are given in horizontal left-to-right layout. This is the case + // for the OpenOffice.org file format. (#i28749#) + bool mbShapePositionInHoriL2R; + bool mbTextDocInOOoFileFormat; + + const uno::Reference< uno::XComponentContext > mxComponentContext; + OUString implementationName; + + uno::Reference< embed::XStorage > mxSourceStorage; + + std::unique_ptr< xmloff::RDFaImportHelper > mpRDFaHelper; + + std::unique_ptr< DocumentInfo > mpDocumentInfo; + + SvXMLImport_Impl( const uno::Reference< uno::XComponentContext >& rxContext, + OUString const & theImplementationName) + : hBatsFontConv( nullptr ) + , hMathFontConv( nullptr ) + , mbOwnGraphicResolver( false ) + , mbOwnEmbeddedResolver( false ) + , mbIsOOoXML(false) + // Convert drawing object positions from OOo file format to OASIS (#i28749#) + , mbShapePositionInHoriL2R( false ) + , mbTextDocInOOoFileFormat( false ) + , mxComponentContext( rxContext ) + , implementationName(theImplementationName) + , mpRDFaHelper() // lazy + , mpDocumentInfo() // lazy + { + SAL_WARN_IF(!mxComponentContext.is(), "xmloff.core", "SvXMLImport: no ComponentContext"); + if (!mxComponentContext.is()) throw uno::RuntimeException(); + } + + sal_uInt16 getGeneratorVersion( const SvXMLImport& rImport ) + { + if (!mpDocumentInfo) + { + mpDocumentInfo.reset( new DocumentInfo( rImport ) ); + } + + return mpDocumentInfo->getGeneratorVersion(); + } + + ::comphelper::UnoInterfaceToUniqueIdentifierMapper maInterfaceToIdentifierMapper; +}; + +SvXMLImportContext *SvXMLImport::CreateFastContext( sal_Int32 nElement, + const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ ) +{ + SAL_WARN( "xmloff.core", "CreateFastContext should be overridden, for element " << nElement); + return new SvXMLImportContext( *this ); +} + +void SvXMLImport::InitCtor_() +{ + if( mnImportFlags != SvXMLImportFlags::NONE ) + { + // implicit "xml" namespace prefix + mpNamespaceMap->Add( GetXMLToken(XML_XML), GetXMLToken(XML_N_XML), XML_NAMESPACE_XML ); + mpNamespaceMap->Add( "_office", GetXMLToken(XML_N_OFFICE), XML_NAMESPACE_OFFICE ); + mpNamespaceMap->Add( "_office_ooo", GetXMLToken(XML_N_OFFICE_EXT), XML_NAMESPACE_OFFICE_EXT ); + mpNamespaceMap->Add( "_ooo", GetXMLToken(XML_N_OOO), XML_NAMESPACE_OOO ); + mpNamespaceMap->Add( "_style", GetXMLToken(XML_N_STYLE), XML_NAMESPACE_STYLE ); + mpNamespaceMap->Add( "_text", GetXMLToken(XML_N_TEXT), XML_NAMESPACE_TEXT ); + mpNamespaceMap->Add( "_table", GetXMLToken(XML_N_TABLE), XML_NAMESPACE_TABLE ); + mpNamespaceMap->Add( "_table_ooo", GetXMLToken(XML_N_TABLE_EXT), XML_NAMESPACE_TABLE_EXT ); + mpNamespaceMap->Add( "_draw", GetXMLToken(XML_N_DRAW), XML_NAMESPACE_DRAW ); + mpNamespaceMap->Add( "_draw_ooo", GetXMLToken(XML_N_DRAW_EXT), XML_NAMESPACE_DRAW_EXT ); + mpNamespaceMap->Add( "_dr3d", GetXMLToken(XML_N_DR3D), XML_NAMESPACE_DR3D ); + mpNamespaceMap->Add( "_fo", GetXMLToken(XML_N_FO_COMPAT), XML_NAMESPACE_FO ); + mpNamespaceMap->Add( "_xlink", GetXMLToken(XML_N_XLINK), XML_NAMESPACE_XLINK ); + mpNamespaceMap->Add( "_dc", GetXMLToken(XML_N_DC), XML_NAMESPACE_DC ); + mpNamespaceMap->Add( "_dom", GetXMLToken(XML_N_DOM), XML_NAMESPACE_DOM ); + mpNamespaceMap->Add( "_meta", GetXMLToken(XML_N_META), XML_NAMESPACE_META ); + mpNamespaceMap->Add( "_number", GetXMLToken(XML_N_NUMBER), XML_NAMESPACE_NUMBER ); + mpNamespaceMap->Add( "_svg", GetXMLToken(XML_N_SVG_COMPAT), XML_NAMESPACE_SVG ); + mpNamespaceMap->Add( "_chart", GetXMLToken(XML_N_CHART), XML_NAMESPACE_CHART ); + mpNamespaceMap->Add( "_math", GetXMLToken(XML_N_MATH), XML_NAMESPACE_MATH ); + mpNamespaceMap->Add( "_form", GetXMLToken(XML_N_FORM), XML_NAMESPACE_FORM ); + mpNamespaceMap->Add( "_script", GetXMLToken(XML_N_SCRIPT), XML_NAMESPACE_SCRIPT ); + mpNamespaceMap->Add( "_config", GetXMLToken(XML_N_CONFIG), XML_NAMESPACE_CONFIG ); + mpNamespaceMap->Add( "_xforms", GetXMLToken(XML_N_XFORMS_1_0), XML_NAMESPACE_XFORMS ); + mpNamespaceMap->Add( "_formx", GetXMLToken( XML_N_FORMX ), XML_NAMESPACE_FORMX ); + mpNamespaceMap->Add( "_xsd", GetXMLToken(XML_N_XSD), XML_NAMESPACE_XSD ); + mpNamespaceMap->Add( "_xsi", GetXMLToken(XML_N_XSI), XML_NAMESPACE_XFORMS ); + mpNamespaceMap->Add( "_ooow", GetXMLToken(XML_N_OOOW), XML_NAMESPACE_OOOW ); + mpNamespaceMap->Add( "_oooc", GetXMLToken(XML_N_OOOC), XML_NAMESPACE_OOOC ); + mpNamespaceMap->Add( "_field", GetXMLToken(XML_N_FIELD), XML_NAMESPACE_FIELD ); + mpNamespaceMap->Add( "_of", GetXMLToken(XML_N_OF), XML_NAMESPACE_OF ); + mpNamespaceMap->Add( "_xhtml", GetXMLToken(XML_N_XHTML), XML_NAMESPACE_XHTML ); + mpNamespaceMap->Add( "_css3text", GetXMLToken(XML_N_CSS3TEXT), XML_NAMESPACE_CSS3TEXT ); + + mpNamespaceMap->Add( "_calc_libo", GetXMLToken(XML_N_CALC_EXT), XML_NAMESPACE_CALC_EXT); + mpNamespaceMap->Add( "_office_libo", + GetXMLToken(XML_N_LO_EXT), XML_NAMESPACE_LO_EXT); + } + + if (mxNumberFormatsSupplier.is()) + mpNumImport = std::make_unique<SvXMLNumFmtHelper>(mxNumberFormatsSupplier, GetComponentContext()); + + if (mxModel.is() && !mxEventListener.is()) + { + mxEventListener.set(new SvXMLImportEventListener(this)); + mxModel->addEventListener(mxEventListener); + } +} + +SvXMLImport::SvXMLImport( + const css::uno::Reference< css::uno::XComponentContext >& xContext, + OUString const & implementationName, SvXMLImportFlags nImportFlags ) +: mpImpl( new SvXMLImport_Impl(xContext, implementationName) ), + mpNamespaceMap( new SvXMLNamespaceMap ), + + mpUnitConv( new SvXMLUnitConverter( xContext, + util::MeasureUnit::MM_100TH, util::MeasureUnit::MM_100TH) ), + + mnImportFlags( nImportFlags ), + isFastContext( false ), + maNamespaceHandler( new SvXMLImportFastNamespaceHandler() ), + mbIsFormsSupported( true ), + mbIsTableShapeSupported( false ), + mbNotifyMacroEventRead( false ) +{ + SAL_WARN_IF( !xContext.is(), "xmloff.core", "got no service manager" ); + InitCtor_(); + mxParser = xml::sax::FastParser::create( xContext ); + setNamespaceHandler( maNamespaceHandler.get() ); + setTokenHandler( xTokenHandler.get() ); + if ( !bIsNSMapsInitialized ) + { + initializeNamespaceMaps(); + bIsNSMapsInitialized = true; + } + registerNamespaces(); +} + +void SvXMLImport::cleanup() throw () +{ + if (mxEventListener.is() && mxModel.is()) + mxModel->removeEventListener(mxEventListener); + // clear context stacks first in case of parse error because the context + // class dtors are full of application logic + while (!maFastContexts.empty()) + { + if (SvXMLStylesContext* pStylesContext = dynamic_cast<SvXMLStylesContext*>(maFastContexts.top().get())) + pStylesContext->Clear(); + maFastContexts.pop(); + } + while (!maContexts.empty()) + { + if (SvXMLStylesContext* pStylesContext = dynamic_cast<SvXMLStylesContext*>(maContexts.top().get())) + pStylesContext->Clear(); + maContexts.pop(); + } + mxTextImport.clear(); // XMLRedlineImportHelper needs model + DisposingModel(); +} + +SvXMLImport::~SvXMLImport() throw () +{ + cleanup(); +} + +bool SvXMLImport::addEmbeddedFont(const css::uno::Reference< css::io::XInputStream >& stream, + const OUString& fontName, const char* extra, + std::vector<unsigned char> key, bool eot) +{ + if (!mxEmbeddedFontHelper) + mxEmbeddedFontHelper.reset(new EmbeddedFontsHelper); + return mxEmbeddedFontHelper->addEmbeddedFont(stream, fontName, extra, key, eot); +} + +namespace +{ + class theSvXMLImportUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSvXMLImportUnoTunnelId> {}; +} + +const css::uno::Sequence<sal_Int8>& SvXMLImport::getUnoTunnelId() throw() +{ + return theSvXMLImportUnoTunnelId::get().getSeq(); +} + +// XUnoTunnel +sal_Int64 SAL_CALL SvXMLImport::getSomething( const uno::Sequence< sal_Int8 >& rId ) +{ + if( isUnoTunnelId<SvXMLImport>(rId) ) + { + return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this)); + } + return 0; +} + +namespace +{ + class setFastDocumentHandlerGuard + { + private: + css::uno::Reference<css::xml::sax::XFastParser> mxParser; + public: + setFastDocumentHandlerGuard(const css::uno::Reference<css::xml::sax::XFastParser>& Parser, + const css::uno::Reference<css::xml::sax::XFastDocumentHandler>& Handler) + : mxParser(Parser) + { + mxParser->setFastDocumentHandler(Handler); + } + //guarantee restoration of null document handler + ~setFastDocumentHandlerGuard() + { + mxParser->setFastDocumentHandler(nullptr); + } + }; +} + +// XFastParser +void SAL_CALL SvXMLImport::parseStream( const xml::sax::InputSource& aInputSource ) +{ + setFastDocumentHandlerGuard aDocumentHandlerGuard(mxParser, mxFastDocumentHandler.is() ? mxFastDocumentHandler : this); + mxParser->parseStream(aInputSource); +} + +void SAL_CALL SvXMLImport::setFastDocumentHandler( const uno::Reference< xml::sax::XFastDocumentHandler >& Handler ) +{ + mxFastDocumentHandler = Handler; +} + +void SAL_CALL SvXMLImport::setTokenHandler( const uno::Reference< xml::sax::XFastTokenHandler >& Handler ) +{ + mxParser->setTokenHandler( Handler ); +} + +void SAL_CALL SvXMLImport::registerNamespace( const OUString& NamespaceURL, sal_Int32 NamespaceToken ) +{ + mxParser->registerNamespace( NamespaceURL, NamespaceToken ); +} + +OUString SAL_CALL SvXMLImport::getNamespaceURL( const OUString& rPrefix ) +{ + return mxParser->getNamespaceURL( rPrefix ); +} + +void SAL_CALL SvXMLImport::setErrorHandler( const uno::Reference< xml::sax::XErrorHandler >& Handler ) +{ + mxParser->setErrorHandler( Handler ); +} + +void SAL_CALL SvXMLImport::setEntityResolver( const uno::Reference< xml::sax::XEntityResolver >& Resolver ) +{ + mxParser->setEntityResolver( Resolver ); +} + +void SAL_CALL SvXMLImport::setLocale( const lang::Locale& rLocale ) +{ + mxParser->setLocale( rLocale ); +} + +void SAL_CALL SvXMLImport::setNamespaceHandler( const uno::Reference< xml::sax::XFastNamespaceHandler >& Handler) +{ + mxParser->setNamespaceHandler( Handler ); +} + + +void SAL_CALL SvXMLImport::startDocument() +{ + SAL_INFO( "xmloff.core", "{ SvXMLImport::startDocument" ); + if (!mxGraphicStorageHandler.is() || !mxEmbeddedResolver.is()) + { + Reference< lang::XMultiServiceFactory > xFactory( mxModel, UNO_QUERY ); + if( xFactory.is() ) + { + try + { + if (!mxGraphicStorageHandler.is()) + { + // #99870# Import... instead of Export... + mxGraphicStorageHandler.set( + xFactory->createInstance("com.sun.star.document.ImportGraphicStorageHandler"), + UNO_QUERY); + mpImpl->mbOwnGraphicResolver = mxGraphicStorageHandler.is(); + } + + if( !mxEmbeddedResolver.is() ) + { + // #99870# Import... instead of Export... + mxEmbeddedResolver.set( + xFactory->createInstance("com.sun.star.document.ImportEmbeddedObjectResolver"), + UNO_QUERY); + mpImpl->mbOwnEmbeddedResolver = mxEmbeddedResolver.is(); + } + } + catch( css::uno::Exception& ) + { + } + } + } +} + +void SAL_CALL SvXMLImport::endDocument() +{ + SAL_INFO( "xmloff.core", "} SvXMLImport::endDocument" ); + // #i9518# All the stuff that accesses the document has to be done here, not in the dtor, + // because the SvXMLImport dtor might not be called until after the document has been closed. + + GetTextImport()->MapCrossRefHeadingFieldsHorribly(); + + if (mpImpl->mpRDFaHelper) + { + const uno::Reference<rdf::XRepositorySupplier> xRS(mxModel, + uno::UNO_QUERY); + if (xRS.is()) + { + mpImpl->mpRDFaHelper->InsertRDFa( xRS ); + } + } + + mpNumImport.reset(); + if (mxImportInfo.is()) + { + uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxImportInfo->getPropertySetInfo(); + if (xPropertySetInfo.is()) + { + if (bool(mpProgressBarHelper)) + { + OUString sProgressMax(XML_PROGRESSMAX); + OUString sProgressCurrent(XML_PROGRESSCURRENT); + OUString sRepeat(XML_PROGRESSREPEAT); + if (xPropertySetInfo->hasPropertyByName(sProgressMax) && + xPropertySetInfo->hasPropertyByName(sProgressCurrent)) + { + sal_Int32 nProgressMax(mpProgressBarHelper->GetReference()); + sal_Int32 nProgressCurrent(mpProgressBarHelper->GetValue()); + mxImportInfo->setPropertyValue(sProgressMax, uno::Any(nProgressMax)); + mxImportInfo->setPropertyValue(sProgressCurrent, uno::Any(nProgressCurrent)); + } + if (xPropertySetInfo->hasPropertyByName(sRepeat)) + mxImportInfo->setPropertyValue(sRepeat, css::uno::makeAny(mpProgressBarHelper->GetRepeat())); + // pProgressBarHelper is deleted in dtor + } + OUString sNumberStyles(XML_NUMBERSTYLES); + if (mxNumberStyles.is() && xPropertySetInfo->hasPropertyByName(sNumberStyles)) + { + mxImportInfo->setPropertyValue(sNumberStyles, Any(mxNumberStyles)); + } + } + } + + if( mxFontDecls.is() ) + static_cast<SvXMLStylesContext *>(mxFontDecls.get())->Clear(); + if( mxStyles.is() ) + static_cast<SvXMLStylesContext *>(mxStyles.get())->Clear(); + if( mxAutoStyles.is() ) + static_cast<SvXMLStylesContext *>(mxAutoStyles.get())->Clear(); + if( mxMasterStyles.is() ) + static_cast<SvXMLStylesContext *>(mxMasterStyles.get())->Clear(); + + // possible form-layer related knittings which can only be done when + // the whole document exists + if ( mxFormImport.is() ) + mxFormImport->documentDone(); + + // The shape import helper does the z-order sorting in the dtor, + // so it must be deleted here, too. + mxShapeImport = nullptr; + + if( mpImpl->mbOwnGraphicResolver ) + { + Reference<lang::XComponent> xComp(mxGraphicStorageHandler, UNO_QUERY); + xComp->dispose(); + } + + if( mpImpl->mbOwnEmbeddedResolver ) + { + Reference< lang::XComponent > xComp( mxEmbeddedResolver, UNO_QUERY ); + xComp->dispose(); + } + mpStyleMap.clear(); + + if ( bool( mpXMLErrors ) ) + { + mpXMLErrors->ThrowErrorAsSAXException( XMLERROR_FLAG_SEVERE ); + } +} + +std::unique_ptr<SvXMLNamespaceMap> SvXMLImport::processNSAttributes( + const uno::Reference< xml::sax::XAttributeList >& xAttrList) +{ + std::unique_ptr<SvXMLNamespaceMap> pRewindMap; + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + for( sal_Int16 i=0; i < nAttrCount; i++ ) + { + const OUString& rAttrName = xAttrList->getNameByIndex( i ); + if ( rAttrName == "office:version" ) + { + mpImpl->aODFVersion = xAttrList->getValueByIndex( i ); + + // the ODF version in content.xml and manifest.xml must be the same starting from ODF1.2 + if ( mpImpl->mStreamName == "content.xml" && !IsODFVersionConsistent( mpImpl->aODFVersion ) ) + { + throw xml::sax::SAXException("Inconsistent ODF versions in content.xml and manifest.xml!", + uno::Reference< uno::XInterface >(), + uno::makeAny( + packages::zip::ZipIOException("Inconsistent ODF versions in content.xml and manifest.xml!" ) ) ); + } + } + else if( ( rAttrName.getLength() >= 5 ) && + ( rAttrName.startsWith( GetXMLToken(XML_XMLNS) ) ) && + ( rAttrName.getLength() == 5 || ':' == rAttrName[5] ) ) + { + if( !pRewindMap ) + { + pRewindMap = std::move(mpNamespaceMap); + mpNamespaceMap.reset(new SvXMLNamespaceMap(*pRewindMap)); + } + const OUString& rAttrValue = xAttrList->getValueByIndex( i ); + + OUString aPrefix( ( rAttrName.getLength() == 5 ) + ? OUString() + : rAttrName.copy( 6 ) ); + // Add namespace, but only if it is known. + sal_uInt16 nKey = mpNamespaceMap->AddIfKnown( aPrefix, rAttrValue ); + // If namespace is unknown, try to match a name with similar + // TC Id and version + if( XML_NAMESPACE_UNKNOWN == nKey ) + { + OUString aTestName( rAttrValue ); + if( SvXMLNamespaceMap::NormalizeURI( aTestName ) ) + nKey = mpNamespaceMap->AddIfKnown( aPrefix, aTestName ); + } + // If that namespace is not known, too, add it as unknown + if( XML_NAMESPACE_UNKNOWN == nKey ) + mpNamespaceMap->Add( aPrefix, rAttrValue ); + + } + } + return pRewindMap; +} + +void SAL_CALL SvXMLImport::startElement( const OUString& rName, + const uno::Reference< xml::sax::XAttributeList >& xAttrList ) +{ + // SAL_INFO("svg", "startElement " << rName); + // Process namespace attributes. This must happen before creating the + // context, because namespace declaration apply to the element name itself. + std::unique_ptr<SvXMLNamespaceMap> pRewindMap(processNSAttributes(xAttrList)); + + // Get element's namespace and local name. + OUString aLocalName; + sal_uInt16 nPrefix = + mpNamespaceMap->GetKeyByAttrName( rName, &aLocalName ); + + // If there are contexts already, call a CreateChildContext at the topmost + // context. Otherwise, create a default context. + SvXMLImportContextRef xContext; + if(!maContexts.empty()) + { + xContext = maContexts.top()->CreateChildContext(nPrefix, aLocalName, xAttrList); + SAL_WARN_IF( xContext.is() && xContext->IsPrefixFilledIn() && (xContext->GetPrefix() != nPrefix), "xmloff.core", + "SvXMLImport::startElement: created context has wrong prefix" ); + } + else + { + Reference<xml::sax::XLocator> xDummyLocator; + Sequence < OUString > aParams { rName }; + + SetError( XMLERROR_FLAG_SEVERE|XMLERROR_UNKNOWN_ROOT, + aParams, "Root element " + rName + " unknown", xDummyLocator ); + } + + if ( !xContext.is() ) + SAL_INFO_IF( !xContext.is(), "xmloff.core", "SvXMLImport::startElement: missing context for element " << rName ); + + if( !xContext.is() ) + xContext.set(new SvXMLImportContext( *this, nPrefix, aLocalName )); + + // Remember old namespace map. + if( pRewindMap ) + xContext->PutRewindMap(std::move(pRewindMap)); + + // Call a startElement at the new context. + xContext->StartElement( xAttrList ); + + // Push context on stack. + maContexts.push(xContext); +} + +void SAL_CALL SvXMLImport::endElement( const OUString& +#ifdef DBG_UTIL +rName +#endif +) +{ + if (maContexts.empty()) + { + SAL_WARN("xmloff.core", "SvXMLImport::endElement: no context left"); + return; + } + + std::unique_ptr<SvXMLNamespaceMap> pRewindMap; + + { + // Get topmost context and remove it from the stack. + SvXMLImportContextRef xContext = std::move(maContexts.top()); + maContexts.pop(); + +#ifdef DBG_UTIL + // Non product only: check if endElement call matches startELement call. + if (xContext->IsPrefixFilledIn()) // prefix+localname are only valid in the non-FastParser case + { + OUString aLocalName; + sal_uInt16 nPrefix = + mpNamespaceMap->GetKeyByAttrName( rName, &aLocalName ); + SAL_WARN_IF( xContext->GetPrefix() != nPrefix, "xmloff.core", "SvXMLImport::endElement: popped context has wrong prefix" ); + SAL_WARN_IF( xContext->GetLocalName() != aLocalName, "xmloff.core", "SvXMLImport::endElement: popped context has wrong lname" ); + } +#endif + + // Call a EndElement at the current context. + xContext->EndElement(); + // Get a namespace map to rewind. + pRewindMap = xContext->TakeRewindMap(); + // note: delete xContext *before* rewinding namespace map! + } + + // Rewind a namespace map. + if (pRewindMap) + { + mpNamespaceMap.reset(); + mpNamespaceMap = std::move(pRewindMap); + } +} + +void SAL_CALL SvXMLImport::characters( const OUString& rChars ) +{ + if ( !maFastContexts.empty() ) + { + maFastContexts.top()->characters( rChars ); + } + else if( !maContexts.empty() ) + { + maContexts.top()->Characters( rChars ); + } +} + +void SvXMLImport::Characters( const OUString& rChars ) +{ + if( !maContexts.empty() ) + { + maContexts.top()->Characters( rChars ); + } +} + +void SAL_CALL SvXMLImport::ignorableWhitespace( const OUString& ) +{ +} + +void SAL_CALL SvXMLImport::processingInstruction( const OUString&, + const OUString& ) +{ +} + +void SAL_CALL SvXMLImport::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& rLocator ) +{ + mxLocator = rLocator; +} + +// XFastContextHandler +void SAL_CALL SvXMLImport::startFastElement (sal_Int32 Element, + const uno::Reference< xml::sax::XFastAttributeList > & Attribs) +{ + if ( Attribs.is() ) + { + sax_fastparser::FastAttributeList& rAttribList = + sax_fastparser::castToFastAttributeList( Attribs ); + auto aIter( rAttribList.find( XML_ELEMENT( OFFICE, XML_VERSION ) ) ); + if( aIter != rAttribList.end() ) + { + mpImpl->aODFVersion = aIter.toString(); + + // the ODF version in content.xml and manifest.xml must be the same starting from ODF1.2 + if ( mpImpl->mStreamName == "content.xml" && !IsODFVersionConsistent( mpImpl->aODFVersion ) ) + { + throw xml::sax::SAXException("Inconsistent ODF versions in content.xml and manifest.xml!", + uno::Reference< uno::XInterface >(), + uno::makeAny( + packages::zip::ZipIOException("Inconsistent ODF versions in content.xml and manifest.xml!" ) ) ); + } + } + } + + //Namespace handling is unnecessary. It is done by the fastparser itself. + uno::Reference<XFastContextHandler> xContext; + if (!maFastContexts.empty()) + { + uno::Reference<XFastContextHandler> pHandler = maFastContexts.top(); + xContext = pHandler->createFastChildContext( Element, Attribs ); + } + else + xContext.set( CreateFastContext( Element, Attribs ) ); + + SAL_INFO_IF(!xContext.is(), "xmloff.core", "No fast context for element " << getNameFromToken(Element)); + if ( !xContext.is() ) + xContext.set( new SvXMLImportContext( *this ) ); + + isFastContext = true; + + // Call a startElement at the new context. + xContext->startFastElement( Element, Attribs ); + + if ( isFastContext ) + { + if ( maNamespaceAttrList.is() ) + maNamespaceAttrList->Clear(); + else + maNamespaceAttrList = new comphelper::AttributeList; + + maNamespaceHandler->addNSDeclAttributes( maNamespaceAttrList ); + std::unique_ptr<SvXMLNamespaceMap> pRewindMap( + processNSAttributes( maNamespaceAttrList.get() )); + assert( dynamic_cast<SvXMLImportContext*>( xContext.get() ) != nullptr ); + SvXMLImportContext *pContext = static_cast<SvXMLImportContext*>( xContext.get() ); + if (pRewindMap) + pContext->PutRewindMap(std::move(pRewindMap)); + maContexts.push(pContext); + } + + // Push context on stack. + maFastContexts.push(xContext); +} + +void SAL_CALL SvXMLImport::startUnknownElement (const OUString & rPrefix, const OUString & rLocalName, + const uno::Reference< xml::sax::XFastAttributeList > & Attribs) +{ + uno::Reference<XFastContextHandler> xContext; + if (!maFastContexts.empty()) + { + uno::Reference<XFastContextHandler> pHandler = maFastContexts.top(); + xContext = pHandler->createUnknownChildContext( rPrefix, rLocalName, Attribs ); + } + else + xContext.set( CreateFastContext( -1, Attribs ) ); + + SAL_WARN_IF(!xContext.is(), "xmloff.core", "No context for unknown-element " << rLocalName); + if ( !xContext.is() ) + xContext.set( new SvXMLImportContext( *this ) ); + + xContext->startUnknownElement( rPrefix, rLocalName, Attribs ); + maFastContexts.push(xContext); +} + +void SAL_CALL SvXMLImport::endFastElement (sal_Int32 Element) +{ + if (!maFastContexts.empty()) + { + uno::Reference<XFastContextHandler> xContext = std::move(maFastContexts.top()); + maFastContexts.pop(); + isFastContext = true; + xContext->endFastElement( Element ); + if (isFastContext) + maContexts.pop(); + + xContext = nullptr; + } +} + +void SAL_CALL SvXMLImport::endUnknownElement (const OUString & rPrefix, const OUString & rLocalName) +{ + if (!maFastContexts.empty()) + { + uno::Reference<XFastContextHandler> xContext = std::move(maFastContexts.top()); + maFastContexts.pop(); + xContext->endUnknownElement( rPrefix, rLocalName ); + xContext = nullptr; + } +} + +uno::Reference< xml::sax::XFastContextHandler > SAL_CALL + SvXMLImport::createFastChildContext (sal_Int32, + const uno::Reference< xml::sax::XFastAttributeList > &) +{ + return this; +} + +uno::Reference< xml::sax::XFastContextHandler > SAL_CALL + SvXMLImport::createUnknownChildContext (const OUString &, const OUString &, + const uno::Reference< xml::sax::XFastAttributeList > &) +{ + return this; +} + +// XExtendedDocumentHandler +void SAL_CALL SvXMLImport::startCDATA() +{ +} + +void SAL_CALL SvXMLImport::endCDATA() +{ +} + +void SAL_CALL SvXMLImport::comment( const OUString& ) +{ +} + +void SAL_CALL SvXMLImport::allowLineBreak() +{ +} + +void SAL_CALL SvXMLImport::unknown( const OUString& ) +{ +} + +void SvXMLImport::SetStatistics(const uno::Sequence< beans::NamedValue> &) +{ + GetProgressBarHelper()->SetRepeat(false); + GetProgressBarHelper()->SetReference(0); +} + +// XImporter +void SAL_CALL SvXMLImport::setTargetDocument( const uno::Reference< lang::XComponent >& xDoc ) +{ + mxModel.set( xDoc, UNO_QUERY ); + if( !mxModel.is() ) + throw lang::IllegalArgumentException(); + + try + { + uno::Reference<document::XStorageBasedDocument> const xSBDoc(mxModel, uno::UNO_QUERY); + uno::Reference<embed::XStorage> const xStor(xSBDoc.is() ? xSBDoc->getDocumentStorage() + : nullptr); + if (xStor.is()) + { + mpImpl->mbIsOOoXML = + ::comphelper::OStorageHelper::GetXStorageFormat(xStor) + < SOFFICE_FILEFORMAT_8; + } + } + catch (uno::Exception const&) + { + DBG_UNHANDLED_EXCEPTION("xmloff.core"); + } + if (!mxEventListener.is()) + { + mxEventListener.set(new SvXMLImportEventListener(this)); + mxModel->addEventListener(mxEventListener); + } + + SAL_WARN_IF( bool(mpNumImport), "xmloff.core", "number format import already exists." ); + mpNumImport.reset(); +} + +// XFilter +sal_Bool SAL_CALL SvXMLImport::filter( const uno::Sequence< beans::PropertyValue >& ) +{ + return false; +} + +void SAL_CALL SvXMLImport::cancel( ) +{ +} + +// XInitialize +void SAL_CALL SvXMLImport::initialize( const uno::Sequence< uno::Any >& aArguments ) +{ + for( const auto& rAny : aArguments ) + { + Reference<XInterface> xValue; + rAny >>= xValue; + + uno::Reference<task::XStatusIndicator> xTmpStatusIndicator( + xValue, UNO_QUERY ); + if( xTmpStatusIndicator.is() ) + mxStatusIndicator = xTmpStatusIndicator; + + uno::Reference<document::XGraphicStorageHandler> xGraphicStorageHandler(xValue, UNO_QUERY); + if (xGraphicStorageHandler.is()) + mxGraphicStorageHandler = xGraphicStorageHandler; + + uno::Reference<document::XEmbeddedObjectResolver> xTmpObjectResolver( + xValue, UNO_QUERY ); + if( xTmpObjectResolver.is() ) + mxEmbeddedResolver = xTmpObjectResolver; + + uno::Reference<beans::XPropertySet> xTmpPropSet( xValue, UNO_QUERY ); + if( xTmpPropSet.is() ) + { + mxImportInfo = xTmpPropSet; + uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxImportInfo->getPropertySetInfo(); + if (xPropertySetInfo.is()) + { + OUString sPropName(XML_NUMBERSTYLES); + if (xPropertySetInfo->hasPropertyByName(sPropName)) + { + uno::Any aAny = mxImportInfo->getPropertyValue(sPropName); + aAny >>= mxNumberStyles; + } + + sPropName = "PrivateData"; + if (xPropertySetInfo->hasPropertyByName(sPropName)) + { + Reference < XInterface > xIfc; + uno::Any aAny = mxImportInfo->getPropertyValue(sPropName); + aAny >>= xIfc; + + StyleMap *pSMap = comphelper::getUnoTunnelImplementation<StyleMap>( xIfc ); + if( pSMap ) + { + mpStyleMap = pSMap; + } + } + OUString sBaseURI; + sPropName = "BaseURI"; + if (xPropertySetInfo->hasPropertyByName(sPropName)) + { + uno::Any aAny = mxImportInfo->getPropertyValue(sPropName); + aAny >>= sBaseURI; + mpImpl->aBaseURL.SetURL( sBaseURI ); + mpImpl->aDocBase.SetURL( sBaseURI ); + } + OUString sRelPath; + sPropName = "StreamRelPath"; + if( xPropertySetInfo->hasPropertyByName(sPropName) ) + { + uno::Any aAny = mxImportInfo->getPropertyValue(sPropName); + aAny >>= sRelPath; + } + OUString sName; + sPropName = "StreamName"; + if( xPropertySetInfo->hasPropertyByName(sPropName) ) + { + uno::Any aAny = mxImportInfo->getPropertyValue(sPropName); + aAny >>= sName; + } + if( !sBaseURI.isEmpty() && !sName.isEmpty() ) + { + if( !sRelPath.isEmpty() ) + mpImpl->aBaseURL.insertName( sRelPath ); + mpImpl->aBaseURL.insertName( sName ); + } + mpImpl->mStreamName = sName; // Note: may be empty (XSLT) + // Retrieve property <ShapePositionInHoriL2R> (#i28749#) + sPropName = "ShapePositionInHoriL2R"; + if( xPropertySetInfo->hasPropertyByName(sPropName) ) + { + uno::Any aAny = mxImportInfo->getPropertyValue(sPropName); + aAny >>= mpImpl->mbShapePositionInHoriL2R; + } + sPropName = "TextDocInOOoFileFormat"; + if( xPropertySetInfo->hasPropertyByName(sPropName) ) + { + uno::Any aAny = mxImportInfo->getPropertyValue(sPropName); + aAny >>= mpImpl->mbTextDocInOOoFileFormat; + } + + sPropName = "SourceStorage"; + if( xPropertySetInfo->hasPropertyByName(sPropName) ) + mxImportInfo->getPropertyValue(sPropName) >>= mpImpl->mxSourceStorage; + } + } + } + + uno::Reference<lang::XInitialization> const xInit(mxParser, uno::UNO_QUERY_THROW); + uno::Sequence<uno::Any> args(1); + args[0] <<= OUString("IgnoreMissingNSDecl"); + xInit->initialize( args ); +} + +// XServiceInfo +OUString SAL_CALL SvXMLImport::getImplementationName() +{ + return mpImpl->implementationName; +} + +sal_Bool SAL_CALL SvXMLImport::supportsService( const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + +uno::Sequence< OUString > SAL_CALL SvXMLImport::getSupportedServiceNames( ) +{ + return { "com.sun.star.document.ImportFilter", "com.sun.star.xml.XMLImportFilter" }; +} + +XMLTextImportHelper* SvXMLImport::CreateTextImport() +{ + return new XMLTextImportHelper( mxModel, *this ); +} + +XMLShapeImportHelper* SvXMLImport::CreateShapeImport() +{ + return new XMLShapeImportHelper( *this, mxModel ); +} + +SchXMLImportHelper* SvXMLImport::CreateChartImport() +{ + return new SchXMLImportHelper(); +} + +::xmloff::OFormLayerXMLImport* SvXMLImport::CreateFormImport() +{ + return new ::xmloff::OFormLayerXMLImport(*this); +} + + +// Get or create fill/line/lineend-style-helper + + +const Reference< container::XNameContainer > & SvXMLImport::GetGradientHelper() +{ + if( !mxGradientHelper.is() ) + { + if( mxModel.is() ) + { + Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY); + if( xServiceFact.is() ) + { + try + { + mxGradientHelper.set( xServiceFact->createInstance( + "com.sun.star.drawing.GradientTable" ), UNO_QUERY); + } + catch( lang::ServiceNotRegisteredException& ) + {} + } + } + } + + return mxGradientHelper; +} + +const Reference< container::XNameContainer > & SvXMLImport::GetHatchHelper() +{ + if( !mxHatchHelper.is() ) + { + if( mxModel.is() ) + { + Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY); + if( xServiceFact.is() ) + { + try + { + mxHatchHelper.set( xServiceFact->createInstance( + "com.sun.star.drawing.HatchTable" ), UNO_QUERY); + } + catch( lang::ServiceNotRegisteredException& ) + {} + } + } + } + + return mxHatchHelper; +} + +const Reference< container::XNameContainer > & SvXMLImport::GetBitmapHelper() +{ + if( !mxBitmapHelper.is() ) + { + if( mxModel.is() ) + { + Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY); + if( xServiceFact.is() ) + { + try + { + mxBitmapHelper.set( xServiceFact->createInstance( + "com.sun.star.drawing.BitmapTable" ), UNO_QUERY); + } + catch( lang::ServiceNotRegisteredException& ) + {} + } + } + } + + return mxBitmapHelper; +} + +const Reference< container::XNameContainer > & SvXMLImport::GetTransGradientHelper() +{ + if( !mxTransGradientHelper.is() ) + { + if( mxModel.is() ) + { + Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY); + if( xServiceFact.is() ) + { + try + { + mxTransGradientHelper.set( xServiceFact->createInstance( + "com.sun.star.drawing.TransparencyGradientTable" ), UNO_QUERY); + } + catch( lang::ServiceNotRegisteredException& ) + {} + } + } + } + + return mxTransGradientHelper; +} + +const Reference< container::XNameContainer > & SvXMLImport::GetMarkerHelper() +{ + if( !mxMarkerHelper.is() ) + { + if( mxModel.is() ) + { + Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY); + if( xServiceFact.is() ) + { + try + { + mxMarkerHelper.set( xServiceFact->createInstance( "com.sun.star.drawing.MarkerTable" ), UNO_QUERY); + } + catch( lang::ServiceNotRegisteredException& ) + {} + } + } + } + + return mxMarkerHelper; +} + +const Reference< container::XNameContainer > & SvXMLImport::GetDashHelper() +{ + if( !mxDashHelper.is() && mxModel.is() ) + { + Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY); + if( xServiceFact.is() ) + { + try + { + mxDashHelper.set( xServiceFact->createInstance( "com.sun.star.drawing.DashTable" ), UNO_QUERY); + } + catch( lang::ServiceNotRegisteredException& ) + {} + } + } + + return mxDashHelper; +} + +bool SvXMLImport::IsPackageURL( const OUString& rURL ) const +{ + + // if, and only if, only parts are imported, then we're in a package + const SvXMLImportFlags nTest = SvXMLImportFlags::META|SvXMLImportFlags::STYLES|SvXMLImportFlags::CONTENT|SvXMLImportFlags::SETTINGS; + if( (mnImportFlags & nTest) == nTest ) + return false; + + // TODO: from this point extract to own static function + + // Some quick tests: Some may rely on the package structure! + sal_Int32 nLen = rURL.getLength(); + if( nLen > 0 && '/' == rURL[0] ) + // RFC2396 net_path or abs_path + return false; + else if( nLen > 1 && '.' == rURL[0] ) + { + if( '.' == rURL[1] ) + // ../: We are never going up one level, so we know + // it's not an external URI + return false; + else if( '/' == rURL[1] ) + // we are remaining on a level, so it's a package URI + return true; + } + + // Now check for a RFC2396 schema + sal_Int32 nPos = 1; + while( nPos < nLen ) + { + switch( rURL[nPos] ) + { + case '/': + // a relative path segment + return true; + case ':': + // a schema + return false; + default: + break; + // we don't care about any other characters + } + ++nPos; + } + + return true; +} + +uno::Reference<graphic::XGraphic> SvXMLImport::loadGraphicByURL(OUString const & rURL) +{ + uno::Reference<graphic::XGraphic> xGraphic; + + if (mxGraphicStorageHandler.is()) + { + if (IsPackageURL(rURL)) + { + xGraphic = mxGraphicStorageHandler->loadGraphic(rURL); + } + else + { + OUString const & rAbsoluteURL = GetAbsoluteReference(rURL); + GraphicExternalLink aExternalLink(rAbsoluteURL); + Graphic aGraphic(aExternalLink); + xGraphic = aGraphic.GetXGraphic(); + } + } + + return xGraphic; +} + +uno::Reference<graphic::XGraphic> SvXMLImport::loadGraphicFromBase64(uno::Reference<io::XOutputStream> const & rxOutputStream) +{ + uno::Reference<graphic::XGraphic> xGraphic; + + if (mxGraphicStorageHandler.is()) + { + xGraphic = mxGraphicStorageHandler->loadGraphicFromOutputStream(rxOutputStream); + } + + return xGraphic; +} + +Reference< XOutputStream > SvXMLImport::GetStreamForGraphicObjectURLFromBase64() const +{ + Reference< XOutputStream > xOStm; + Reference< document::XBinaryStreamResolver > xStmResolver(mxGraphicStorageHandler, UNO_QUERY); + + if( xStmResolver.is() ) + xOStm = xStmResolver->createOutputStream(); + + return xOStm; +} + +OUString SvXMLImport::ResolveEmbeddedObjectURL( + const OUString& rURL, + const OUString& rClassId ) +{ + OUString sRet; + + if( IsPackageURL( rURL ) ) + { + if ( mxEmbeddedResolver.is() ) + { + OUString sURL( rURL ); + if( !rClassId.isEmpty() ) + { + sURL += "!" + rClassId; + } + sRet = mxEmbeddedResolver->resolveEmbeddedObjectURL( sURL ); + } + } + else + sRet = GetAbsoluteReference( rURL ); + + return sRet; +} + +Reference< embed::XStorage > const & SvXMLImport::GetSourceStorage() const +{ + return mpImpl->mxSourceStorage; +} + +Reference < XOutputStream > + SvXMLImport::GetStreamForEmbeddedObjectURLFromBase64() const +{ + Reference < XOutputStream > xOLEStream; + + if( mxEmbeddedResolver.is() ) + { + Reference< XNameAccess > xNA( mxEmbeddedResolver, UNO_QUERY ); + if( xNA.is() ) + { + Any aAny = xNA->getByName( "Obj12345678" ); + aAny >>= xOLEStream; + } + } + + return xOLEStream; +} + +OUString SvXMLImport::ResolveEmbeddedObjectURLFromBase64() +{ + OUString sRet; + + if( mxEmbeddedResolver.is() ) + { + sRet = mxEmbeddedResolver->resolveEmbeddedObjectURL( "Obj12345678" ); + } + + return sRet; +} + +void SvXMLImport::AddStyleDisplayName( XmlStyleFamily nFamily, + const OUString& rName, + const OUString& rDisplayName ) +{ + if( !mpStyleMap.is() ) + { + mpStyleMap = new StyleMap; + if( mxImportInfo.is() ) + { + OUString sPrivateData( "PrivateData" ); + Reference< beans::XPropertySetInfo > xPropertySetInfo = + mxImportInfo->getPropertySetInfo(); + if( xPropertySetInfo.is() && + xPropertySetInfo->hasPropertyByName(sPrivateData) ) + { + Reference < XInterface > xIfc( + static_cast< XUnoTunnel *>( mpStyleMap.get() ) ); + mxImportInfo->setPropertyValue( sPrivateData, Any(xIfc) ); + } + } + } + + StyleMap::key_type aKey( nFamily, rName ); + StyleMap::value_type aValue( aKey, rDisplayName ); + ::std::pair<StyleMap::iterator,bool> aRes( mpStyleMap->insert( aValue ) ); + SAL_WARN_IF( !aRes.second, + "xmloff.core", + "duplicate style name of family " << static_cast<int>(nFamily) << ": \"" << rName << "\""); + +} + +OUString SvXMLImport::GetStyleDisplayName( XmlStyleFamily nFamily, + const OUString& rName ) const +{ + OUString sName( rName ); + if( mpStyleMap.is() && !rName.isEmpty() ) + { + StyleMap::key_type aKey( nFamily, rName ); + StyleMap::const_iterator aIter = mpStyleMap->find( aKey ); + if( aIter != mpStyleMap->end() ) + sName = (*aIter).second; + } + return sName; +} + +void SvXMLImport::SetViewSettings(const css::uno::Sequence<css::beans::PropertyValue>&) +{ +} + +void SvXMLImport::SetConfigurationSettings(const css::uno::Sequence<css::beans::PropertyValue>&) +{ +} + +void SvXMLImport::SetDocumentSpecificSettings(const OUString&, const uno::Sequence<beans::PropertyValue>&) +{ +} + +ProgressBarHelper* SvXMLImport::GetProgressBarHelper() +{ + if (!mpProgressBarHelper) + { + mpProgressBarHelper = std::make_unique<ProgressBarHelper>(mxStatusIndicator, false); + + if (mxImportInfo.is()) + { + uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxImportInfo->getPropertySetInfo(); + if (xPropertySetInfo.is()) + { + OUString sProgressRange(XML_PROGRESSRANGE); + OUString sProgressMax(XML_PROGRESSMAX); + OUString sProgressCurrent(XML_PROGRESSCURRENT); + OUString sRepeat(XML_PROGRESSREPEAT); + if (xPropertySetInfo->hasPropertyByName(sProgressMax) && + xPropertySetInfo->hasPropertyByName(sProgressCurrent) && + xPropertySetInfo->hasPropertyByName(sProgressRange)) + { + uno::Any aAny; + sal_Int32 nProgressMax(0); + sal_Int32 nProgressCurrent(0); + sal_Int32 nProgressRange(0); + aAny = mxImportInfo->getPropertyValue(sProgressRange); + if (aAny >>= nProgressRange) + mpProgressBarHelper->SetRange(nProgressRange); + aAny = mxImportInfo->getPropertyValue(sProgressMax); + if (aAny >>= nProgressMax) + mpProgressBarHelper->SetReference(nProgressMax); + aAny = mxImportInfo->getPropertyValue(sProgressCurrent); + if (aAny >>= nProgressCurrent) + mpProgressBarHelper->SetValue(nProgressCurrent); + } + if (xPropertySetInfo->hasPropertyByName(sRepeat)) + { + uno::Any aAny = mxImportInfo->getPropertyValue(sRepeat); + if (aAny.getValueType() == cppu::UnoType<bool>::get()) + mpProgressBarHelper->SetRepeat(::cppu::any2bool(aAny)); + else { + SAL_WARN( "xmloff.core", "why is it no boolean?" ); + } + } + } + } + } + return mpProgressBarHelper.get(); +} + +void SvXMLImport::AddNumberStyle(sal_Int32 nKey, const OUString& rName) +{ + if (!mxNumberStyles.is()) + mxNumberStyles.set( comphelper::NameContainer_createInstance( ::cppu::UnoType<sal_Int32>::get()) ); + if (mxNumberStyles.is()) + { + try + { + mxNumberStyles->insertByName(rName, Any(nKey)); + } + catch ( uno::Exception& ) + { + DBG_UNHANDLED_EXCEPTION( "xmloff.core", "Numberformat could not be inserted"); + } + } + else { + SAL_WARN( "xmloff.core", "not possible to create NameContainer"); + } +} + +XMLEventImportHelper& SvXMLImport::GetEventImport() +{ + if (!mpEventImportHelper) + { + // construct event helper and register StarBasic handler and standard + // event tables + mpEventImportHelper = std::make_unique<XMLEventImportHelper>(); + const OUString& sStarBasic(GetXMLToken(XML_STARBASIC)); + mpEventImportHelper->RegisterFactory(sStarBasic, + std::make_unique<XMLStarBasicContextFactory>()); + const OUString& sScript(GetXMLToken(XML_SCRIPT)); + mpEventImportHelper->RegisterFactory(sScript, + std::make_unique<XMLScriptContextFactory>()); + mpEventImportHelper->AddTranslationTable(aStandardEventTable); + + // register StarBasic event handler with capitalized spelling + mpEventImportHelper->RegisterFactory("StarBasic", + std::make_unique<XMLStarBasicContextFactory>()); + } + + return *mpEventImportHelper; +} + +void SvXMLImport::SetFontDecls( XMLFontStylesContext *pFontDecls ) +{ + if (mxFontDecls.is()) + static_cast<SvXMLStylesContext*>(mxFontDecls.get())->Clear(); + mxFontDecls = pFontDecls; +} + +void SvXMLImport::SetStyles( SvXMLStylesContext *pStyles ) +{ + if (mxStyles.is()) + static_cast<SvXMLStylesContext*>(mxStyles.get())->Clear(); + mxStyles = pStyles; +} + +void SvXMLImport::SetAutoStyles( SvXMLStylesContext *pAutoStyles ) +{ + if (pAutoStyles && mxNumberStyles.is()) + { + uno::Reference<xml::sax::XAttributeList> xAttrList; + const uno::Sequence<OUString> aStyleNames = mxNumberStyles->getElementNames(); + for (const auto& name : aStyleNames) + { + uno::Any aAny(mxNumberStyles->getByName(name)); + sal_Int32 nKey(0); + if (aAny >>= nKey) + { + SvXMLStyleContext* pContext = new SvXMLNumFormatContext( + *this, XML_NAMESPACE_NUMBER, name, xAttrList, nKey, + GetDataStylesImport()->GetLanguageForKey(nKey), *pAutoStyles); + pAutoStyles->AddStyle(*pContext); + } + } + } + if (mxAutoStyles.is()) + static_cast<SvXMLStylesContext*>(mxAutoStyles.get())->Clear(); + mxAutoStyles = pAutoStyles; + GetTextImport()->SetAutoStyles( pAutoStyles ); + GetShapeImport()->SetAutoStylesContext( pAutoStyles ); + GetChartImport()->SetAutoStylesContext( pAutoStyles ); + GetFormImport()->setAutoStyleContext( pAutoStyles ); +} + +void SvXMLImport::SetMasterStyles( SvXMLStylesContext *pMasterStyles ) +{ + if (mxMasterStyles.is()) + static_cast<SvXMLStylesContext*>(mxMasterStyles.get())->Clear(); + mxMasterStyles = pMasterStyles; +} + +XMLFontStylesContext *SvXMLImport::GetFontDecls() +{ + return static_cast<XMLFontStylesContext *>(mxFontDecls.get()); +} + +SvXMLStylesContext *SvXMLImport::GetStyles() +{ + return static_cast<SvXMLStylesContext *>(mxStyles.get()); +} + +SvXMLStylesContext *SvXMLImport::GetAutoStyles() +{ + return static_cast<SvXMLStylesContext *>(mxAutoStyles.get()); +} + +const XMLFontStylesContext *SvXMLImport::GetFontDecls() const +{ + return static_cast<const XMLFontStylesContext *>(mxFontDecls.get()); +} + +const SvXMLStylesContext *SvXMLImport::GetStyles() const +{ + return static_cast<const SvXMLStylesContext *>(mxStyles.get()); +} + +const SvXMLStylesContext *SvXMLImport::GetAutoStyles() const +{ + return static_cast<const SvXMLStylesContext *>(mxAutoStyles.get()); +} + +OUString SvXMLImport::GetAbsoluteReference(const OUString& rValue) const +{ + if( rValue.isEmpty() || rValue[0] == '#' ) + return rValue; + + INetURLObject aAbsURL; + if( mpImpl->aBaseURL.GetNewAbsURL( rValue, &aAbsURL ) ) + return aAbsURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri ); + else + return rValue; +} + +bool SvXMLImport::IsODFVersionConsistent( const OUString& aODFVersion ) +{ + // the check returns sal_False only if the storage version could be retrieved + bool bResult = true; + + if ( !aODFVersion.isEmpty() && aODFVersion.compareTo( ODFVER_012_TEXT ) >= 0 ) + { + // check the consistency only for the ODF1.2 and later ( according to content.xml ) + // manifest.xml might have no version, it should be checked here and the correct version should be set + try + { // don't use getDocumentStorage(), it's temporary and latest version + uno::Reference<embed::XStorage> const xStor(GetSourceStorage()); + uno::Reference< beans::XPropertySet > xStorProps( xStor, uno::UNO_QUERY_THROW ); + + // the check should be done only for OASIS format + if (!IsOOoXML()) + { + bool bRepairPackage = false; + try + { + xStorProps->getPropertyValue( "RepairPackage" ) + >>= bRepairPackage; + } catch ( uno::Exception& ) + {} + + // check only if not in Repair mode + if ( !bRepairPackage ) + { + OUString aStorVersion; + xStorProps->getPropertyValue( "Version" ) + >>= aStorVersion; + + // if the storage version is set in manifest.xml, it must be the same as in content.xml + // if not, set it explicitly to be used further ( it will work even for readonly storage ) + // This workaround is not nice, but I see no other way to handle it, since there are + // ODF1.2 documents without version in manifest.xml + if ( !aStorVersion.isEmpty() ) + bResult = aODFVersion == aStorVersion; + else + xStorProps->setPropertyValue( "Version", + uno::makeAny( aODFVersion ) ); + + if ( bResult ) + { + bool bInconsistent = false; + xStorProps->getPropertyValue( "IsInconsistent" ) + >>= bInconsistent; + bResult = !bInconsistent; + } + } + } + } + catch( uno::Exception& ) + {} + } + + return bResult; +} + +void SvXMLImport::CreateNumberFormatsSupplier_() +{ + SAL_WARN_IF( mxNumberFormatsSupplier.is(), "xmloff.core", "number formats supplier already exists!" ); + if(mxModel.is()) + mxNumberFormatsSupplier = + uno::Reference< util::XNumberFormatsSupplier> (mxModel, uno::UNO_QUERY); +} + +void SvXMLImport::CreateDataStylesImport_() +{ + SAL_WARN_IF( bool(mpNumImport), "xmloff.core", "data styles import already exists!" ); + uno::Reference<util::XNumberFormatsSupplier> xNum = + GetNumberFormatsSupplier(); + if ( xNum.is() ) + mpNumImport = std::make_unique<SvXMLNumFmtHelper>(xNum, GetComponentContext() ); +} + +sal_Unicode SvXMLImport::ConvStarBatsCharToStarSymbol( sal_Unicode c ) +{ + sal_Unicode cNew = c; + if( !mpImpl->hBatsFontConv ) + { + mpImpl->hBatsFontConv = CreateFontToSubsFontConverter( "StarBats", + FontToSubsFontFlags::IMPORT ); + SAL_WARN_IF( !mpImpl->hBatsFontConv, "xmloff.core", "Got no symbol font converter" ); + } + if( mpImpl->hBatsFontConv ) + { + cNew = ConvertFontToSubsFontChar( mpImpl->hBatsFontConv, c ); + } + + return cNew; +} + +sal_Unicode SvXMLImport::ConvStarMathCharToStarSymbol( sal_Unicode c ) +{ + sal_Unicode cNew = c; + if( !mpImpl->hMathFontConv ) + { + mpImpl->hMathFontConv = CreateFontToSubsFontConverter( "StarMath", + FontToSubsFontFlags::IMPORT ); + SAL_WARN_IF( !mpImpl->hMathFontConv, "xmloff.core", "Got no symbol font converter" ); + } + if( mpImpl->hMathFontConv ) + { + cNew = ConvertFontToSubsFontChar( mpImpl->hMathFontConv, c ); + } + + return cNew; +} + +void SvXMLImport::SetError( + sal_Int32 nId, + const Sequence<OUString>& rMsgParams, + const OUString& rExceptionMessage, + const Reference<xml::sax::XLocator>& rLocator ) +{ + // create error list on demand + if ( !mpXMLErrors ) + mpXMLErrors = std::make_unique<XMLErrors>(); + + // save error information + // use document locator (if none supplied) + mpXMLErrors->AddRecord( nId, rMsgParams, rExceptionMessage, + rLocator.is() ? rLocator : mxLocator ); +} + +void SvXMLImport::SetError( + sal_Int32 nId, + const Sequence<OUString>& rMsgParams) +{ + SetError( nId, rMsgParams, "", nullptr ); +} + +void SvXMLImport::SetError( + sal_Int32 nId) +{ + Sequence<OUString> aSeq(0); + SetError( nId, aSeq ); +} + +void SvXMLImport::SetError( + sal_Int32 nId, + const OUString& rMsg1) +{ + Sequence<OUString> aSeq { rMsg1 }; + SetError( nId, aSeq ); +} + +void SvXMLImport::SetError( + sal_Int32 nId, + const OUString& rMsg1, + const OUString& rMsg2) +{ + Sequence<OUString> aSeq(2); + OUString* pSeq = aSeq.getArray(); + pSeq[0] = rMsg1; + pSeq[1] = rMsg2; + SetError( nId, aSeq ); +} + +void SvXMLImport::DisposingModel() +{ + if( mxFontDecls.is() ) + static_cast<SvXMLStylesContext *>(mxFontDecls.get())->Clear(); + if( mxStyles.is() ) + static_cast<SvXMLStylesContext *>(mxStyles.get())->Clear(); + if( mxAutoStyles.is() ) + static_cast<SvXMLStylesContext *>(mxAutoStyles.get())->Clear(); + if( mxMasterStyles.is() ) + static_cast<SvXMLStylesContext *>(mxMasterStyles.get())->Clear(); + + mxModel.set(nullptr); + mxEventListener.set(nullptr); +} + +::comphelper::UnoInterfaceToUniqueIdentifierMapper& SvXMLImport::getInterfaceToIdentifierMapper() +{ + return mpImpl->maInterfaceToIdentifierMapper; +} + +uno::Reference< uno::XComponentContext > const & +SvXMLImport::GetComponentContext() const +{ + return mpImpl->mxComponentContext; +} + +OUString SvXMLImport::GetBaseURL() const +{ + return mpImpl->aBaseURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ); +} + +OUString SvXMLImport::GetDocumentBase() const +{ + return mpImpl->aDocBase.GetMainURL( INetURLObject::DecodeMechanism::NONE ); +} + +// Convert drawing object positions from OOo file format to OASIS (#i28749#) +bool SvXMLImport::IsShapePositionInHoriL2R() const +{ + return mpImpl->mbShapePositionInHoriL2R; +} + +bool SvXMLImport::IsTextDocInOOoFileFormat() const +{ + return mpImpl->mbTextDocInOOoFileFormat; +} + +void SvXMLImport::initXForms() +{ + // dummy method; to be implemented by derived classes supporting XForms +} + +bool SvXMLImport::getBuildIds( sal_Int32& rUPD, sal_Int32& rBuild ) const +{ + bool bRet = false; + OUString const aBuildId(getBuildIdsProperty(mxImportInfo)); + if (!aBuildId.isEmpty()) + { + sal_Int32 nIndex = aBuildId.indexOf('$'); + if (nIndex != -1) + { + rUPD = aBuildId.copy( 0, nIndex ).toInt32(); + sal_Int32 nIndexEnd = aBuildId.indexOf(';', nIndex); + rBuild = (nIndexEnd == -1) + ? aBuildId.copy(nIndex + 1).toInt32() + : aBuildId.copy(nIndex + 1, nIndexEnd - nIndex - 1).toInt32(); + bRet = true; + } + } + return bRet; +} + +sal_uInt16 SvXMLImport::getGeneratorVersion() const +{ + // --> ORW + return mpImpl->getGeneratorVersion( *this ); + // <-- +} + +bool SvXMLImport::isGeneratorVersionOlderThan( + sal_uInt16 const nOOoVersion, sal_uInt16 const nLOVersion) +{ + assert( (nLOVersion & LO_flag)); + assert(!(nOOoVersion & LO_flag)); + const sal_uInt16 nGeneratorVersion(getGeneratorVersion()); + return (nGeneratorVersion & LO_flag) + ? nGeneratorVersion < nLOVersion + : nGeneratorVersion < nOOoVersion; +} + + +OUString const & SvXMLImport::GetODFVersion() const +{ + return mpImpl->aODFVersion; +} + +bool SvXMLImport::IsOOoXML() const +{ + return mpImpl->mbIsOOoXML; +} + +// xml:id for RDF metadata +void SvXMLImport::SetXmlId(uno::Reference<uno::XInterface> const & i_xIfc, + OUString const & i_rXmlId) +{ + if (!i_rXmlId.isEmpty()) { + try { + const uno::Reference<rdf::XMetadatable> xMeta(i_xIfc, + uno::UNO_QUERY); +//FIXME: not yet + if (xMeta.is()) { + const beans::StringPair mdref( mpImpl->mStreamName, i_rXmlId ); + try { + xMeta->setMetadataReference(mdref); + } catch (lang::IllegalArgumentException &) { + // probably duplicate; ignore + SAL_INFO("xmloff.core", "SvXMLImport::SetXmlId: cannot set xml:id"); + } + } + } catch (uno::Exception &) { + TOOLS_WARN_EXCEPTION("xmloff.core","SvXMLImport::SetXmlId"); + } + } +} + +::xmloff::RDFaImportHelper & +SvXMLImport::GetRDFaImportHelper() +{ + if (!mpImpl->mpRDFaHelper) + { + mpImpl->mpRDFaHelper.reset( new ::xmloff::RDFaImportHelper(*this) ); + } + return *mpImpl->mpRDFaHelper; +} + +void +SvXMLImport::AddRDFa(const uno::Reference<rdf::XMetadatable>& i_xObject, + OUString const & i_rAbout, + OUString const & i_rProperty, + OUString const & i_rContent, + OUString const & i_rDatatype) +{ + // N.B.: we only get called if i_xObject had xhtml:about attribute + // (an empty attribute value is valid) + ::xmloff::RDFaImportHelper & rRDFaHelper( GetRDFaImportHelper() ); + rRDFaHelper.ParseAndAddRDFa(i_xObject, + i_rAbout, i_rProperty, i_rContent, i_rDatatype); +} + +bool SvXMLImport::embeddedFontAlreadyProcessed( const OUString& url ) +{ + if( embeddedFontUrlsKnown.count( url ) != 0 ) + return true; + embeddedFontUrlsKnown.insert( url ); + return false; +} + +const OUString & SvXMLImport::getNameFromToken( sal_Int32 nToken ) +{ + return xTokenHandler->getIdentifier( nToken & TOKEN_MASK ); +} + +OUString SvXMLImport::getPrefixAndNameFromToken( sal_Int32 nToken ) +{ + OUString rv; + sal_Int32 nNamespaceToken = ( nToken & NMSP_MASK ) >> NMSP_SHIFT; + auto aIter( aNamespaceMap.find( nNamespaceToken ) ); + if( aIter != aNamespaceMap.end() ) + rv = (*aIter).second.second + " " + aIter->second.first + ":"; + return rv + xTokenHandler->getIdentifier( nToken & TOKEN_MASK ); +} + +OUString SvXMLImport::getNamespacePrefixFromToken(sal_Int32 nToken, const SvXMLNamespaceMap* pMap) +{ + sal_Int32 nNamespaceToken = ( nToken & NMSP_MASK ) >> NMSP_SHIFT; + auto aIter( aNamespaceMap.find( nNamespaceToken ) ); + if( aIter != aNamespaceMap.end() ) + { + if (pMap) + { + OUString sRet = pMap->GetPrefixByKey(pMap->GetKeyByName((*aIter).second.second)); + if (!sRet.isEmpty()) + return sRet; + } + return (*aIter).second.first; + } + else + return OUString(); +} + +OUString SvXMLImport::getNamespaceURIFromToken( sal_Int32 nToken ) +{ + sal_Int32 nNamespaceToken = ( nToken & NMSP_MASK ) >> NMSP_SHIFT; + auto aIter( aNamespaceMap.find( nNamespaceToken ) ); + if( aIter != aNamespaceMap.end() ) + return (*aIter).second.second; + else + return OUString(); +} + +OUString SvXMLImport::getNamespacePrefixFromURI( const OUString& rURI ) +{ + auto aIter( aNamespaceURIPrefixMap.find(rURI) ); + if( aIter != aNamespaceURIPrefixMap.end() ) + return (*aIter).second; + else + return OUString(); +} + +void SvXMLImport::initializeNamespaceMaps() +{ + auto mapTokenToNamespace = [&]( sal_Int32 nToken, sal_Int32 nPrefix, sal_Int32 nNamespace ) + { + if ( nToken >= 0 ) + { + const OUString& sNamespace = GetXMLToken( static_cast<XMLTokenEnum>( nNamespace ) ); + const OUString& sPrefix = GetXMLToken( static_cast<XMLTokenEnum>( nPrefix ) ); + assert( aNamespaceMap.find(nToken +1) == aNamespaceMap.end() && "cannot map two namespaces to the same token here"); + aNamespaceMap[ nToken + 1 ] = std::make_pair( sPrefix, sNamespace ); + aNamespaceURIPrefixMap.emplace( sNamespace, sPrefix ); + } + }; + + mapTokenToNamespace( XML_NAMESPACE_OFFICE, XML_NP_OFFICE, XML_N_OFFICE ); + mapTokenToNamespace( XML_NAMESPACE_OFFICE_SO52, XML_NP_OFFICE, XML_N_OFFICE_OLD ); + mapTokenToNamespace( XML_NAMESPACE_OFFICE_OOO, XML_NP_OFFICE, XML_N_OFFICE_OOO ); + mapTokenToNamespace( XML_NAMESPACE_STYLE, XML_NP_STYLE, XML_N_STYLE ); + mapTokenToNamespace( XML_NAMESPACE_STYLE_SO52, XML_NP_STYLE, XML_N_STYLE_OLD ); + mapTokenToNamespace( XML_NAMESPACE_STYLE_OOO, XML_NP_STYLE, XML_N_STYLE_OOO ); + mapTokenToNamespace( XML_NAMESPACE_TEXT, XML_NP_TEXT, XML_N_TEXT ); + mapTokenToNamespace( XML_NAMESPACE_TEXT_SO52, XML_NP_TEXT, XML_N_TEXT_OLD ); + mapTokenToNamespace( XML_NAMESPACE_TEXT_OOO, XML_NP_TEXT, XML_N_TEXT_OOO ); + mapTokenToNamespace( XML_NAMESPACE_TABLE, XML_NP_TABLE, XML_N_TABLE ); + mapTokenToNamespace( XML_NAMESPACE_TABLE_SO52, XML_NP_TABLE, XML_N_TABLE_OLD ); + mapTokenToNamespace( XML_NAMESPACE_TABLE_OOO, XML_NP_TABLE, XML_N_TABLE_OOO ); + mapTokenToNamespace( XML_NAMESPACE_DRAW, XML_NP_DRAW, XML_N_DRAW ); + mapTokenToNamespace( XML_NAMESPACE_DRAW_SO52, XML_NP_DRAW, XML_N_DRAW_OLD ); + mapTokenToNamespace( XML_NAMESPACE_DRAW_OOO, XML_NP_DRAW, XML_N_DRAW_OOO ); + mapTokenToNamespace( XML_NAMESPACE_FO, XML_NP_FO, XML_N_FO ); + mapTokenToNamespace( XML_NAMESPACE_FO_SO52, XML_NP_FO, XML_N_FO_OLD ); + mapTokenToNamespace( XML_NAMESPACE_FO_COMPAT, XML_NP_FO, XML_N_FO_COMPAT ); + mapTokenToNamespace( XML_NAMESPACE_XLINK, XML_NP_XLINK, XML_N_XLINK ); + mapTokenToNamespace( XML_NAMESPACE_XLINK_SO52, XML_NP_XLINK, XML_N_XLINK_OLD ); + mapTokenToNamespace( XML_NAMESPACE_DC, XML_NP_DC, XML_N_DC ); + mapTokenToNamespace( XML_NAMESPACE_META, XML_NP_META, XML_N_META ); + mapTokenToNamespace( XML_NAMESPACE_META_SO52, XML_NP_META, XML_N_META_OLD ); + mapTokenToNamespace( XML_NAMESPACE_META_OOO, XML_NP_META, XML_N_META_OOO ); + mapTokenToNamespace( XML_NAMESPACE_NUMBER, XML_NP_NUMBER, XML_N_NUMBER ); + mapTokenToNamespace( XML_NAMESPACE_NUMBER_SO52, XML_NP_NUMBER, XML_N_NUMBER_OLD ); + mapTokenToNamespace( XML_NAMESPACE_NUMBER_OOO, XML_NP_NUMBER, XML_N_NUMBER_OOO ); + mapTokenToNamespace( XML_NAMESPACE_PRESENTATION, XML_NP_PRESENTATION, XML_N_PRESENTATION ); + mapTokenToNamespace( XML_NAMESPACE_PRESENTATION_SO52,XML_NP_PRESENTATION, XML_N_PRESENTATION_OLD ); + mapTokenToNamespace( XML_NAMESPACE_PRESENTATION_OOO, XML_NP_PRESENTATION, XML_N_PRESENTATION_OOO ); + mapTokenToNamespace( XML_NAMESPACE_PRESENTATION_OASIS, XML_NP_PRESENTATION, XML_N_PRESENTATION_OASIS ); + mapTokenToNamespace( XML_NAMESPACE_SVG, XML_NP_SVG, XML_N_SVG ); + mapTokenToNamespace( XML_NAMESPACE_SVG_COMPAT, XML_NP_SVG, XML_N_SVG_COMPAT ); + mapTokenToNamespace( XML_NAMESPACE_CHART, XML_NP_CHART, XML_N_CHART ); + mapTokenToNamespace( XML_NAMESPACE_CHART_SO52, XML_NP_CHART, XML_N_CHART_OLD ); + mapTokenToNamespace( XML_NAMESPACE_CHART_OOO, XML_NP_CHART, XML_N_CHART_OOO ); + mapTokenToNamespace( XML_NAMESPACE_DR3D, XML_NP_DR3D, XML_N_DR3D ); + mapTokenToNamespace( XML_NAMESPACE_DR3D_OOO, XML_NP_DR3D, XML_N_DR3D_OOO ); + mapTokenToNamespace( XML_NAMESPACE_MATH, XML_NP_MATH, XML_N_MATH ); + mapTokenToNamespace( XML_NAMESPACE_VERSIONS_LIST, XML_NP_VERSIONS_LIST, XML_N_VERSIONS_LIST ); + mapTokenToNamespace( XML_NAMESPACE_FORM, XML_NP_FORM, XML_N_FORM ); + mapTokenToNamespace( XML_NAMESPACE_FORM_OOO, XML_NP_FORM, XML_N_FORM_OOO ); + mapTokenToNamespace( XML_NAMESPACE_SCRIPT, XML_NP_SCRIPT, XML_N_SCRIPT ); + mapTokenToNamespace( XML_NAMESPACE_SCRIPT_OOO, XML_NP_SCRIPT, XML_N_SCRIPT_OOO ); + mapTokenToNamespace( XML_NAMESPACE_BLOCKLIST, XML_NP_BLOCK_LIST, XML_N_BLOCK_LIST ); + mapTokenToNamespace( XML_NAMESPACE_CONFIG, XML_NP_CONFIG, XML_N_CONFIG ); + mapTokenToNamespace( XML_NAMESPACE_CONFIG_OOO, XML_NP_CONFIG, XML_N_CONFIG_OOO ); + mapTokenToNamespace( XML_NAMESPACE_OOO, XML_NP_OOO, XML_N_OOO ); + mapTokenToNamespace( XML_NAMESPACE_OOOW, XML_NP_OOOW, XML_N_OOOW ); + mapTokenToNamespace( XML_NAMESPACE_OOOC, XML_NP_OOOC, XML_N_OOOC ); + mapTokenToNamespace( XML_NAMESPACE_DOM, XML_NP_DOM, XML_N_DOM ); + mapTokenToNamespace( XML_NAMESPACE_DB, XML_NP_DB, XML_N_DB ); + mapTokenToNamespace( XML_NAMESPACE_DB_OASIS, XML_NP_DB, XML_N_DB_OASIS ); + mapTokenToNamespace( XML_NAMESPACE_DLG, XML_NP_DLG, XML_N_DLG ); + mapTokenToNamespace( XML_NAMESPACE_XFORMS, XML_NP_XFORMS_1_0, XML_N_XFORMS_1_0 ); + mapTokenToNamespace( XML_NAMESPACE_XSD, XML_NP_XSD, XML_N_XSD ); + mapTokenToNamespace( XML_NAMESPACE_XSI, XML_NP_XSI, XML_N_XSI ); + mapTokenToNamespace( XML_NAMESPACE_SMIL, XML_NP_SMIL, XML_N_SMIL ); + mapTokenToNamespace( XML_NAMESPACE_SMIL_SO52, XML_NP_SMIL, XML_N_SMIL_OLD ); + mapTokenToNamespace( XML_NAMESPACE_SMIL_COMPAT, XML_NP_SMIL, XML_N_SMIL_COMPAT ); + mapTokenToNamespace( XML_NAMESPACE_ANIMATION, XML_NP_ANIMATION, XML_N_ANIMATION ); + mapTokenToNamespace( XML_NAMESPACE_ANIMATION_OOO, XML_NP_ANIMATION, XML_N_ANIMATION_OOO ); + mapTokenToNamespace( XML_NAMESPACE_REPORT, XML_NP_RPT, XML_N_RPT ); + mapTokenToNamespace( XML_NAMESPACE_REPORT_OASIS, XML_NP_RPT, XML_N_RPT_OASIS ); + mapTokenToNamespace( XML_NAMESPACE_OF, XML_NP_OF, XML_N_OF ); + mapTokenToNamespace( XML_NAMESPACE_XHTML, XML_NP_XHTML, XML_N_XHTML ); + mapTokenToNamespace( XML_NAMESPACE_GRDDL, XML_NP_GRDDL, XML_N_GRDDL ); + mapTokenToNamespace( XML_NAMESPACE_OFFICE_EXT, XML_NP_OFFICE_EXT, XML_N_OFFICE_EXT ); + mapTokenToNamespace( XML_NAMESPACE_TABLE_EXT, XML_NP_TABLE_EXT, XML_N_TABLE_EXT ); + mapTokenToNamespace( XML_NAMESPACE_CHART_EXT, XML_NP_CHART_EXT, XML_N_CHART_EXT ); + mapTokenToNamespace( XML_NAMESPACE_DRAW_EXT, XML_NP_DRAW_EXT, XML_N_DRAW_EXT ); + mapTokenToNamespace( XML_NAMESPACE_CALC_EXT, XML_NP_CALC_EXT, XML_N_CALC_EXT ); + mapTokenToNamespace( XML_NAMESPACE_LO_EXT, XML_NP_LO_EXT, XML_N_LO_EXT ); + mapTokenToNamespace( XML_NAMESPACE_CSS3TEXT, XML_NP_CSS3TEXT, XML_N_CSS3TEXT ); + mapTokenToNamespace( XML_NAMESPACE_FIELD, XML_NP_FIELD, XML_N_FIELD ); + mapTokenToNamespace( XML_NAMESPACE_FORMX, XML_NP_FORMX, XML_N_FORMX ); +} + +void SvXMLImport::registerNamespaces() +{ + for( auto const &aNamespaceEntry : aNamespaceMap ) + { + // aNamespaceMap = { Token : ( NamespacePrefix, NamespaceURI ) } + registerNamespace( aNamespaceEntry.second.second, aNamespaceEntry.first << NMSP_SHIFT ); + } +} + +void SvXMLImport::NotifyMacroEventRead() +{ + if (mbNotifyMacroEventRead) + return; + + comphelper::DocumentInfo::notifyMacroEventRead(mxModel); + + mbNotifyMacroEventRead = true; +} + +SvXMLImportFastNamespaceHandler::SvXMLImportFastNamespaceHandler() +{ +} + +void SvXMLImportFastNamespaceHandler::addNSDeclAttributes( rtl::Reference < comphelper::AttributeList > const & rAttrList ) +{ + for(const auto& aNamespaceDefine : m_aNamespaceDefines) + { + OUString& rPrefix = aNamespaceDefine->m_aPrefix; + OUString& rNamespaceURI = aNamespaceDefine->m_aNamespaceURI; + OUString sDecl; + if ( rPrefix.isEmpty() ) + sDecl = "xmlns"; + else + sDecl = "xmlns:" + rPrefix; + rAttrList->AddAttribute( sDecl, "CDATA", rNamespaceURI ); + } + m_aNamespaceDefines.clear(); +} + +void SvXMLImportFastNamespaceHandler::registerNamespace( const OUString& rNamespacePrefix, const OUString& rNamespaceURI ) +{ + // Elements with default namespace parsed by FastParser have namespace prefix. + // A default namespace needs to be registered with the prefix, to maintain the compatibility. + if ( rNamespacePrefix.isEmpty() ) + m_aNamespaceDefines.push_back( std::make_unique<NamespaceDefine>( + SvXMLImport::getNamespacePrefixFromURI( rNamespaceURI ), rNamespaceURI) ); + + m_aNamespaceDefines.push_back( std::make_unique<NamespaceDefine>( + rNamespacePrefix, rNamespaceURI) ); +} + +OUString SvXMLImportFastNamespaceHandler::getNamespaceURI( const OUString&/* rNamespacePrefix */ ) +{ + return OUString(); +} + +SvXMLLegacyToFastDocHandler::SvXMLLegacyToFastDocHandler( const rtl::Reference< SvXMLImport > & rImport ) +: mrImport( rImport ), + mxFastAttributes( new sax_fastparser::FastAttributeList( SvXMLImport::xTokenHandler.get() ) ) +{ +} + +void SAL_CALL SvXMLLegacyToFastDocHandler::setTargetDocument( const uno::Reference< lang::XComponent >& xDoc ) +{ + mrImport->setTargetDocument( xDoc ); +} + +void SAL_CALL SvXMLLegacyToFastDocHandler::startDocument() +{ + mrImport->startDocument(); +} + +void SAL_CALL SvXMLLegacyToFastDocHandler::endDocument() +{ + mrImport->endDocument(); +} + +void SAL_CALL SvXMLLegacyToFastDocHandler::startElement( const OUString& rName, + const uno::Reference< xml::sax::XAttributeList >& xAttrList ) +{ + mrImport->processNSAttributes(xAttrList); + OUString aLocalName; + sal_uInt16 nPrefix = mrImport->mpNamespaceMap->GetKeyByAttrName( rName, &aLocalName ); + Sequence< sal_Int8 > aLocalNameSeq( reinterpret_cast<sal_Int8 const *>( + OUStringToOString( aLocalName, RTL_TEXTENCODING_UTF8 ).getStr()), aLocalName.getLength() ); + sal_Int32 mnElement = NAMESPACE_TOKEN( nPrefix ) | SvXMLImport::xTokenHandler->getTokenFromUTF8( aLocalNameSeq ); + mxFastAttributes->clear(); + + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + for( sal_Int16 i=0; i < nAttrCount; i++ ) + { + OUString aLocalAttrName; + OUString aNamespace; + const OUString& rAttrName = xAttrList->getNameByIndex( i ); + const OUString& rAttrValue = xAttrList->getValueByIndex( i ); + sal_uInt16 const nAttrPrefix(mrImport->mpNamespaceMap->GetKeyByAttrName( + rAttrName, nullptr, &aLocalAttrName, &aNamespace)); + if( XML_NAMESPACE_XMLNS != nAttrPrefix ) + { + Sequence< sal_Int8 > aAttrSeq( reinterpret_cast<sal_Int8 const *>( + OUStringToOString( aLocalAttrName, RTL_TEXTENCODING_UTF8 ).getStr()), aLocalAttrName.getLength() ); + auto const nToken(SvXMLImport::xTokenHandler->getTokenFromUTF8(aAttrSeq)); + if (nToken == xmloff::XML_TOKEN_INVALID) + { + mxFastAttributes->addUnknown(aNamespace, + OUStringToOString(rAttrName, RTL_TEXTENCODING_UTF8), + OUStringToOString(rAttrValue, RTL_TEXTENCODING_UTF8)); + } + else + { + sal_Int32 const nAttr = NAMESPACE_TOKEN(nAttrPrefix) | nToken; + mxFastAttributes->add(nAttr, OUStringToOString(rAttrValue, RTL_TEXTENCODING_UTF8).getStr()); + } + } + } + mrImport->startFastElement( mnElement, mxFastAttributes.get() ); +} + +void SAL_CALL SvXMLLegacyToFastDocHandler::endElement( const OUString& rName ) +{ + OUString aLocalName; + sal_uInt16 nPrefix = mrImport->mpNamespaceMap->GetKeyByAttrName( rName, &aLocalName ); + Sequence< sal_Int8 > aLocalNameSeq( reinterpret_cast<sal_Int8 const *>( + OUStringToOString( aLocalName, RTL_TEXTENCODING_UTF8 ).getStr()), aLocalName.getLength() ); + sal_Int32 mnElement = NAMESPACE_TOKEN( nPrefix ) | SvXMLImport::xTokenHandler->getTokenFromUTF8( aLocalNameSeq ); + mrImport->endFastElement( mnElement ); +} + +void SAL_CALL SvXMLLegacyToFastDocHandler::characters( const OUString& aChars ) +{ + mrImport->characters( aChars ); +} + +void SAL_CALL SvXMLLegacyToFastDocHandler::ignorableWhitespace( const OUString& aWhitespaces ) +{ + mrImport->ignorableWhitespace( aWhitespaces ); +} + +void SAL_CALL SvXMLLegacyToFastDocHandler::processingInstruction( const OUString& aTarget, + const OUString& aData) +{ + mrImport->processingInstruction( aTarget, aData ); +} + +void SAL_CALL SvXMLLegacyToFastDocHandler::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& rLocator ) +{ + mrImport->setDocumentLocator( rLocator ); +} + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/xmlmultiimagehelper.cxx b/xmloff/source/core/xmlmultiimagehelper.cxx new file mode 100644 index 000000000..af03e7bb1 --- /dev/null +++ b/xmloff/source/core/xmlmultiimagehelper.cxx @@ -0,0 +1,176 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <rtl/ustring.hxx> +#include <xmlmultiimagehelper.hxx> + +#include <comphelper/graphicmimetype.hxx> + +using namespace ::com::sun::star; + +namespace +{ + OUString getMimeTypeForURL(const OUString& rString) + { + OUString sMimeType; + if (rString.startsWith("vnd.sun.star.Package")) + { + OString aExtension = OUStringToOString(rString.copy(rString.lastIndexOf(".") + 1), RTL_TEXTENCODING_ASCII_US); + sMimeType = comphelper::GraphicMimeTypeHelper::GetMimeTypeForExtension(aExtension); + } + return sMimeType; + } + + sal_uInt32 getQualityIndex(const OUString& rMimeType) + { + // pixel formats first + if (rMimeType == "image/bmp") + { + return 10; + } + if (rMimeType == "image/gif") + { + return 20; + } + if (rMimeType == "image/jpeg") + { + return 30; + } + if (rMimeType == "image/png") + { + return 40; + } + + // vector formats, prefer always + if (rMimeType == "image/x-vclgraphic") // MIMETYPE_VCLGRAPHIC + { + return 990; + } + if (rMimeType == "image/x-svm") + { + return 1000; + } + if (rMimeType == "image/x-wmf") + { + return 1010; + } + if (rMimeType == "image/x-emf") + { + return 1020; + } + if (rMimeType == "image/x-eps") + { + return 1025; + } + if (rMimeType == "application/pdf") + { + return 1030; + } + if (rMimeType == "image/svg+xml") + { + return 1040; + } + + return 0; + } +} + +MultiImageImportHelper::MultiImageImportHelper() +: maImplContextVector(), + mbSupportsMultipleContents(false) +{ +} + +MultiImageImportHelper::~MultiImageImportHelper() +{ +} + +SvXMLImportContextRef MultiImageImportHelper::solveMultipleImages() +{ + SvXMLImportContextRef pContext; + if(maImplContextVector.size() > 1) + { + // multiple child contexts were imported, decide which is the most valuable one + // and remove the rest + std::vector<SvXMLImportContextRef>::size_type nIndexOfPreferred(maImplContextVector.size()); + sal_uInt32 nBestQuality(0); + + for(std::vector<SvXMLImportContextRef>::size_type a = 0; a < maImplContextVector.size(); a++) + { + const SvXMLImportContext& rContext = *maImplContextVector[a]; + + + OUString sMimeType; + + const OUString aStreamURL(getGraphicPackageURLFromImportContext(rContext)); + if (!aStreamURL.isEmpty()) + { + sMimeType = getMimeTypeForURL(aStreamURL); + } + else + { + uno::Reference<graphic::XGraphic> xGraphic(getGraphicFromImportContext(rContext)); + if (xGraphic.is()) + sMimeType = comphelper::GraphicMimeTypeHelper::GetMimeTypeForXGraphic(xGraphic); + } + + sal_uInt32 nNewQuality = getQualityIndex(sMimeType); + if (nNewQuality > nBestQuality) + { + nBestQuality = nNewQuality; + nIndexOfPreferred = a; + } + } + + // correct if needed, default is to use the last entry + if(nIndexOfPreferred >= maImplContextVector.size()) + { + nIndexOfPreferred = maImplContextVector.size() - 1; + } + + // Take out the most valuable one + const std::vector< SvXMLImportContextRef >::iterator aRemove(maImplContextVector.begin() + nIndexOfPreferred); + pContext = *aRemove; + maImplContextVector.erase(aRemove); + + // remove the rest from parent + for(std::vector<SvXMLImportContextRef>::size_type a = 0; a < maImplContextVector.size(); a++) + { + SvXMLImportContext& rCandidate = *maImplContextVector[a]; + + removeGraphicFromImportContext(rCandidate); + } + // re-insert it so that solveMultipleImages is idempotent + maImplContextVector.clear(); + maImplContextVector.push_back(pContext); + } + else if (maImplContextVector.size() == 1) + { + pContext = maImplContextVector.front(); + } + + return pContext; +} + +void MultiImageImportHelper::addContent(const SvXMLImportContext& rSvXMLImportContext) +{ + maImplContextVector.emplace_back(const_cast< SvXMLImportContext* >(&rSvXMLImportContext)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/xmltkmap.cxx b/xmloff/source/core/xmltkmap.cxx new file mode 100644 index 000000000..d89eb9621 --- /dev/null +++ b/xmloff/source/core/xmltkmap.cxx @@ -0,0 +1,104 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <rtl/ustring.hxx> +#include <xmloff/xmltkmap.hxx> +#include <xmloff/xmltoken.hxx> +#include <boost/functional/hash.hpp> + +#include <unordered_map> +#include <utility> + +using namespace ::xmloff::token; + +class SvXMLTokenMap_Impl +{ +private: + struct PairHash + { + std::size_t operator()(const std::pair<sal_uInt16,OUString> &pair) const + { + std::size_t seed = 0; + boost::hash_combine(seed, pair.first); + boost::hash_combine(seed, pair.second.hashCode()); + return seed; + } + }; + std::unordered_map< std::pair<sal_uInt16, OUString>, + sal_uInt16, PairHash> m_aPrefixAndNameToTokenMap; + std::unordered_map< sal_Int32, sal_uInt16> m_aFastTokenToTokenMap; + +public: + void insert( const SvXMLTokenMapEntry& rEntry ); + sal_uInt16 get( sal_uInt16 nKeyPrefix, const OUString& rLName ) const; + sal_uInt16 get( sal_Int32 nFastTok ) const; +}; + +void SvXMLTokenMap_Impl::insert( const SvXMLTokenMapEntry& rEntry ) +{ + m_aPrefixAndNameToTokenMap.insert( std::make_pair( std::make_pair( rEntry.nPrefixKey, + GetXMLToken( rEntry.eLocalName ) ), rEntry.nToken ) ); + if( rEntry.nFastToken ) + m_aFastTokenToTokenMap.insert( std::make_pair( rEntry.nFastToken, rEntry.nToken ) ); +} + +sal_uInt16 SvXMLTokenMap_Impl::get( sal_uInt16 nKeyPrefix, const OUString& rLName ) const +{ + auto aIter( m_aPrefixAndNameToTokenMap.find( std::make_pair( nKeyPrefix, rLName ) ) ); + if ( aIter != m_aPrefixAndNameToTokenMap.end() ) + return (*aIter).second; + else + return XML_TOK_UNKNOWN; +} + +sal_uInt16 SvXMLTokenMap_Impl::get( sal_Int32 nFastTok ) const +{ + auto aIter( m_aFastTokenToTokenMap.find( nFastTok ) ); + if ( aIter != m_aFastTokenToTokenMap.end() ) + return (*aIter).second; + else + return XML_TOK_UNKNOWN; +} + +SvXMLTokenMap::SvXMLTokenMap( const SvXMLTokenMapEntry *pMap ) + : m_pImpl( new SvXMLTokenMap_Impl ) +{ + while( pMap->eLocalName != XML_TOKEN_INVALID ) + { + m_pImpl->insert( *pMap ); + pMap++; + } +} + +SvXMLTokenMap::~SvXMLTokenMap() +{ +} + +sal_uInt16 SvXMLTokenMap::Get( sal_uInt16 nKeyPrefix, + const OUString& rLName ) const +{ + return m_pImpl->get( nKeyPrefix, rLName ); +} + +sal_uInt16 SvXMLTokenMap::Get( sal_Int32 nFastTok ) const +{ + return m_pImpl->get( nFastTok ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx new file mode 100644 index 000000000..8d9a70f5e --- /dev/null +++ b/xmloff/source/core/xmltoken.cxx @@ -0,0 +1,3449 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/macros.h> +#include <xmloff/xmltoken.hxx> +#include <rtl/ustring.hxx> +#include <rtl/string.hxx> +#include <sal/log.hxx> +#include <optional> +#include <set> + + +namespace xmloff::token { + + // keep the tokens (and their length) + namespace + { + struct XMLTokenEntry + { + sal_Int32 nLength; + const char* pChar; + std::optional<OUString> xOUString; +#if OSL_DEBUG_LEVEL > 0 + XMLTokenEnum eToken; +#endif + }; + } + + +#if OSL_DEBUG_LEVEL > 0 + #define TOKEN( s, e ) { sizeof(s)-1, s, std::nullopt, e } +#else + #define TOKEN( s, e ) { sizeof(s)-1, s, std::nullopt } +#endif + + // IMPORTANT! aTokenList order MUST be in synch with XMLTokenEnum in include/xmloff/xmltoken.hxx + // and with xmloff/source/token/tokens.txt. + + struct XMLTokenEntry aTokenList[] = + { +#if OSL_DEBUG_LEVEL > 0 + { 0, nullptr, std::nullopt, XML_TOKEN_START }, +#else + { 0, nullptr, std::nullopt }, // XML_TOKEN_START +#endif + + // common XML + TOKEN( "CDATA", XML_CDATA ), + TOKEN( " ", XML_WS ), + TOKEN( "xml", XML_XML ), + TOKEN( "xmlns", XML_XMLNS ), + TOKEN( "version=\"1.0\" encoding=\"UTF-8\"", XML_XML_PI ), + TOKEN( "<!DOCTYPE ", XML_XML_DOCTYPE_PREFIX ), + TOKEN( " PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"office.dtd\">", XML_XML_DOCTYPE_SUFFIX ), + + // namespace prefixes and names + TOKEN( "http://www.w3.org/XML/1998/namespace", XML_N_XML ), + TOKEN( "office", XML_NP_OFFICE ), + TOKEN( "urn:oasis:names:tc:opendocument:xmlns:office:1.0", XML_N_OFFICE ), + TOKEN( "http://sun.com/xmlns/staroffice/office", XML_N_OFFICE_OLD ), + TOKEN( "meta", XML_NP_META ), + TOKEN( "urn:oasis:names:tc:opendocument:xmlns:meta:1.0", XML_N_META ), + TOKEN( "http://sun.com/xmlns/staroffice/meta", XML_N_META_OLD ), + TOKEN( "style", XML_NP_STYLE ), + TOKEN( "urn:oasis:names:tc:opendocument:xmlns:style:1.0", XML_N_STYLE ), + TOKEN( "http://sun.com/xmlns/staroffice/style", XML_N_STYLE_OLD ), + TOKEN( "number", XML_NP_NUMBER ), + TOKEN( "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0", XML_N_NUMBER ), + TOKEN( "http://sun.com/xmlns/staroffice/number", XML_N_NUMBER_OLD ), + TOKEN( "text", XML_NP_TEXT ), + TOKEN( "urn:oasis:names:tc:opendocument:xmlns:text:1.0", XML_N_TEXT ), + TOKEN( "http://sun.com/xmlns/staroffice/text", XML_N_TEXT_OLD ), + TOKEN( "table", XML_NP_TABLE ), + TOKEN( "urn:oasis:names:tc:opendocument:xmlns:table:1.0", XML_N_TABLE ), + TOKEN( "http://sun.com/xmlns/staroffice/table", XML_N_TABLE_OLD ), + TOKEN( "draw", XML_NP_DRAW ), + TOKEN( "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0", XML_N_DRAW ), + TOKEN( "dr3d", XML_NP_DR3D ), + TOKEN( "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0", XML_N_DR3D ), + TOKEN( "http://sun.com/xmlns/staroffice/draw", XML_N_DRAW_OLD ), + TOKEN( "presentation", XML_NP_PRESENTATION ), + TOKEN( "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0", XML_N_PRESENTATION ), + TOKEN( "http://sun.com/xmlns/staroffice/presentation", XML_N_PRESENTATION_OLD ), + TOKEN( "chart", XML_NP_CHART ), + TOKEN( "urn:oasis:names:tc:opendocument:xmlns:chart:1.0", XML_N_CHART ), + TOKEN( "config", XML_NP_CONFIG ), + TOKEN( "urn:oasis:names:tc:opendocument:xmlns:config:1.0", XML_N_CONFIG ), + TOKEN( "http://sun.com/xmlns/staroffice/chart", XML_N_CHART_OLD ), + TOKEN( "fo", XML_NP_FO ), + TOKEN( "http://www.w3.org/1999/XSL/Format/", XML_N_FO_OLD ), + TOKEN( "http://www.w3.org/1999/XSL/Format", XML_N_FO ), + TOKEN( "xlink", XML_NP_XLINK ), + TOKEN( "http://www.w3.org/1999/xlink", XML_N_XLINK ), + TOKEN( "http://www.w3.org/1999/xlink/namespace", XML_N_XLINK_OLD ), + TOKEN( "dc", XML_NP_DC ), + TOKEN( "http://purl.org/dc/elements/1.1/", XML_N_DC ), + TOKEN( "svg", XML_NP_SVG ), + TOKEN( "http://www.w3.org/2000/svg", XML_N_SVG ), + TOKEN( "form", XML_NP_FORM ), + TOKEN( "urn:oasis:names:tc:opendocument:xmlns:form:1.0", XML_N_FORM ), + TOKEN( "script", XML_NP_SCRIPT ), + TOKEN( "urn:oasis:names:tc:opendocument:xmlns:script:1.0", XML_N_SCRIPT ), + TOKEN( "tcd", XML_NP_TCD ), + TOKEN( "http://openoffice.org/2003/text-conversion-dictionary", XML_N_TCD ), + TOKEN( "xforms", XML_NP_XFORMS_1_0 ), + TOKEN( "http://www.w3.org/2002/xforms", XML_N_XFORMS_1_0 ), + TOKEN( "xsd", XML_NP_XSD ), + TOKEN( "http://www.w3.org/2001/XMLSchema", XML_N_XSD ), + TOKEN( "xsi", XML_NP_XSI ), + TOKEN( "http://www.w3.org/2001/XMLSchema-instance", XML_N_XSI ), + + TOKEN( "block-list", XML_NP_BLOCK_LIST ), + TOKEN( "http://openoffice.org/2001/block-list", XML_N_BLOCK_LIST ), + + TOKEN( "math", XML_NP_MATH ), + TOKEN( "http://www.w3.org/1998/Math/MathML", XML_N_MATH ), + + TOKEN( "VL", XML_NP_VERSIONS_LIST ), + TOKEN( "http://openoffice.org/2001/versions-list", XML_N_VERSIONS_LIST ), + + // erAck: 2008-04-09T20:12+0200 OpenFormula aka ODFF + TOKEN( "of", XML_NP_OF ), + TOKEN( "urn:oasis:names:tc:opendocument:xmlns:of:1.2", XML_N_OF ), + + // ODF 1.2 metadata: RDFa and GRDDL + TOKEN( "xhtml", XML_NP_XHTML ), + TOKEN( "http://www.w3.org/1999/xhtml", XML_N_XHTML ), + TOKEN( "grddl", XML_NP_GRDDL ), + TOKEN( "http://www.w3.org/2003/g/data-view#", XML_N_GRDDL ), + + // ODF Enhanced namespaces + TOKEN( "officeooo", XML_NP_OFFICE_EXT ), + TOKEN( "http://openoffice.org/2009/office", XML_N_OFFICE_EXT ), + + // jonp: 2008-09-24 Excel Interop + TOKEN( "formx", XML_NP_FORMX ), + TOKEN( "urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0", XML_N_FORMX ), + TOKEN( "tableooo", XML_NP_TABLE_EXT ), + TOKEN( "http://openoffice.org/2009/table", XML_N_TABLE_EXT ), + + TOKEN( "drawooo", XML_NP_DRAW_EXT ), + TOKEN( "http://openoffice.org/2010/draw", XML_N_DRAW_EXT ), + + TOKEN( "css3t", XML_NP_CSS3TEXT ), + TOKEN( "http://www.w3.org/TR/css3-text/", XML_N_CSS3TEXT ), + + // extension namespace for calc extensions + TOKEN( "calcext", XML_NP_CALC_EXT ), + TOKEN( "urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0", XML_N_CALC_EXT ), + TOKEN( "loext", XML_NP_LO_EXT ), + TOKEN( "urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0", XML_N_LO_EXT ), + + TOKEN( "urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0", XML_N_FIELD ), + TOKEN( "field", XML_NP_FIELD ), + + // units + TOKEN( "m", XML_UNIT_M ), + TOKEN( "cm", XML_UNIT_CM ), + TOKEN( "pt", XML_UNIT_PT ), + TOKEN( "pc", XML_UNIT_PC ), + TOKEN( "ft", XML_UNIT_FOOT ), + + // any other + TOKEN( "1", XML_1 ), + TOKEN( "10", XML_10 ), + TOKEN( "2", XML_2 ), + TOKEN( "3", XML_3 ), + TOKEN( "4", XML_4 ), + TOKEN( "5", XML_5 ), + TOKEN( "6", XML_6 ), + TOKEN( "7", XML_7 ), + TOKEN( "8", XML_8 ), + TOKEN( "9", XML_9 ), + TOKEN( "A", XML_A_UPCASE ), + TOKEN( "I", XML_I_UPCASE ), + TOKEN( "IBM437", XML_IBM437 ), + TOKEN( "IBM850", XML_IBM850 ), + TOKEN( "IBM860", XML_IBM860 ), + TOKEN( "IBM861", XML_IBM861 ), + TOKEN( "IBM863", XML_IBM863 ), + TOKEN( "IBM865", XML_IBM865 ), + TOKEN( "ISO-8859-1", XML_ISO_8859_1 ), + TOKEN( "ole2", XML_OLE2 ), + TOKEN( ":", XML__COLON ), + TOKEN( "", XML__EMPTY ), + TOKEN( "_unknown_", XML__UNKNOWN_ ), + + TOKEN( "a", XML_A ), + TOKEN( "abbreviated-name", XML_ABBREVIATED_NAME ), + TOKEN( "above", XML_ABOVE ), + TOKEN( "abs", XML_ABS ), + TOKEN( "accent", XML_ACCENT ), + TOKEN( "accentunder", XML_ACCENTUNDER ), + TOKEN( "acceptance-state", XML_ACCEPTANCE_STATE ), + TOKEN( "accepted", XML_ACCEPTED ), + TOKEN( "action", XML_ACTION ), + TOKEN( "active", XML_ACTIVE ), + TOKEN( "active-split-range", XML_ACTIVE_SPLIT_RANGE ), + TOKEN( "active-table", XML_ACTIVE_TABLE ), + TOKEN( "actuate", XML_ACTUATE ), + TOKEN( "add-in", XML_ADD_IN ), + TOKEN( "add-in-name", XML_ADD_IN_NAME ), + TOKEN( "address", XML_ADDRESS ), + TOKEN( "adjustment", XML_ADJUSTMENT ), + TOKEN( "algorithm", XML_ALGORITHM ), + TOKEN( "align", XML_ALIGN ), + TOKEN( "all", XML_ALL ), + TOKEN( "allow-empty-cell", XML_ALLOW_EMPTY_CELL ), + TOKEN( "alphabetical-index", XML_ALPHABETICAL_INDEX ), + TOKEN( "alphabetical-index-auto-mark-file", XML_ALPHABETICAL_INDEX_AUTO_MARK_FILE ), + TOKEN( "alphabetical-index-entry-template", XML_ALPHABETICAL_INDEX_ENTRY_TEMPLATE ), + TOKEN( "alphabetical-index-mark", XML_ALPHABETICAL_INDEX_MARK ), + TOKEN( "alphabetical-index-mark-end", XML_ALPHABETICAL_INDEX_MARK_END ), + TOKEN( "alphabetical-index-mark-start", XML_ALPHABETICAL_INDEX_MARK_START ), + TOKEN( "alphabetical-index-source", XML_ALPHABETICAL_INDEX_SOURCE ), + TOKEN( "alphabetical-separators", XML_ALPHABETICAL_SEPARATORS ), + TOKEN( "alternate", XML_ALTERNATE ), + TOKEN( "am-pm", XML_AM_PM ), + TOKEN( "ambient-color", XML_AMBIENT_COLOR ), + TOKEN( "anchor-page-number", XML_ANCHOR_PAGE_NUMBER ), + TOKEN( "anchor-type", XML_ANCHOR_TYPE ), + TOKEN( "and", XML_AND ), + TOKEN( "animation", XML_ANIMATION ), + TOKEN( "animation-delay", XML_ANIMATION_DELAY ), + TOKEN( "animation-direction", XML_ANIMATION_DIRECTION ), + TOKEN( "animation-repeat", XML_ANIMATION_REPEAT ), + TOKEN( "animation-start-inside", XML_ANIMATION_START_INSIDE ), + TOKEN( "animation-steps", XML_ANIMATION_STEPS ), + TOKEN( "animation-stop-inside", XML_ANIMATION_STOP_INSIDE ), + TOKEN( "animations", XML_ANIMATIONS ), + TOKEN( "annotation", XML_ANNOTATION ), + TOKEN( "annotation-end", XML_ANNOTATION_END ), + TOKEN( "annotations", XML_ANNOTATIONS ), + TOKEN( "annote", XML_ANNOTE ), + TOKEN( "appear", XML_APPEAR ), + TOKEN( "applet", XML_APPLET ), + TOKEN( "applet-name", XML_APPLET_NAME ), + TOKEN( "application-data", XML_APPLICATION_DATA ), + TOKEN( "application-xml", XML_APPLICATION_XML ), + TOKEN( "apply", XML_APPLY ), + TOKEN( "apply-design-mode", XML_APPLY_DESIGN_MODE ), + TOKEN( "apply-style-name", XML_APPLY_STYLE_NAME ), + TOKEN( "aqua", XML_AQUA ), + TOKEN( "arc", XML_ARC ), + TOKEN( "arccos", XML_ARCCOS ), + TOKEN( "archive", XML_ARCHIVE ), + TOKEN( "arcsin", XML_ARCSIN ), + TOKEN( "arctan", XML_ARCTAN ), + TOKEN( "area", XML_AREA ), + TOKEN( "area-circle", XML_AREA_CIRCLE ), + TOKEN( "area-polygon", XML_AREA_POLYGON ), + TOKEN( "area-rectangle", XML_AREA_RECTANGLE ), + TOKEN( "article", XML_ARTICLE ), + TOKEN( "as-char", XML_AS_CHAR ), + TOKEN( "ascending", XML_ASCENDING ), + TOKEN( "attached-axis", XML_ATTACHED_AXIS ), + TOKEN( "attractive", XML_ATTRACTIVE ), + TOKEN( "author", XML_AUTHOR ), + TOKEN( "author-initials", XML_AUTHOR_INITIALS ), + TOKEN( "author-name", XML_AUTHOR_NAME ), + TOKEN( "auto", XML_AUTO ), + TOKEN( "auto-complete", XML_AUTO_COMPLETE ), + TOKEN( "auto-grow-height", XML_AUTO_GROW_HEIGHT ), + TOKEN( "auto-grow-width", XML_AUTO_GROW_WIDTH ), + TOKEN( "auto-reload", XML_AUTO_RELOAD ), + TOKEN( "auto-text", XML_AUTO_TEXT ), + TOKEN( "auto-text-events", XML_AUTO_TEXT_EVENTS ), + TOKEN( "auto-text-group", XML_AUTO_TEXT_GROUP ), + TOKEN( "auto-text-indent", XML_AUTO_TEXT_INDENT ), + TOKEN( "auto-update", XML_AUTO_UPDATE ), + TOKEN( "automatic", XML_AUTOMATIC ), + TOKEN( "automatic-find-labels", XML_AUTOMATIC_FIND_LABELS ), + TOKEN( "automatic-focus", XML_AUTOMATIC_FOCUS ), + TOKEN( "automatic-order", XML_AUTOMATIC_ORDER ), + TOKEN( "automatic-styles", XML_AUTOMATIC_STYLES ), + TOKEN( "automatic-update", XML_AUTOMATIC_UPDATE ), + TOKEN( "autosize", XML_AUTOSIZE ), + TOKEN( "average", XML_AVERAGE ), + TOKEN( "axis", XML_AXIS ), + TOKEN( "axis-color", XML_AXIS_COLOR ), + TOKEN( "back-scale", XML_BACK_SCALE ), + TOKEN( "backface-culling", XML_BACKFACE_CULLING ), + TOKEN( "background", XML_BACKGROUND ), + TOKEN( "background-color", XML_BACKGROUND_COLOR ), + TOKEN( "background-image", XML_BACKGROUND_IMAGE ), + TOKEN( "no-repeat", XML_BACKGROUND_NO_REPEAT ), + TOKEN( "bar", XML_BAR ), + TOKEN( "base64Binary", XML_BASE64BINARY ), + TOKEN( "base-cell-address", XML_BASE_CELL_ADDRESS ), + TOKEN( "baseline", XML_BASELINE ), + TOKEN( "before-date-time", XML_BEFORE_DATE_TIME ), + TOKEN( "below", XML_BELOW ), + TOKEN( "between-date-times", XML_BETWEEN_DATE_TIMES ), + TOKEN( "bevel", XML_BEVEL ), + TOKEN( "bevelled", XML_BEVELLED ), + TOKEN( "bibiliographic-type", XML_BIBILIOGRAPHIC_TYPE ), + TOKEN( "bibliography", XML_BIBLIOGRAPHY ), + TOKEN( "bibliography-configuration", XML_BIBLIOGRAPHY_CONFIGURATION ), + TOKEN( "bibliography-data-field", XML_BIBLIOGRAPHY_DATA_FIELD ), + TOKEN( "bibliography-entry-template", XML_BIBLIOGRAPHY_ENTRY_TEMPLATE ), + TOKEN( "bibliography-mark", XML_BIBLIOGRAPHY_MARK ), + TOKEN( "bibliography-source", XML_BIBLIOGRAPHY_SOURCE ), + TOKEN( "bibliography-type", XML_BIBLIOGRAPHY_TYPE ), + TOKEN( "bind-styles-to-content", XML_BIND_STYLES_TO_CONTENT ), + TOKEN( "bitmap", XML_BITMAP ), + TOKEN( "bitmap-table", XML_BITMAP_TABLE ), + TOKEN( "black", XML_BLACK ), + TOKEN( "blend", XML_BLEND ), + TOKEN( "blinking", XML_BLINKING ), + TOKEN( "block", XML_BLOCK ), + TOKEN( "block-list", XML_BLOCK_LIST ), + TOKEN( "blue", XML_BLUE ), + TOKEN( "body", XML_BODY ), + TOKEN( "bold", XML_BOLD ), + TOKEN( "book", XML_BOOK ), + TOKEN( "booklet", XML_BOOKLET ), + TOKEN( "bookmark", XML_BOOKMARK ), + TOKEN( "bookmark-end", XML_BOOKMARK_END ), + TOKEN( "bookmark-ref", XML_BOOKMARK_REF ), + TOKEN( "bookmark-start", XML_BOOKMARK_START ), + TOKEN( "booktitle", XML_BOOKTITLE ), + TOKEN( "boolean", XML_BOOLEAN ), + TOKEN( "boolean-style", XML_BOOLEAN_STYLE ), + TOKEN( "boolean-value", XML_BOOLEAN_VALUE ), + TOKEN( "border", XML_BORDER ), + TOKEN( "border-bottom", XML_BORDER_BOTTOM ), + TOKEN( "border-color", XML_BORDER_COLOR ), + TOKEN( "border-left", XML_BORDER_LEFT ), + TOKEN( "border-line-width", XML_BORDER_LINE_WIDTH ), + TOKEN( "border-line-width-bottom", XML_BORDER_LINE_WIDTH_BOTTOM ), + TOKEN( "border-line-width-left", XML_BORDER_LINE_WIDTH_LEFT ), + TOKEN( "border-line-width-right", XML_BORDER_LINE_WIDTH_RIGHT ), + TOKEN( "border-line-width-top", XML_BORDER_LINE_WIDTH_TOP ), + TOKEN( "border-right", XML_BORDER_RIGHT ), + TOKEN( "border-top", XML_BORDER_TOP ), + TOKEN( "both", XML_BOTH ), + TOKEN( "bottom", XML_BOTTOM ), + TOKEN( "bottom-left", XML_BOTTOM_LEFT ), + TOKEN( "bottom percent", XML_BOTTOM_PERCENT ), + TOKEN( "bottom-right", XML_BOTTOM_RIGHT ), + TOKEN( "bottom values", XML_BOTTOM_VALUES ), + TOKEN( "bottom-arc", XML_BOTTOMARC ), + TOKEN( "bottom-circle", XML_BOTTOMCIRCLE ), + TOKEN( "bound-column", XML_BOUND_COLUMN ), + TOKEN( "break-after", XML_BREAK_AFTER ), + TOKEN( "break-before", XML_BREAK_BEFORE ), + TOKEN( "break-inside", XML_BREAK_INSIDE ), + TOKEN( "bubble", XML_BUBBLE ), + TOKEN( "bullet-char", XML_BULLET_CHAR ), + TOKEN( "bullet-relative-size", XML_BULLET_RELATIVE_SIZE ), + TOKEN( "butt", XML_BUTT ), + TOKEN( "button1", XML_BUTTON1 ), + TOKEN( "button2", XML_BUTTON2 ), + TOKEN( "button3", XML_BUTTON3 ), + TOKEN( "button4", XML_BUTTON4 ), + TOKEN( "buttons", XML_BUTTONS ), + TOKEN( "bvar", XML_BVAR ), + TOKEN( "c", XML_C ), + TOKEN( "calculation-settings", XML_CALCULATION_SETTINGS ), + TOKEN( "calendar", XML_CALENDAR ), + TOKEN( "capitalize-entries", XML_CAPITALIZE_ENTRIES ), + TOKEN( "can-add-comment", XML_CAN_ADD_COMMENT ), + TOKEN( "caption", XML_CAPTION ), + TOKEN( "caption-point-x", XML_CAPTION_POINT_X ), + TOKEN( "caption-point-y", XML_CAPTION_POINT_Y ), + TOKEN( "caption-sequence-format", XML_CAPTION_SEQUENCE_FORMAT ), + TOKEN( "caption-sequence-name", XML_CAPTION_SEQUENCE_NAME ), + TOKEN( "case-sensitive", XML_CASE_SENSITIVE ), + TOKEN( "capitalize", XML_CASEMAP_CAPITALIZE ), + TOKEN( "lowercase", XML_CASEMAP_LOWERCASE ), + TOKEN( "small-caps", XML_CASEMAP_SMALL_CAPS ), + TOKEN( "uppercase", XML_CASEMAP_UPPERCASE ), + TOKEN( "categories", XML_CATEGORIES ), + TOKEN( "category", XML_CATEGORY ), + TOKEN( "category-and-value", XML_CATEGORY_AND_VALUE ), + TOKEN( "cell-address", XML_CELL_ADDRESS ), + TOKEN( "cell-content-change", XML_CELL_CONTENT_CHANGE ), + TOKEN( "cell-content-deletion", XML_CELL_CONTENT_DELETION ), + TOKEN( "cell-count", XML_CELL_COUNT ), + TOKEN( "cell-protect", XML_CELL_PROTECT ), + TOKEN( "cell-range-address", XML_CELL_RANGE_ADDRESS ), + TOKEN( "cell-range-address-list", XML_CELL_RANGE_ADDRESS_LIST ), + TOKEN( "cell-range-source", XML_CELL_RANGE_SOURCE ), + TOKEN( "center", XML_CENTER ), + TOKEN( "chain-next-name", XML_CHAIN_NEXT_NAME ), + TOKEN( "change", XML_CHANGE ), + TOKEN( "change-deletion", XML_CHANGE_DELETION ), + TOKEN( "change-end", XML_CHANGE_END ), + TOKEN( "change-id", XML_CHANGE_ID ), + TOKEN( "change-info", XML_CHANGE_INFO ), + TOKEN( "change-start", XML_CHANGE_START ), + TOKEN( "change-track-table-cell", XML_CHANGE_TRACK_TABLE_CELL ), + TOKEN( "change-view-conditions", XML_CHANGE_VIEW_CONDITIONS ), + TOKEN( "change-view-settings", XML_CHANGE_VIEW_SETTINGS ), + TOKEN( "changed-region", XML_CHANGED_REGION ), + TOKEN( "chapter", XML_CHAPTER ), + TOKEN( "char", XML_CHAR ), + TOKEN( "char-shading-value", XML_CHAR_SHADING_VALUE ), + TOKEN( "character-count", XML_CHARACTER_COUNT ), + TOKEN( "chart", XML_CHART ), + TOKEN( "charts", XML_CHARTS ), + TOKEN( "checkerboard", XML_CHECKERBOARD ), + TOKEN( "chg-author", XML_CHG_AUTHOR ), + TOKEN( "chg-comment", XML_CHG_COMMENT ), + TOKEN( "chg-date-time", XML_CHG_DATE_TIME ), + TOKEN( "ci", XML_CI ), + TOKEN( "circle", XML_CIRCLE ), + TOKEN( "citation-body-style-name", XML_CITATION_BODY_STYLE_NAME ), + TOKEN( "citation-style-name", XML_CITATION_STYLE_NAME ), + TOKEN( "class", XML_CLASS ), + TOKEN( "class-id", XML_CLASS_ID ), + TOKEN( "clip", XML_CLIP ), + TOKEN( "clockwise", XML_CLOCKWISE ), + TOKEN( "close", XML_CLOSE ), + TOKEN( "close-horizontal", XML_CLOSE_HORIZONTAL ), + TOKEN( "close-vertical", XML_CLOSE_VERTICAL ), + TOKEN( "cn", XML_CN ), + TOKEN( "code", XML_CODE ), + TOKEN( "codebase", XML_CODEBASE ), + TOKEN( "collapse", XML_COLLAPSE ), + TOKEN( "color", XML_COLOR ), + TOKEN( "color-inversion", XML_COLOR_INVERSION ), + TOKEN( "color-mode", XML_COLOR_MODE ), + TOKEN( "color-scale", XML_COLOR_SCALE ), + TOKEN( "color-scale-entry", XML_COLOR_SCALE_ENTRY ), + TOKEN( "color-table", XML_COLOR_TABLE ), + TOKEN( "column", XML_COLUMN ), + TOKEN( "column-count", XML_COLUMN_COUNT ), + TOKEN( "column-gap", XML_COLUMN_GAP ), + TOKEN( "column-name", XML_COLUMN_NAME ), + TOKEN( "column-sep", XML_COLUMN_SEP ), + TOKEN( "column-width", XML_COLUMN_WIDTH ), + TOKEN( "columnalign", XML_COLUMNALIGN ), + TOKEN( "columns", XML_COLUMNS ), + TOKEN( "avoid", XML_COLUMNSPLIT_AVOID ), + TOKEN( "combine-entries", XML_COMBINE_ENTRIES ), + TOKEN( "combine-entries-with-dash", XML_COMBINE_ENTRIES_WITH_DASH ), + TOKEN( "combine-entries-with-pp", XML_COMBINE_ENTRIES_WITH_PP ), + TOKEN( "comma-separated", XML_COMMA_SEPARATED ), + TOKEN( "command", XML_COMMAND ), + TOKEN( "comment", XML_COMMENT ), + TOKEN( "compose", XML_COMPOSE ), + TOKEN( "cond-style-name", XML_COND_STYLE_NAME ), + TOKEN( "condition", XML_CONDITION ), + TOKEN( "condition-source", XML_CONDITION_SOURCE ), + TOKEN( "condition-source-range-address", XML_CONDITION_SOURCE_RANGE_ADDRESS ), + TOKEN( "conditional-text", XML_CONDITIONAL_TEXT ), + TOKEN( "conditional-format", XML_CONDITIONAL_FORMAT ), + TOKEN( "conditional-formats", XML_CONDITIONAL_FORMATS ), + TOKEN( "cone", XML_CONE ), + TOKEN( "conference", XML_CONFERENCE ), + TOKEN( "config-item", XML_CONFIG_ITEM ), + TOKEN( "config-item-map-entry", XML_CONFIG_ITEM_MAP_ENTRY ), + TOKEN( "config-item-map-indexed", XML_CONFIG_ITEM_MAP_INDEXED ), + TOKEN( "config-item-map-named", XML_CONFIG_ITEM_MAP_NAMED ), + TOKEN( "config-item-set", XML_CONFIG_ITEM_SET ), + TOKEN( "configuration-settings", XML_CONFIGURATION_SETTINGS ), + TOKEN( "conjugate", XML_CONJUGATE ), + TOKEN( "connect-bars", XML_CONNECT_BARS ), + TOKEN( "connection-name", XML_CONNECTION_NAME ), + TOKEN( "connector", XML_CONNECTOR ), + TOKEN( "consecutive-numbering", XML_CONSECUTIVE_NUMBERING ), + TOKEN( "consolidation", XML_CONSOLIDATION ), + TOKEN( "constant", XML_CONSTANT ), + TOKEN( "contains-error", XML_CONTAINS_ERROR ), + TOKEN( "contains-header", XML_CONTAINS_HEADER ), + TOKEN( "content", XML_CONTENT ), + TOKEN( "content-validation", XML_CONTENT_VALIDATION ), + TOKEN( "content-validation-name", XML_CONTENT_VALIDATION_NAME ), + TOKEN( "content-validations", XML_CONTENT_VALIDATIONS ), + TOKEN( "contextual-spacing", XML_CONTEXTUAL_SPACING ), + TOKEN( "continue", XML_CONTINUE ), + TOKEN( "continue-numbering", XML_CONTINUE_NUMBERING ), + TOKEN( "contour-path", XML_CONTOUR_PATH ), + TOKEN( "contour-polygon", XML_CONTOUR_POLYGON ), + TOKEN( "contrast", XML_CONTRAST ), + TOKEN( "control", XML_CONTROL ), + TOKEN( "conversion-mode", XML_CONVERSION_MODE ), + TOKEN( "conversion-type", XML_CONVERSION_TYPE ), + TOKEN( "copy-back", XML_COPY_BACK ), + TOKEN( "copy-formulas", XML_COPY_FORMULAS ), + TOKEN( "copy-outline-levels", XML_COPY_OUTLINE_LEVELS ), + TOKEN( "copy-results-only", XML_COPY_RESULTS_ONLY ), + TOKEN( "copy-styles", XML_COPY_STYLES ), + TOKEN( "corner-radius", XML_CORNER_RADIUS ), + TOKEN( "correct", XML_CORRECT ), + TOKEN( "cos", XML_COS ), + TOKEN( "cosh", XML_COSH ), + TOKEN( "cot", XML_COT ), + TOKEN( "coth", XML_COTH ), + TOKEN( "count", XML_COUNT ), + TOKEN( "count-empty-lines", XML_COUNT_EMPTY_LINES ), + TOKEN( "count-in-floating-frames", XML_COUNT_IN_FLOATING_FRAMES ), + TOKEN( "counter-clockwise", XML_COUNTER_CLOCKWISE ), + TOKEN( "counterclockwise", XML_COUNTERCLOCKWISE ), + TOKEN( "countnums", XML_COUNTNUMS ), + TOKEN( "country", XML_COUNTRY ), + TOKEN( "country-asian", XML_COUNTRY_ASIAN ), + TOKEN( "country-complex", XML_COUNTRY_COMPLEX ), + TOKEN( "covered-table-cell", XML_COVERED_TABLE_CELL ), + TOKEN( "create-date", XML_CREATE_DATE ), + TOKEN( "create-date-string", XML_CREATE_DATE_STRING ), + TOKEN( "creation-date", XML_CREATION_DATE ), + TOKEN( "creation-time", XML_CREATION_TIME ), + TOKEN( "creator", XML_CREATOR ), + TOKEN( "csc", XML_CSC ), + TOKEN( "csch", XML_CSCH ), + TOKEN( "cube", XML_CUBE ), + TOKEN( "cuboid", XML_CUBOID ), + TOKEN( "currency", XML_CURRENCY ), + TOKEN( "currency-style", XML_CURRENCY_STYLE ), + TOKEN( "currency-symbol", XML_CURRENCY_SYMBOL ), + TOKEN( "current", XML_CURRENT ), + TOKEN( "current-value", XML_CURRENT_VALUE ), + TOKEN( "cursor-position", XML_CURSOR_POSITION ), + TOKEN( "cursor-position-x", XML_CURSOR_POSITION_X ), + TOKEN( "cursor-position-y", XML_CURSOR_POSITION_Y ), + TOKEN( "curve", XML_CURVE ), + TOKEN( "custom1", XML_CUSTOM1 ), + TOKEN( "custom2", XML_CUSTOM2 ), + TOKEN( "custom3", XML_CUSTOM3 ), + TOKEN( "custom4", XML_CUSTOM4 ), + TOKEN( "custom5", XML_CUSTOM5 ), + TOKEN( "custom-iconset", XML_CUSTOM_ICONSET ), + TOKEN( "custom-iconset-index", XML_CUSTOM_ICONSET_INDEX ), + TOKEN( "custom-iconset-name", XML_CUSTOM_ICONSET_NAME ), + TOKEN( "custom-label-field", XML_CUSTOM_LABEL_FIELD ), + TOKEN( "custom-label-pos-x", XML_CUSTOM_LABEL_POS_X ), + TOKEN( "custom-label-pos-y", XML_CUSTOM_LABEL_POS_Y ), + TOKEN( "cut", XML_CUT ), + TOKEN( "cut-offs", XML_CUT_OFFS ), + TOKEN( "cut_offs", XML_CUT_OFFS2 ), + TOKEN( "cx", XML_CX ), + TOKEN( "cy", XML_CY ), + TOKEN( "cylinder", XML_CYLINDER ), + TOKEN( "d", XML_D ), + TOKEN( "dash", XML_DASH ), + TOKEN( "dash-dot", XML_DASH_DOT ), + TOKEN( "dash-dot-dot", XML_DASH_DOT_DOT ), + TOKEN( "dash-table", XML_DASH_TABLE ), + TOKEN( "dashed", XML_DASHED ), + TOKEN( "data", XML_DATA ), + TOKEN( "data-bar", XML_DATA_BAR ), + TOKEN( "data-bar-entry", XML_DATA_BAR_ENTRY ), + TOKEN( "data-cell-range-address", XML_DATA_CELL_RANGE_ADDRESS ), + TOKEN( "data-label", XML_DATA_LABEL ), + TOKEN( "data-label-number", XML_DATA_LABEL_NUMBER ), + TOKEN( "data-label-symbol", XML_DATA_LABEL_SYMBOL ), + TOKEN( "data-label-text", XML_DATA_LABEL_TEXT ), + TOKEN( "data-pilot-source", XML_DATA_PILOT_SOURCE ), + TOKEN( "data-pilot-field", XML_DATA_PILOT_FIELD ), + TOKEN( "data-pilot-grand-total", XML_DATA_PILOT_GRAND_TOTAL ), + TOKEN( "data-pilot-level", XML_DATA_PILOT_LEVEL ), + TOKEN( "data-pilot-member", XML_DATA_PILOT_MEMBER ), + TOKEN( "data-pilot-members", XML_DATA_PILOT_MEMBERS ), + TOKEN( "data-pilot-subtotal", XML_DATA_PILOT_SUBTOTAL ), + TOKEN( "data-pilot-subtotals", XML_DATA_PILOT_SUBTOTALS ), + TOKEN( "data-pilot-table", XML_DATA_PILOT_TABLE ), + TOKEN( "data-pilot-tables", XML_DATA_PILOT_TABLES ), + TOKEN( "data-point", XML_DATA_POINT ), + TOKEN( "data-stream-source", XML_DATA_STREAM_SOURCE ), + TOKEN( "data-style", XML_DATA_STYLE ), + TOKEN( "data-style-name", XML_DATA_STYLE_NAME ), + TOKEN( "data-type", XML_DATA_TYPE ), + TOKEN( "database-display", XML_DATABASE_DISPLAY ), + TOKEN( "database-name", XML_DATABASE_NAME ), + TOKEN( "database-next", XML_DATABASE_NEXT ), + TOKEN( "database-range", XML_DATABASE_RANGE ), + TOKEN( "database-ranges", XML_DATABASE_RANGES ), + TOKEN( "database-row-number", XML_DATABASE_ROW_NUMBER ), + TOKEN( "database-select", XML_DATABASE_SELECT ), + TOKEN( "database-source-query", XML_DATABASE_SOURCE_QUERY ), + TOKEN( "database-source-sql", XML_DATABASE_SOURCE_SQL ), + TOKEN( "database-source-table", XML_DATABASE_SOURCE_TABLE ), + TOKEN( "database-table-name", XML_DATABASE_TABLE_NAME ), + TOKEN( "date", XML_DATE ), + TOKEN( "date-is", XML_DATE_IS ), + TOKEN( "date-adjust", XML_DATE_ADJUST ), + TOKEN( "date-style", XML_DATE_STYLE ), + TOKEN( "date-time", XML_DATE_TIME ), + TOKEN( "date-time-update", XML_DATE_TIME_UPDATE ), + TOKEN( "date-time-visible", XML_DATE_TIME_VISIBLE ), + TOKEN( "date-value", XML_DATE_VALUE ), + TOKEN( "datetime", XML_DATETIME ), + TOKEN( "day", XML_DAY ), + TOKEN( "day-of-week", XML_DAY_OF_WEEK ), + TOKEN( "dde-application", XML_DDE_APPLICATION ), + TOKEN( "dde-connection", XML_DDE_CONNECTION ), + TOKEN( "dde-connection-decl", XML_DDE_CONNECTION_DECL ), + TOKEN( "dde-connection-decls", XML_DDE_CONNECTION_DECLS ), + TOKEN( "dde-item", XML_DDE_ITEM ), + TOKEN( "dde-link", XML_DDE_LINK ), + TOKEN( "dde-links", XML_DDE_LINKS ), + TOKEN( "dde-source", XML_DDE_SOURCE ), + TOKEN( "dde-topic", XML_DDE_TOPIC ), + TOKEN( "decimal-places", XML_DECIMAL_PLACES ), + TOKEN( "decimal-replacement", XML_DECIMAL_REPLACEMENT ), + TOKEN( "declare", XML_DECLARE ), + TOKEN( "decorate-words-only", XML_DECORATE_WORDS_ONLY ), + TOKEN( "decorative", XML_DECORATIVE ), + TOKEN( "deep", XML_DEEP ), + TOKEN( "default", XML_DEFAULT ), + TOKEN( "default-cell-style-name", XML_DEFAULT_CELL_STYLE_NAME ), + TOKEN( "default-style", XML_DEFAULT_STYLE ), + TOKEN( "default-style-name", XML_DEFAULT_STYLE_NAME ), + TOKEN( "degree", XML_DEGREE ), + TOKEN( "delay", XML_DELAY ), + TOKEN( "delay-for-repeat", XML_DELAY_FOR_REPEAT ), + TOKEN( "delete-columns", XML_DELETE_COLUMNS ), + TOKEN( "delete-rows", XML_DELETE_ROWS ), + TOKEN( "deletion", XML_DELETION ), + TOKEN( "deletions", XML_DELETIONS ), + TOKEN( "denomalign" , XML_DENOMALIGN ), + TOKEN( "denominator-value", XML_DENOMINATOR_VALUE ), + TOKEN( "dependence", XML_DEPENDENCE ), + TOKEN( "dependences", XML_DEPENDENCES ), + TOKEN( "dependencies", XML_DEPENDENCIES ), + TOKEN( "depth", XML_DEPTH ), + TOKEN( "desc", XML_DESC ), + TOKEN( "descending", XML_DESCENDING ), + TOKEN( "description", XML_DESCRIPTION ), + TOKEN( "detective", XML_DETECTIVE ), + TOKEN( "determinant", XML_DETERMINANT ), + TOKEN( "diff", XML_DIFF ), + TOKEN( "diffuse-color", XML_DIFFUSE_COLOR ), + TOKEN( "dim", XML_DIM ), + TOKEN( "direction", XML_DIRECTION ), + TOKEN( "disabled", XML_DISABLED ), + TOKEN( "disc", XML_DISC ), + TOKEN( "display", XML_DISPLAY ), + TOKEN( "display-border", XML_DISPLAY_BORDER ), + TOKEN( "display-details", XML_DISPLAY_DETAILS ), + TOKEN( "display-duplicates", XML_DISPLAY_DUPLICATES ), + TOKEN( "display-empty", XML_DISPLAY_EMPTY ), + TOKEN( "display-filter-buttons", XML_DISPLAY_FILTER_BUTTONS ), + TOKEN( "display-formula", XML_DISPLAY_FORMULA ), + TOKEN( "display-label", XML_DISPLAY_LABEL ), + TOKEN( "display-levels", XML_DISPLAY_LEVELS ), + TOKEN( "display-name", XML_DISPLAY_NAME ), + TOKEN( "display-outline-level", XML_DISPLAY_OUTLINE_LEVEL ), + TOKEN( "dissolve", XML_DISSOLVE ), + TOKEN( "distance", XML_DISTANCE ), + TOKEN( "distance-after-sep", XML_DISTANCE_AFTER_SEP ), + TOKEN( "distance-before-sep", XML_DISTANCE_BEFORE_SEP ), + TOKEN( "distribute", XML_DISTRIBUTE ), + TOKEN( "distribute-letter", XML_DISTRIBUTE_LETTER ), + TOKEN( "distribute-space", XML_DISTRIBUTE_SPACE ), + TOKEN( "divide", XML_DIVIDE ), + TOKEN( "document", XML_DOCUMENT ), + TOKEN( "document-content", XML_DOCUMENT_CONTENT ), + TOKEN( "document-meta", XML_DOCUMENT_META ), + TOKEN( "document-settings", XML_DOCUMENT_SETTINGS ), + TOKEN( "document-statistic", XML_DOCUMENT_STATISTIC ), + TOKEN( "document-styles", XML_DOCUMENT_STYLES ), + TOKEN( "domain", XML_DOMAIN ), + TOKEN( "dot", XML_DOT ), + TOKEN( "dots1", XML_DOTS1 ), + TOKEN( "dots1-length", XML_DOTS1_LENGTH ), + TOKEN( "dots2", XML_DOTS2 ), + TOKEN( "dots2-length", XML_DOTS2_LENGTH ), + TOKEN( "dotted", XML_DOTTED ), + TOKEN( "double", XML_DOUBLE ), + TOKEN( "double-sided", XML_DOUBLE_SIDED ), + TOKEN( "double-thin", XML_DOUBLE_THIN ), + TOKEN( "down", XML_DOWN ), + TOKEN( "draft", XML_DRAFT ), + TOKEN( "draw", XML_DRAW ), + TOKEN( "ole-draw-aspect", XML_DRAW_ASPECT ), + TOKEN( "drawing", XML_DRAWING ), + TOKEN( "drawings", XML_DRAWINGS ), + TOKEN( "drawpool", XML_DRAWPOOL ), + TOKEN( "dropdown", XML_DROPDOWN ), + TOKEN( "drop-cap", XML_DROP_CAP ), + TOKEN( "dynamic", XML_DYNAMIC ), + TOKEN( "edge-rounding", XML_EDGE_ROUNDING ), + TOKEN( "editable", XML_EDITABLE ), + TOKEN( "editing-cycles", XML_EDITING_CYCLES ), + TOKEN( "editing-duration", XML_EDITING_DURATION ), + TOKEN( "edition", XML_EDITION ), + TOKEN( "editor", XML_EDITOR ), + TOKEN( "effect", XML_EFFECT ), + TOKEN( "ellipse", XML_ELLIPSE ), + TOKEN( "email", XML_EMAIL ), + TOKEN( "embed", XML_EMBED ), + TOKEN( "embedded-visible-area", XML_EMBEDDED_VISIBLE_AREA ), + TOKEN( "embossed", XML_EMBOSSED ), + TOKEN( "emissive-color", XML_EMISSIVE_COLOR ), + TOKEN( "empty", XML_EMPTY ), + TOKEN( "empty-line-refresh", XML_EMPTY_LINE_REFRESH ), + TOKEN( "enable-numbering", XML_ENABLE_NUMBERING ), + TOKEN( "enabled", XML_ENABLED ), + TOKEN( "encoding", XML_ENCODING ), + TOKEN( "end", XML_END ), + TOKEN( "end-angle", XML_END_ANGLE ), + TOKEN( "end-cell-address", XML_END_CELL_ADDRESS ), + TOKEN( "end-color", XML_END_COLOR ), + TOKEN( "end-column", XML_END_COLUMN ), + TOKEN( "end-glue-point", XML_END_GLUE_POINT ), + TOKEN( "end-guide", XML_END_GUIDE ), + TOKEN( "end-intensity", XML_END_INTENSITY ), + TOKEN( "end-line-spacing-horizontal", XML_END_LINE_SPACING_HORIZONTAL ), + TOKEN( "end-line-spacing-vertical", XML_END_LINE_SPACING_VERTICAL ), + TOKEN( "end-position", XML_END_POSITION ), + TOKEN( "end-row", XML_END_ROW ), + TOKEN( "end-shape", XML_END_SHAPE ), + TOKEN( "end-table", XML_END_TABLE ), + TOKEN( "end-x", XML_END_X ), + TOKEN( "end-y", XML_END_Y ), + TOKEN( "endless", XML_ENDLESS ), + TOKEN( "endnote", XML_ENDNOTE ), + TOKEN( "endnote-body", XML_ENDNOTE_BODY ), + TOKEN( "endnote-citation", XML_ENDNOTE_CITATION ), + TOKEN( "endnote-ref", XML_ENDNOTE_REF ), + TOKEN( "endnotes-configuration", XML_ENDNOTES_CONFIGURATION ), + TOKEN( "engraved", XML_ENGRAVED ), + TOKEN( "entry", XML_ENTRY ), + TOKEN( "eq", XML_EQ ), + TOKEN( "equal-author", XML_EQUAL_AUTHOR ), + TOKEN( "equal-comment", XML_EQUAL_COMMENT ), + TOKEN( "equal-date", XML_EQUAL_DATE ), + TOKEN( "era", XML_ERA ), + TOKEN( "ergo-sum", XML_ERGO_SUM ), + TOKEN( "error-category", XML_ERROR_CATEGORY ), + TOKEN( "error-lower-indicator", XML_ERROR_LOWER_INDICATOR ), + TOKEN( "error-lower-limit", XML_ERROR_LOWER_LIMIT ), + TOKEN( "error-macro", XML_ERROR_MACRO ), + TOKEN( "error-margin", XML_ERROR_MARGIN ), + TOKEN( "error-message", XML_ERROR_MESSAGE ), + TOKEN( "error-percentage", XML_ERROR_PERCENTAGE ), + TOKEN( "error-upper-indicator", XML_ERROR_UPPER_INDICATOR ), + TOKEN( "error-upper-limit", XML_ERROR_UPPER_LIMIT ), + TOKEN( "sub", XML_ESCAPEMENT_SUB ), + TOKEN( "super", XML_ESCAPEMENT_SUPER ), + TOKEN( "even-page", XML_EVEN_PAGE ), + TOKEN( "event", XML_EVENT ), + TOKEN( "event-name", XML_EVENT_NAME ), + TOKEN( "events", XML_EVENTS ), + TOKEN( "execute", XML_EXECUTE ), + TOKEN( "execute-macro", XML_EXECUTE_MACRO ), + TOKEN( "exists", XML_EXISTS ), + TOKEN( "exp", XML_EXP ), + TOKEN( "exponential", XML_EXPONENTIAL ), + TOKEN( "expression", XML_EXPRESSION ), + TOKEN( "extra", XML_EXTRA ), + TOKEN( "extrude", XML_EXTRUDE ), + TOKEN( "factorial", XML_FACTORIAL ), + TOKEN( "fade", XML_FADE ), + TOKEN( "fade-from-bottom", XML_FADE_FROM_BOTTOM ), + TOKEN( "fade-from-center", XML_FADE_FROM_CENTER ), + TOKEN( "fade-from-left", XML_FADE_FROM_LEFT ), + TOKEN( "fade-from-lowerleft", XML_FADE_FROM_LOWERLEFT ), + TOKEN( "fade-from-lowerright", XML_FADE_FROM_LOWERRIGHT ), + TOKEN( "fade-from-right", XML_FADE_FROM_RIGHT ), + TOKEN( "fade-from-top", XML_FADE_FROM_TOP ), + TOKEN( "fade-from-upperleft", XML_FADE_FROM_UPPERLEFT ), + TOKEN( "fade-from-upperright", XML_FADE_FROM_UPPERRIGHT ), + TOKEN( "fade-out", XML_FADE_OUT ), + TOKEN( "fade-to-center", XML_FADE_TO_CENTER ), + TOKEN( "false", XML_FALSE ), + TOKEN( "family", XML_FAMILY ), + TOKEN( "fast", XML_FAST ), + TOKEN( "fence", XML_FENCE ), + TOKEN( "field-number", XML_FIELD_NUMBER ), + TOKEN( "file-name", XML_FILE_NAME ), + TOKEN( "fill", XML_FILL ), + TOKEN( "fill-character", XML_FILL_CHARACTER ), + TOKEN( "fill-color", XML_FILL_COLOR ), + TOKEN( "fill-gradient-name", XML_FILL_GRADIENT_NAME ), + TOKEN( "fill-hatch-name", XML_FILL_HATCH_NAME ), + TOKEN( "fill-hatch-solid", XML_FILL_HATCH_SOLID ), + TOKEN( "fill-image", XML_FILL_IMAGE ), + TOKEN( "fill-image-height", XML_FILL_IMAGE_HEIGHT ), + TOKEN( "fill-image-name", XML_FILL_IMAGE_NAME ), + TOKEN( "fill-image-ref-point", XML_FILL_IMAGE_REF_POINT ), + TOKEN( "fill-image-ref-point-x", XML_FILL_IMAGE_REF_POINT_X ), + TOKEN( "fill-image-ref-point-y", XML_FILL_IMAGE_REF_POINT_Y ), + TOKEN( "fill-image-width", XML_FILL_IMAGE_WIDTH ), + TOKEN( "fill-rule", XML_FILL_RULE ), + TOKEN( "filter", XML_FILTER ), + TOKEN( "filter-and", XML_FILTER_AND ), + TOKEN( "filter-condition", XML_FILTER_CONDITION ), + TOKEN( "filter-name", XML_FILTER_NAME ), + TOKEN( "filter-options", XML_FILTER_OPTIONS ), + TOKEN( "filter-or", XML_FILTER_OR ), + TOKEN( "filter-set-item", XML_FILTER_SET_ITEM ), + TOKEN( "fine-dashed", XML_FINE_DASHED ), + TOKEN( "first-date-time", XML_FIRST_DATE_TIME ), + TOKEN( "first-page", XML_FIRST_PAGE ), + TOKEN( "first-page-number", XML_FIRST_PAGE_NUMBER ), + TOKEN( "fit-to-contour", XML_FIT_TO_CONTOUR ), + TOKEN( "fit-to-size", XML_FIT_TO_SIZE ), + TOKEN( "fix", XML_FIX ), + TOKEN( "fixed", XML_FIXED ), + TOKEN( "flat", XML_FLAT ), + TOKEN( "float", XML_FLOAT ), + TOKEN( "floating-frame", XML_FLOATING_FRAME ), + TOKEN( "floor", XML_FLOOR ), + TOKEN( "fn", XML_FN ), + TOKEN( "focal-length", XML_FOCAL_LENGTH ), + TOKEN( "font-char-width", XML_FONT_CHAR_WIDTH ), + TOKEN( "font-charset", XML_FONT_CHARSET ), + TOKEN( "font-charset-asian", XML_FONT_CHARSET_ASIAN ), + TOKEN( "font-charset-complex", XML_FONT_CHARSET_COMPLEX ), + TOKEN( "font-color", XML_FONT_COLOR ), + TOKEN( "font-decl", XML_FONT_DECL ), + TOKEN( "font-decls", XML_FONT_DECLS ), + TOKEN( "font-family", XML_FONT_FAMILY ), + TOKEN( "font-family-asian", XML_FONT_FAMILY_ASIAN ), + TOKEN( "font-family-complex", XML_FONT_FAMILY_COMPLEX ), + TOKEN( "font-family-generic", XML_FONT_FAMILY_GENERIC ), + TOKEN( "font-family-generic-asian", XML_FONT_FAMILY_GENERIC_ASIAN ), + TOKEN( "font-family-generic-complex", XML_FONT_FAMILY_GENERIC_COMPLEX ), + TOKEN( "font-kerning", XML_FONT_KERNING ), + TOKEN( "font-name", XML_FONT_NAME ), + TOKEN( "font-name-asian", XML_FONT_NAME_ASIAN ), + TOKEN( "font-name-complex", XML_FONT_NAME_COMPLEX ), + TOKEN( "font-pitch", XML_FONT_PITCH ), + TOKEN( "font-pitch-asian", XML_FONT_PITCH_ASIAN ), + TOKEN( "font-pitch-complex", XML_FONT_PITCH_COMPLEX ), + TOKEN( "font-relief", XML_FONT_RELIEF ), + TOKEN( "font-size", XML_FONT_SIZE ), + TOKEN( "font-size-asian", XML_FONT_SIZE_ASIAN ), + TOKEN( "font-size-complex", XML_FONT_SIZE_COMPLEX ), + TOKEN( "font-size-rel", XML_FONT_SIZE_REL ), + TOKEN( "font-size-rel-asian", XML_FONT_SIZE_REL_ASIAN ), + TOKEN( "font-size-rel-complex", XML_FONT_SIZE_REL_COMPLEX ), + TOKEN( "font-style", XML_FONT_STYLE ), + TOKEN( "font-style-asian", XML_FONT_STYLE_ASIAN ), + TOKEN( "font-style-complex", XML_FONT_STYLE_COMPLEX ), + TOKEN( "font-style-name", XML_FONT_STYLE_NAME ), + TOKEN( "font-style-name-asian", XML_FONT_STYLE_NAME_ASIAN ), + TOKEN( "font-style-name-complex", XML_FONT_STYLE_NAME_COMPLEX ), + TOKEN( "font-variant", XML_FONT_VARIANT ), + TOKEN( "font-weight", XML_FONT_WEIGHT ), + TOKEN( "font-weight-asian", XML_FONT_WEIGHT_ASIAN ), + TOKEN( "font-weight-complex", XML_FONT_WEIGHT_COMPLEX ), + TOKEN( "font-width", XML_FONT_WIDTH ), + TOKEN( "font-word-line-mode", XML_FONT_WORD_LINE_MODE ), + TOKEN( "fontfamily", XML_FONTFAMILY ), + TOKEN( "fontsize", XML_FONTSIZE ), + TOKEN( "fontstyle", XML_FONTSTYLE ), + TOKEN( "fontweight", XML_FONTWEIGHT ), + TOKEN( "fontwork-adjust", XML_FONTWORK_ADJUST ), + TOKEN( "fontwork-distance", XML_FONTWORK_DISTANCE ), + TOKEN( "fontwork-form", XML_FONTWORK_FORM ), + TOKEN( "fontwork-hide-form", XML_FONTWORK_HIDE_FORM ), + TOKEN( "fontwork-mirror", XML_FONTWORK_MIRROR ), + TOKEN( "fontwork-outline", XML_FONTWORK_OUTLINE ), + TOKEN( "fontwork-shadow", XML_FONTWORK_SHADOW ), + TOKEN( "fontwork-shadow-color", XML_FONTWORK_SHADOW_COLOR ), + TOKEN( "fontwork-shadow-offset-x", XML_FONTWORK_SHADOW_OFFSET_X ), + TOKEN( "fontwork-shadow-offset-y", XML_FONTWORK_SHADOW_OFFSET_Y ), + TOKEN( "fontwork-shadow-transparence", XML_FONTWORK_SHADOW_TRANSPARENCE ), + TOKEN( "fontwork-start", XML_FONTWORK_START ), + TOKEN( "fontwork-style", XML_FONTWORK_STYLE ), + TOKEN( "footer", XML_FOOTER ), + TOKEN( "footer-first", XML_FOOTER_FIRST ), + TOKEN( "footer-left", XML_FOOTER_LEFT ), + TOKEN( "footer-style", XML_FOOTER_STYLE ), + TOKEN( "footer-visible", XML_FOOTER_VISIBLE ), + TOKEN( "footnote", XML_FOOTNOTE ), + TOKEN( "footnote-body", XML_FOOTNOTE_BODY ), + TOKEN( "footnote-citation", XML_FOOTNOTE_CITATION ), + TOKEN( "footnote-continuation-notice-backward", XML_FOOTNOTE_CONTINUATION_NOTICE_BACKWARD ), + TOKEN( "footnote-continuation-notice-forward", XML_FOOTNOTE_CONTINUATION_NOTICE_FORWARD ), + TOKEN( "footnote-max-height", XML_FOOTNOTE_MAX_HEIGHT ), + TOKEN( "footnote-ref", XML_FOOTNOTE_REF ), + TOKEN( "footnote-sep", XML_FOOTNOTE_SEP ), + TOKEN( "footnotes-configuration", XML_FOOTNOTES_CONFIGURATION ), + TOKEN( "footnotes-position", XML_FOOTNOTES_POSITION ), + TOKEN( "forall", XML_FORALL ), + TOKEN( "force-manual", XML_FORCE_MANUAL ), + TOKEN( "foreground", XML_FOREGROUND ), + TOKEN( "foreign-object", XML_FOREIGN_OBJECT ), + TOKEN( "format-change", XML_FORMAT_CHANGE ), + TOKEN( "format-source", XML_FORMAT_SOURCE ), + TOKEN( "formatting-entry", XML_FORMATTING_ENTRY ), + TOKEN( "forms", XML_FORMS ), + TOKEN( "formula", XML_FORMULA ), + TOKEN( "formula-hidden", XML_FORMULA_HIDDEN ), + TOKEN( "formulas", XML_FORMULAS ), + TOKEN( "fraction", XML_FRACTION ), + TOKEN( "frame", XML_FRAME ), + TOKEN( "frame-content", XML_FRAME_CONTENT ), + TOKEN( "frame-display-border", XML_FRAME_DISPLAY_BORDER ), + TOKEN( "frame-display-scrollbar", XML_FRAME_DISPLAY_SCROLLBAR ), + TOKEN( "frame-end-margin", XML_FRAME_END_MARGIN ), + TOKEN( "frame-margin-horizontal", XML_FRAME_MARGIN_HORIZONTAL ), + TOKEN( "frame-margin-vertical", XML_FRAME_MARGIN_VERTICAL ), + TOKEN( "frame-name", XML_FRAME_NAME ), + TOKEN( "frame-start-margin", XML_FRAME_START_MARGIN ), + TOKEN( "freeze", XML_FREEZE ), + TOKEN( "freeze-position", XML_FREEZE_POSITION ), + TOKEN( "from-another-table", XML_FROM_ANOTHER_TABLE ), + TOKEN( "from-bottom", XML_FROM_BOTTOM ), + TOKEN( "from-center", XML_FROM_CENTER ), + TOKEN( "from-inside", XML_FROM_INSIDE ), + TOKEN( "from-left", XML_FROM_LEFT ), + TOKEN( "from-lower-left", XML_FROM_LOWER_LEFT ), + TOKEN( "from-lower-right", XML_FROM_LOWER_RIGHT ), + TOKEN( "from-right", XML_FROM_RIGHT ), + TOKEN( "from-same-table", XML_FROM_SAME_TABLE ), + TOKEN( "from-top", XML_FROM_TOP ), + TOKEN( "from-upper-left", XML_FROM_UPPER_LEFT ), + TOKEN( "from-upper-right", XML_FROM_UPPER_RIGHT ), + TOKEN( "fuchsia", XML_FUCHSIA ), + TOKEN( "full", XML_FULL ), + TOKEN( "full-screen", XML_FULL_SCREEN ), + TOKEN( "function", XML_FUNCTION ), + TOKEN( "fx", XML_FX ), + TOKEN( "fy", XML_FY ), + TOKEN( "g", XML_G ), + TOKEN( "gamma", XML_GAMMA ), + TOKEN( "gap", XML_GAP ), + TOKEN( "gap-width", XML_GAP_WIDTH ), + TOKEN( "gcd", XML_GCD ), + TOKEN( "generator", XML_GENERATOR ), + TOKEN( "geq", XML_GEQ ), + TOKEN( "glow-radius", XML_GLOW_RADIUS ), + TOKEN( "glow-color", XML_GLOW_COLOR ), + TOKEN( "glow-transparency", XML_GLOW_TRANSPARENCY ), + TOKEN( "gouraud", XML_GOURAUD ), + TOKEN( "gradient", XML_GRADIENT ), + TOKEN( "angle", XML_GRADIENT_ANGLE ), + TOKEN( "gradient-step-count", XML_GRADIENT_STEP_COUNT ), + TOKEN( "gradient-style", XML_GRADIENT_STYLE ), + TOKEN( "gradient-table", XML_GRADIENT_TABLE ), + TOKEN( "axial", XML_GRADIENTSTYLE_AXIAL ), + TOKEN( "ellipsoid", XML_GRADIENTSTYLE_ELLIPSOID ), + TOKEN( "radial", XML_GRADIENTSTYLE_RADIAL ), + TOKEN( "rectangular", XML_GRADIENTSTYLE_RECTANGULAR ), + TOKEN( "square", XML_GRADIENTSTYLE_SQUARE ), + TOKEN( "gradientTransform", XML_GRADIENTTRANSFORM ), + TOKEN( "grand-total", XML_GRAND_TOTAL ), + TOKEN( "graphic", XML_GRAPHIC ), + TOKEN( "gray", XML_GRAY ), + TOKEN( "green", XML_GREEN ), + TOKEN( "greyscale", XML_GREYSCALE ), + TOKEN( "grid", XML_GRID ), + TOKEN( "groove", XML_GROOVE ), + TOKEN( "group-by-field-number", XML_GROUP_BY_FIELD_NUMBER ), + TOKEN( "group-name", XML_GROUP_NAME ), + TOKEN( "grouping", XML_GROUPING ), + TOKEN( "gt", XML_GT ), + TOKEN( "guide-distance", XML_GUIDE_DISTANCE ), + TOKEN( "guide-overhang", XML_GUIDE_OVERHANG ), + TOKEN( "h", XML_H ), + TOKEN( "hanging", XML_HANGING ), + TOKEN( "has-persistent-data", XML_HAS_PERSISTENT_DATA ), + TOKEN( "hatch", XML_HATCH ), + TOKEN( "hatch-table", XML_HATCH_TABLE ), + TOKEN( "triple", XML_HATCHSTYLE_TRIPLE ), + TOKEN( "header", XML_HEADER ), + TOKEN( "header-first", XML_HEADER_FIRST ), + TOKEN( "header-left", XML_HEADER_LEFT ), + TOKEN( "header-style", XML_HEADER_STYLE ), + TOKEN( "headers", XML_HEADERS ), + TOKEN( "height", XML_HEIGHT ), + TOKEN( "help", XML_HELP), + TOKEN( "help-file-name", XML_HELP_FILE_NAME ), + TOKEN( "help-id", XML_HELP_ID ), + TOKEN( "help-message", XML_HELP_MESSAGE ), + TOKEN( "hidden", XML_HIDDEN ), + TOKEN( "hidden-and-protected", XML_HIDDEN_AND_PROTECTED ), + TOKEN( "hidden-paragraph", XML_HIDDEN_PARAGRAPH ), + TOKEN( "hidden-text", XML_HIDDEN_TEXT ), + TOKEN( "hide", XML_HIDE ), + TOKEN( "hide-legend", XML_HIDE_LEGEND ), + TOKEN( "hide-shape", XML_HIDE_SHAPE ), + TOKEN( "hide-text", XML_HIDE_TEXT ), + TOKEN( "highlighted-range", XML_HIGHLIGHTED_RANGE ), + TOKEN( "hint", XML_HINT), + TOKEN( "horizontal", XML_HORIZONTAL ), + TOKEN( "horizontalstrike", XML_HORIZONTALSTRIKE ), + TOKEN( "horizontal-lines", XML_HORIZONTAL_LINES ), + /* XML_HORIZONTAL_ON_LEFT_PAGES and XML_HORIZONTAL_ON_RIGHT_PAGES + are replaced by XML_HORIZONTAL_ON_EVEN and XML_HORIZONTAL_ON_ODD. + Usage is deprecated, but the old token are needed for the + OpenOffice.org file format import/export filter for the renaming (#i49139#) + */ + TOKEN( "horizontal-on-left-pages", XML_HORIZONTAL_ON_LEFT_PAGES ), + TOKEN( "horizontal-on-right-pages", XML_HORIZONTAL_ON_RIGHT_PAGES ), + TOKEN( "horizontal-pos", XML_HORIZONTAL_POS ), + TOKEN( "horizontal-rel", XML_HORIZONTAL_REL ), + TOKEN( "horizontal-scrollbar-width", XML_HORIZONTAL_SCROLLBAR_WIDTH ), + TOKEN( "horizontal-segments", XML_HORIZONTAL_SEGMENTS ), + TOKEN( "horizontal-split-mode", XML_HORIZONTAL_SPLIT_MODE ), + TOKEN( "horizontal-split-position", XML_HORIZONTAL_SPLIT_POSITION ), + TOKEN( "horizontal-stripes", XML_HORIZONTAL_STRIPES ), + TOKEN( "hours", XML_HOURS ), + TOKEN( "howpublished", XML_HOWPUBLISHED ), + TOKEN( "href", XML_HREF ), + TOKEN( "html", XML_HTML ), + TOKEN( "hyperlink", XML_HYPERLINK ), + TOKEN( "hyperlink-behaviour", XML_HYPERLINK_BEHAVIOUR ), + TOKEN( "hyphenate", XML_HYPHENATE ), + TOKEN( "hyphenation-keep", XML_HYPHENATION_KEEP ), + TOKEN( "hyphenation-ladder-count", XML_HYPHENATION_LADDER_COUNT ), + TOKEN( "hyphenation-push-char-count", XML_HYPHENATION_PUSH_CHAR_COUNT ), + TOKEN( "hyphenation-remain-char-count", XML_HYPHENATION_REMAIN_CHAR_COUNT ), + TOKEN( "hyphenation-no-caps", XML_HYPHENATION_NO_CAPS ), + TOKEN( "i", XML_I ), + TOKEN( "icon", XML_ICON ), + TOKEN( "icon-set", XML_ICON_SET ), + TOKEN( "icon-set-type", XML_ICON_SET_TYPE ), + TOKEN( "id", XML_ID ), + TOKEN( "ident", XML_IDENT ), + TOKEN( "identifier", XML_IDENTIFIER ), + TOKEN( "identify-categories", XML_IDENTIFY_CATEGORIES ), + TOKEN( "ideograph-alpha", XML_IDEOGRAPH_ALPHA ), + TOKEN( "ignore-case", XML_IGNORE_CASE ), + TOKEN( "ignore-empty-rows", XML_IGNORE_EMPTY_ROWS ), + TOKEN( "ignore-selected-page", XML_IGNORE_SELECTED_PAGE ), + TOKEN( "illustration-index", XML_ILLUSTRATION_INDEX ), + TOKEN( "illustration-index-entry-template", XML_ILLUSTRATION_INDEX_ENTRY_TEMPLATE ), + TOKEN( "illustration-index-source", XML_ILLUSTRATION_INDEX_SOURCE ), + TOKEN( "image", XML_IMAGE ), + TOKEN( "image-count", XML_IMAGE_COUNT ), + TOKEN( "image-map", XML_IMAGE_MAP ), + TOKEN( "implies", XML_IMPLIES ), + TOKEN( "in", XML_IN ), + TOKEN( "in-range", XML_IN_RANGE ), + TOKEN( "inbook", XML_INBOOK ), + TOKEN( "incollection", XML_INCOLLECTION ), + TOKEN( "increment", XML_INCREMENT ), + TOKEN( "index", XML_INDEX ), + TOKEN( "index-body", XML_INDEX_BODY ), + TOKEN( "index-entry-bibliography", XML_INDEX_ENTRY_BIBLIOGRAPHY ), + TOKEN( "index-entry-chapter", XML_INDEX_ENTRY_CHAPTER ), + TOKEN( "index-entry-chapter-number", XML_INDEX_ENTRY_CHAPTER_NUMBER ), + TOKEN( "index-entry-link-end", XML_INDEX_ENTRY_LINK_END ), + TOKEN( "index-entry-link-start", XML_INDEX_ENTRY_LINK_START ), + TOKEN( "index-entry-page-number", XML_INDEX_ENTRY_PAGE_NUMBER ), + TOKEN( "index-entry-span", XML_INDEX_ENTRY_SPAN ), + TOKEN( "index-entry-tab-stop", XML_INDEX_ENTRY_TAB_STOP ), + TOKEN( "index-entry-template", XML_INDEX_ENTRY_TEMPLATE ), + TOKEN( "index-entry-text", XML_INDEX_ENTRY_TEXT ), + TOKEN( "index-name", XML_INDEX_NAME ), + TOKEN( "index-scope", XML_INDEX_SCOPE ), + TOKEN( "index-source-style", XML_INDEX_SOURCE_STYLE ), + TOKEN( "index-source-styles", XML_INDEX_SOURCE_STYLES ), + TOKEN( "index-title", XML_INDEX_TITLE ), + TOKEN( "index-title-template", XML_INDEX_TITLE_TEMPLATE ), + TOKEN( "information", XML_INFORMATION ), + TOKEN( "initial-creator", XML_INITIAL_CREATOR ), + TOKEN( "inproceedings", XML_INPROCEEDINGS ), + TOKEN( "insert-columns", XML_INSERT_COLUMNS ), + TOKEN( "insert-rows", XML_INSERT_ROWS ), + TOKEN( "insertion", XML_INSERTION ), + TOKEN( "insertion-cut-off", XML_INSERTION_CUT_OFF ), + TOKEN( "insertion-position", XML_INSERTION_POSITION ), + TOKEN( "inset", XML_INSET ), + TOKEN( "inside", XML_INSIDE ), + TOKEN( "institution", XML_INSTITUTION ), + TOKEN( "int", XML_INT ), + TOKEN( "intensity", XML_INTENSITY ), + TOKEN( "inter-character", XML_INTER_CHARACTER ), + TOKEN( "intersect", XML_INTERSECT ), + TOKEN( "interval", XML_INTERVAL ), + TOKEN( "interval-major", XML_INTERVAL_MAJOR ), + TOKEN( "interval-minor", XML_INTERVAL_MINOR ), + TOKEN( "into-english-number", XML_INTO_ENGLISH_NUMBER ), + TOKEN( "inverse", XML_INVERSE ), + TOKEN( "is-active", XML_IS_ACTIVE ), + TOKEN( "is-data-layout-field", XML_IS_DATA_LAYOUT_FIELD ), + TOKEN( "is-hidden", XML_IS_HIDDEN ), + TOKEN( "is-selection", XML_IS_SELECTION ), + TOKEN( "isbn", XML_ISBN ), + TOKEN( "italic", XML_ITALIC ), + TOKEN( "iteration", XML_ITERATION ), + TOKEN( "journal", XML_JOURNAL ), + TOKEN( "justified", XML_JUSTIFIED ), + TOKEN( "justify", XML_JUSTIFY ), + TOKEN( "justify-single-word", XML_JUSTIFY_SINGLE_WORD ), + TOKEN( "keep-with-next", XML_KEEP_WITH_NEXT ), + TOKEN( "key", XML_KEY ), + TOKEN( "key1", XML_KEY1 ), + TOKEN( "key2", XML_KEY2 ), + TOKEN( "keyword", XML_KEYWORD ), + TOKEN( "keywords", XML_KEYWORDS ), + TOKEN( "kind", XML_KIND ), + TOKEN( "km", XML_KM ), + TOKEN( "label", XML_LABEL ), + TOKEN( "label-arrangement", XML_LABEL_ARRANGEMENT ), + TOKEN( "label-cell-address", XML_LABEL_CELL_ADDRESS ), + TOKEN( "label-cell-range-address", XML_LABEL_CELL_RANGE_ADDRESS ), + TOKEN( "label-fill", XML_LABEL_FILL ), + TOKEN( "label-fill-color", XML_LABEL_FILL_COLOR ), + TOKEN( "label-range", XML_LABEL_RANGE ), + TOKEN( "label-ranges", XML_LABEL_RANGES ), + TOKEN( "label-string", XML_LABEL_STRING ), + TOKEN( "label-stroke", XML_LABEL_STROKE ), + TOKEN( "label-stroke-color", XML_LABEL_STROKE_COLOR ), + TOKEN( "label-stroke-opacity", XML_LABEL_STROKE_OPACITY ), + TOKEN( "label-stroke-width", XML_LABEL_STROKE_WIDTH ), + TOKEN( "lambda", XML_LAMBDA ), + TOKEN( "landscape", XML_LANDSCAPE ), + TOKEN( "lang", XML_LANG ), + TOKEN( "language", XML_LANGUAGE ), + TOKEN( "language-asian", XML_LANGUAGE_ASIAN ), + TOKEN( "language-complex", XML_LANGUAGE_COMPLEX ), + TOKEN( "laser", XML_LASER ), + TOKEN( "last-column-spanned", XML_LAST_COLUMN_SPANNED ), + TOKEN( "last-page", XML_LAST_PAGE ), + TOKEN( "last-row-spanned", XML_LAST_ROW_SPANNED ), + TOKEN( "layer", XML_LAYER ), + TOKEN( "layer-set", XML_LAYER_SET ), + TOKEN( "leader-char", XML_LEADER_CHAR ), + TOKEN( "left", XML_LEFT ), + TOKEN( "left-outside", XML_LEFT_OUTSIDE ), + TOKEN( "left-text", XML_LEFT_TEXT ), + TOKEN( "left-top-position", XML_LEFT_TOP_POSITION ), + TOKEN( "left-arc", XML_LEFTARC ), + TOKEN( "left-circle", XML_LEFTCIRCLE ), + TOKEN( "legend", XML_LEGEND ), + TOKEN( "legend-position", XML_LEGEND_POSITION ), + TOKEN( "length", XML_LENGTH ), + TOKEN( "leq", XML_LEQ ), + TOKEN( "let-text", XML_LET_TEXT ), + TOKEN( "keep-text", XML_KEEP_TEXT ), + TOKEN( "letter-kerning", XML_LETTER_KERNING ), + TOKEN( "letter-spacing", XML_LETTER_SPACING ), + TOKEN( "letters", XML_LETTERS ), + TOKEN( "level", XML_LEVEL ), + TOKEN( "library", XML_LIBRARY ), + TOKEN( "library-embedded", XML_LIBRARY_EMBEDDED ), + TOKEN( "library-linked", XML_LIBRARY_LINKED ), + TOKEN( "light", XML_LIGHT ), + TOKEN( "lighting-mode", XML_LIGHTING_MODE ), + TOKEN( "lime", XML_LIME ), + TOKEN( "limit", XML_LIMIT ), + TOKEN( "line", XML_LINE ), + TOKEN( "line-break", XML_LINE_BREAK ), + TOKEN( "line-distance", XML_LINE_DISTANCE ), + TOKEN( "line-height", XML_LINE_HEIGHT ), + TOKEN( "line-height-at-least", XML_LINE_HEIGHT_AT_LEAST ), + TOKEN( "line-number", XML_LINE_NUMBER ), + TOKEN( "line-skew", XML_LINE_SKEW ), + TOKEN( "line-spacing", XML_LINE_SPACING ), + TOKEN( "line-style", XML_LINE_STYLE ), + TOKEN( "linear", XML_LINEAR ), + TOKEN( "linearGradient", XML_LINEARGRADIENT ), + TOKEN( "linenumbering-configuration", XML_LINENUMBERING_CONFIGURATION ), + TOKEN( "linenumbering-separator", XML_LINENUMBERING_SEPARATOR ), + TOKEN( "lines", XML_LINES ), + TOKEN( "lines-used", XML_LINES_USED ), + TOKEN( "linked-cell", XML_LINKED_CELL ), + TOKEN( "link-to-source-data", XML_LINK_TO_SOURCE_DATA ), + TOKEN( "list", XML_LIST ), + TOKEN( "list-block", XML_LIST_BLOCK ), + TOKEN( "list-header", XML_LIST_HEADER ), + TOKEN( "list-info", XML_LIST_INFO ), + TOKEN( "list-item", XML_LIST_ITEM ), + TOKEN( "list-level", XML_LIST_LEVEL ), + TOKEN( "list-level-style-bullet", XML_LIST_LEVEL_STYLE_BULLET ), + TOKEN( "list-level-style-image", XML_LIST_LEVEL_STYLE_IMAGE ), + TOKEN( "list-level-style-number", XML_LIST_LEVEL_STYLE_NUMBER ), + TOKEN( "list-linkage-type", XML_LIST_LINKAGE_TYPE ), + TOKEN( "list-name", XML_LIST_NAME ), + TOKEN( "list-style", XML_LIST_STYLE ), + TOKEN( "list-style-name", XML_LIST_STYLE_NAME ), + TOKEN( "ln", XML_LN ), + TOKEN( "locked", XML_LOCKED ), + TOKEN( "log", XML_LOG ), + TOKEN( "logarithmic", XML_LOGARITHMIC ), + TOKEN( "logbase", XML_LOGBASE ), + TOKEN( "long", XML_LONG ), + TOKEN( "lowlimit", XML_LOWLIMIT ), + TOKEN( "lr-tb", XML_LR_TB ), + TOKEN( "lt", XML_LT ), + TOKEN( "ltr", XML_LTR ), + TOKEN( "luminance", XML_LUMINANCE ), + TOKEN( "macro-name", XML_MACRO_NAME ), + TOKEN( "maction", XML_MACTION ), + TOKEN( "main-entry-style-name", XML_MAIN_ENTRY_STYLE_NAME ), + TOKEN( "major", XML_MAJOR ), + TOKEN( "major-origin", XML_MAJOR_ORIGIN ), + TOKEN( "maligngroup", XML_MALIGNGROUP ), + TOKEN( "malignmark", XML_MALIGNMARK ), + TOKEN( "manual", XML_MANUAL ), + TOKEN( "map", XML_MAP ), + TOKEN( "margin-bottom", XML_MARGIN_BOTTOM ), + TOKEN( "margin-left", XML_MARGIN_LEFT ), + TOKEN( "margin-right", XML_MARGIN_RIGHT ), + TOKEN( "margin-top", XML_MARGIN_TOP ), + TOKEN( "margins", XML_MARGINS ), + TOKEN( "marker", XML_MARKER ), + TOKEN( "marker-end", XML_MARKER_END ), + TOKEN( "marker-end-center", XML_MARKER_END_CENTER ), + TOKEN( "marker-end-width", XML_MARKER_END_WIDTH ), + TOKEN( "marker-start", XML_MARKER_START ), + TOKEN( "marker-start-center", XML_MARKER_START_CENTER ), + TOKEN( "marker-start-width", XML_MARKER_START_WIDTH ), + TOKEN( "marker-table", XML_MARKER_TABLE ), + TOKEN( "maroon", XML_MAROON ), + TOKEN( "master-page", XML_MASTER_PAGE ), + TOKEN( "master-page-name", XML_MASTER_PAGE_NAME ), + TOKEN( "master-styles", XML_MASTER_STYLES ), + TOKEN( "mastersthesis", XML_MASTERSTHESIS ), + TOKEN( "match", XML_MATCH ), + TOKEN( "math", XML_MATH ), + TOKEN( "matrix", XML_MATRIX ), + TOKEN( "matrix-covered", XML_MATRIX_COVERED ), + TOKEN( "matrixrow", XML_MATRIXROW ), + TOKEN( "max", XML_MAX ), + TOKEN( "max-edge", XML_MAX_EDGE ), + TOKEN( "max-height", XML_MAX_HEIGHT ), + TOKEN( "max-length", XML_MAX_LENGTH ), + TOKEN( "max-width", XML_MAX_WIDTH ), + TOKEN( "maximum", XML_MAXIMUM ), + TOKEN( "maximum-difference", XML_MAXIMUM_DIFFERENCE ), + TOKEN( "may-break-between-rows", XML_MAY_BREAK_BETWEEN_ROWS ), + TOKEN( "may-script", XML_MAY_SCRIPT ), + TOKEN( "mean", XML_MEAN ), + TOKEN( "mean-value", XML_MEAN_VALUE ), + TOKEN( "measure", XML_MEASURE ), + TOKEN( "measure-align", XML_MEASURE_ALIGN ), + TOKEN( "measure-vertical-align", XML_MEASURE_VERTICAL_ALIGN ), + TOKEN( "median", XML_MEDIAN ), + TOKEN( "medium", XML_MEDIUM ), + TOKEN( "menclose", XML_MENCLOSE ), + TOKEN( "merror", XML_MERROR ), + TOKEN( "message-type", XML_MESSAGE_TYPE ), + TOKEN( "meta", XML_META ), + TOKEN( "mfenced", XML_MFENCED ), + TOKEN( "mfrac", XML_MFRAC ), + TOKEN( "mi", XML_MI ), + TOKEN( "middle", XML_MIDDLE ), + TOKEN( "mime-type", XML_MIME_TYPE ), + TOKEN( "min", XML_MIN ), + TOKEN( "min-denominator-digits", XML_MIN_DENOMINATOR_DIGITS ), + TOKEN( "min-edge", XML_MIN_EDGE ), + TOKEN( "min-exponent-digits", XML_MIN_EXPONENT_DIGITS ), + TOKEN( "min-height", XML_MIN_HEIGHT ), + TOKEN( "min-integer-digits", XML_MIN_INTEGER_DIGITS ), + TOKEN( "min-label-distance", XML_MIN_LABEL_DISTANCE ), + TOKEN( "min-label-width", XML_MIN_LABEL_WIDTH ), + TOKEN( "min-length", XML_MIN_LENGTH ), + TOKEN( "min-line-height", XML_MIN_LINE_HEIGHT ), + TOKEN( "min-numerator-digits", XML_MIN_NUMERATOR_DIGITS ), + TOKEN( "min-row-height", XML_MIN_ROW_HEIGHT ), + TOKEN( "min-width", XML_MIN_WIDTH ), + TOKEN( "minimum", XML_MINIMUM ), + TOKEN( "minor", XML_MINOR ), + TOKEN( "minus", XML_MINUS ), + TOKEN( "minutes", XML_MINUTES ), + TOKEN( "mirror", XML_MIRROR ), + TOKEN( "mirrored", XML_MIRRORED ), + TOKEN( "misc", XML_MISC ), + TOKEN( "miter", XML_MITER ), + TOKEN( "mm", XML_MM ), + TOKEN( "mmultiscripts", XML_MMULTISCRIPTS ), + TOKEN( "mn", XML_MN ), + TOKEN( "mo", XML_MO ), + TOKEN( "mode", XML_MODE ), + TOKEN( "modern", XML_MODERN ), + TOKEN( "modification-date", XML_MODIFICATION_DATE ), + TOKEN( "modification-time", XML_MODIFICATION_TIME ), + TOKEN( "modulate", XML_MODULATE ), + TOKEN( "module", XML_MODULE ), + TOKEN( "moment", XML_MOMENT ), + TOKEN( "mono", XML_MONO ), + TOKEN( "month", XML_MONTH ), + TOKEN( "mouse-as-pen", XML_MOUSE_AS_PEN ), + TOKEN( "mouse-visible", XML_MOUSE_VISIBLE ), + TOKEN( "move", XML_MOVE ), + TOKEN( "move-from-bottom", XML_MOVE_FROM_BOTTOM ), + TOKEN( "move-from-left", XML_MOVE_FROM_LEFT ), + TOKEN( "move-from-right", XML_MOVE_FROM_RIGHT ), + TOKEN( "move-from-top", XML_MOVE_FROM_TOP ), + TOKEN( "move-protect", XML_MOVE_PROTECT ), + TOKEN( "move-short", XML_MOVE_SHORT ), + TOKEN( "movement", XML_MOVEMENT ), + TOKEN( "movement-cut-off", XML_MOVEMENT_CUT_OFF ), + TOKEN( "mover", XML_MOVER ), + TOKEN( "moving-average", XML_MOVING_AVERAGE ), + TOKEN( "mpadded", XML_MPADDED ), + TOKEN( "mphantom", XML_MPHANTOM ), + TOKEN( "mprescripts", XML_MPRESCRIPTS ), + TOKEN( "mroot", XML_MROOT ), + TOKEN( "mrow", XML_MROW ), + TOKEN( "ms", XML_MS ), + TOKEN( "mspace", XML_MSPACE ), + TOKEN( "msqrt", XML_MSQRT ), + TOKEN( "mstyle", XML_MSTYLE ), + TOKEN( "msub", XML_MSUB ), + TOKEN( "msubsup", XML_MSUBSUP ), + TOKEN( "msup", XML_MSUP ), + TOKEN( "mtable", XML_MTABLE ), + TOKEN( "mtd", XML_MTD ), + TOKEN( "mtext", XML_MTEXT ), + TOKEN( "mtr", XML_MTR ), + TOKEN( "multi-deletion-spanned", XML_MULTI_DELETION_SPANNED ), + TOKEN( "munder", XML_MUNDER ), + TOKEN( "munderover", XML_MUNDEROVER ), + TOKEN( "name", XML_NAME ), + TOKEN( "name-and-extension", XML_NAME_AND_EXTENSION ), + TOKEN( "named-expression", XML_NAMED_EXPRESSION ), + TOKEN( "named-expressions", XML_NAMED_EXPRESSIONS ), + TOKEN( "named-range", XML_NAMED_RANGE ), + TOKEN( "navy", XML_NAVY ), + TOKEN( "negative-color", XML_NEGATIVE_COLOR ), + TOKEN( "neq", XML_NEQ ), + TOKEN( "new", XML_NEW ), + TOKEN( "next", XML_NEXT ), + TOKEN( "next-page", XML_NEXT_PAGE ), + TOKEN( "next-style-name", XML_NEXT_STYLE_NAME ), + TOKEN( "no-limit", XML_NO_LIMIT ), + TOKEN( "no-wrap", XML_NO_WRAP ), + TOKEN( "!empty", XML_NOEMPTY ), + TOKEN( "nohref", XML_NOHREF ), + TOKEN( "!match", XML_NOMATCH ), + TOKEN( "non-whitespace-character-count", XML_NON_WHITESPACE_CHARACTER_COUNT ), + TOKEN( "none", XML_NONE ), + TOKEN( "normal", XML_NORMAL ), + TOKEN( "normals-direction", XML_NORMALS_DIRECTION ), + TOKEN( "normals-kind", XML_NORMALS_KIND ), + TOKEN( "not", XML_NOT ), + TOKEN( "not-equal-date", XML_NOT_EQUAL_DATE ), + TOKEN( "notation", XML_NOTATION ), + TOKEN( "note", XML_NOTE ), + TOKEN( "notes", XML_NOTES ), + TOKEN( "notin", XML_NOTIN ), + TOKEN( "notprsubset", XML_NOTPRSUBSET ), + TOKEN( "notsubset", XML_NOTSUBSET ), + TOKEN( "null-date", XML_NULL_DATE ), + TOKEN( "null-year", XML_NULL_YEAR ), + TOKEN( "num-format", XML_NUM_FORMAT ), + TOKEN( "num-letter-sync", XML_NUM_LETTER_SYNC ), + TOKEN( "num-prefix", XML_NUM_PREFIX ), + TOKEN( "num-suffix", XML_NUM_SUFFIX ), + TOKEN( "numalign", XML_NUMALIGN ), + TOKEN( "number", XML_NUMBER ), + TOKEN( "number-and-name", XML_NUMBER_AND_NAME ), + TOKEN( "number-columns-repeated", XML_NUMBER_COLUMNS_REPEATED ), + TOKEN( "number-columns-spanned", XML_NUMBER_COLUMNS_SPANNED ), + TOKEN( "number-lines", XML_NUMBER_LINES ), + TOKEN( "number-matrix-columns-spanned", XML_NUMBER_MATRIX_COLUMNS_SPANNED ), + TOKEN( "number-matrix-rows-spanned", XML_NUMBER_MATRIX_ROWS_SPANNED ), + TOKEN( "number-position", XML_NUMBER_POSITION ), + TOKEN( "number-rows-repeated", XML_NUMBER_ROWS_REPEATED ), + TOKEN( "number-rows-spanned", XML_NUMBER_ROWS_SPANNED ), + TOKEN( "number-style", XML_NUMBER_STYLE ), + TOKEN( "number-wrapped-paragraphs", XML_NUMBER_WRAPPED_PARAGRAPHS ), + TOKEN( "numbered-entries", XML_NUMBERED_ENTRIES ), + TOKEN( "object", XML_OBJECT ), + TOKEN( "object-count", XML_OBJECT_COUNT ), + TOKEN( "object-index", XML_OBJECT_INDEX ), + TOKEN( "object-index-entry-template", XML_OBJECT_INDEX_ENTRY_TEMPLATE ), + TOKEN( "object-index-source", XML_OBJECT_INDEX_SOURCE ), + TOKEN( "object-name", XML_OBJECT_NAME ), + TOKEN( "object-ole", XML_OBJECT_OLE ), + TOKEN( "objects", XML_OBJECTS ), + TOKEN( "odd-page", XML_ODD_PAGE ), + TOKEN( "offset", XML_OFFSET ), + TOKEN( "olive", XML_OLIVE ), + TOKEN( "onLoad", XML_ONLOAD ), + TOKEN( "onRequest", XML_ONREQUEST ), + TOKEN( "on-update-keep-size", XML_ON_UPDATE_KEEP_SIZE ), + TOKEN( "on-update-keep-styles", XML_ON_UPDATE_KEEP_STYLES ), + TOKEN( "online", XML_ONLINE ), + TOKEN( "online-text", XML_ONLINE_TEXT ), + TOKEN( "open", XML_OPEN ), + TOKEN( "open-horizontal", XML_OPEN_HORIZONTAL ), + TOKEN( "open-vertical", XML_OPEN_VERTICAL ), + TOKEN( "operation", XML_OPERATION ), + TOKEN( "operator", XML_OPERATOR ), + TOKEN( "optimal", XML_OPTIMAL ), + TOKEN( "option", XML_OPTION ), + TOKEN( "or", XML_OR ), + TOKEN( "order", XML_ORDER ), + TOKEN( "ordered-list", XML_ORDERED_LIST ), + TOKEN( "organizations", XML_ORGANIZATIONS ), + TOKEN( "orientation", XML_ORIENTATION ), + TOKEN( "orientation-landscape", XML_ORIENTATION_LANDSCAPE ), + TOKEN( "orientation-portrait", XML_ORIENTATION_PORTRAIT ), + TOKEN( "origin", XML_ORIGIN ), + TOKEN( "orphans", XML_ORPHANS ), + TOKEN( "outline-level", XML_OUTLINE_LEVEL ), + TOKEN( "outline-level-style", XML_OUTLINE_LEVEL_STYLE ), + TOKEN( "outline-style", XML_OUTLINE_STYLE ), + TOKEN( "outset", XML_OUTSET ), + TOKEN( "outside", XML_OUTSIDE ), + TOKEN( "overlap", XML_OVERLAP ), + TOKEN( "overlay", XML_OVERLAY ), + TOKEN( "p", XML_P ), + TOKEN( "package-name", XML_PACKAGE_NAME ), + TOKEN( "padding", XML_PADDING ), + TOKEN( "padding-bottom", XML_PADDING_BOTTOM ), + TOKEN( "padding-left", XML_PADDING_LEFT ), + TOKEN( "padding-right", XML_PADDING_RIGHT ), + TOKEN( "padding-top", XML_PADDING_TOP ), + TOKEN( "page", XML_PAGE ), + TOKEN( "page-adjust", XML_PAGE_ADJUST ), + TOKEN( "page-breaks-on-group-change", XML_PAGE_BREAKS_ON_GROUP_CHANGE ), + TOKEN( "page-content", XML_PAGE_CONTENT ), + TOKEN( "page-continuation-string", XML_PAGE_CONTINUATION_STRING ), + TOKEN( "page-count", XML_PAGE_COUNT ), + TOKEN( "page-end-margin", XML_PAGE_END_MARGIN ), + TOKEN( "page-height", XML_PAGE_HEIGHT ), + TOKEN( "page-master", XML_PAGE_MASTER ), + TOKEN( "page-master-name", XML_PAGE_MASTER_NAME ), + TOKEN( "page-name", XML_PAGE_NAME ), + TOKEN( "page-number", XML_PAGE_NUMBER ), + TOKEN( "page-number-visible", XML_PAGE_NUMBER_VISIBLE ), + TOKEN( "page-start-margin", XML_PAGE_START_MARGIN ), + TOKEN( "page-style-name", XML_PAGE_STYLE_NAME ), + TOKEN( "page-thumbnail", XML_PAGE_THUMBNAIL ), + TOKEN( "page-usage", XML_PAGE_USAGE ), + TOKEN( "page-variable-get", XML_PAGE_VARIABLE_GET ), + TOKEN( "page-variable-set", XML_PAGE_VARIABLE_SET ), + TOKEN( "page-view-zoom-value", XML_PAGE_VIEW_ZOOM_VALUE ), + TOKEN( "page-width", XML_PAGE_WIDTH ), + TOKEN( "pages", XML_PAGES ), + TOKEN( "paper-tray-number", XML_PAPER_TRAY_NUMBER ), + TOKEN( "paragraph", XML_PARAGRAPH ), + TOKEN( "paragraph-content", XML_PARAGRAPH_CONTENT ), + TOKEN( "paragraph-count", XML_PARAGRAPH_COUNT ), + TOKEN( "paragraph-end-margin", XML_PARAGRAPH_END_MARGIN ), + TOKEN( "paragraph-start-margin", XML_PARAGRAPH_START_MARGIN ), + TOKEN( "parallel", XML_PARALLEL ), + TOKEN( "param", XML_PARAM ), + TOKEN( "parent-style-name", XML_PARENT_STYLE_NAME ), + TOKEN( "parse-sql-statement", XML_PARSE_SQL_STATEMENT ), + TOKEN( "parsed", XML_PARSED ), + TOKEN( "partialdiff", XML_PARTIALDIFF ), + TOKEN( "password", XML_PASSWORD ), + TOKEN( "passwort", XML_PASSWORT ), + TOKEN( "path", XML_PATH ), + TOKEN( "path-id", XML_PATH_ID ), + TOKEN( "pause", XML_PAUSE ), + TOKEN( "pending", XML_PENDING ), + TOKEN( "percentage", XML_PERCENTAGE ), + TOKEN( "percentage-style", XML_PERCENTAGE_STYLE ), + TOKEN( "perspective", XML_PERSPECTIVE ), + TOKEN( "phdthesis", XML_PHDTHESIS ), + TOKEN( "phong", XML_PHONG ), + TOKEN( "pie-offset", XML_PIE_OFFSET ), + TOKEN( "placeholder", XML_PLACEHOLDER ), + TOKEN( "placeholder-type", XML_PLACEHOLDER_TYPE ), + TOKEN( "placing", XML_PLACING ), + TOKEN( "plain-number", XML_PLAIN_NUMBER ), + TOKEN( "plain-number-and-name", XML_PLAIN_NUMBER_AND_NAME ), + TOKEN( "play-full", XML_PLAY_FULL ), + TOKEN( "plot-area", XML_PLOT_AREA ), + TOKEN( "plugin", XML_PLUGIN ), + TOKEN( "plus", XML_PLUS ), + TOKEN( "points", XML_POINTS ), + TOKEN( "polygon", XML_POLYGON ), + TOKEN( "polyline", XML_POLYLINE ), + TOKEN( "polynomial", XML_POLYNOMIAL ), + TOKEN( "pool-id", XML_POOL_ID ), + TOKEN( "portrait", XML_PORTRAIT ), + TOKEN( "position", XML_POSITION ), + TOKEN( "position-bottom", XML_POSITION_BOTTOM ), + TOKEN( "position-left", XML_POSITION_LEFT ), + TOKEN( "position-right", XML_POSITION_RIGHT ), + TOKEN( "position-top", XML_POSITION_TOP ), + TOKEN( "positive-color", XML_POSITIVE_COLOR ), + TOKEN( "oblique", XML_POSTURE_OBLIQUE ), + TOKEN( "power", XML_POWER ), + TOKEN( "precision-as-shown", XML_PRECISION_AS_SHOWN ), + TOKEN( "prefix", XML_PREFIX ), + TOKEN( "presentation", XML_PRESENTATION ), + TOKEN( "orgchart", XML_PRESENTATION_ORGCHART ), + TOKEN( "outline", XML_PRESENTATION_OUTLINE ), + TOKEN( "presentation-page-layout", XML_PRESENTATION_PAGE_LAYOUT ), + TOKEN( "presentation-page-layout-name", XML_PRESENTATION_PAGE_LAYOUT_NAME ), + TOKEN( "previous", XML_PREVIOUS ), + TOKEN( "previous-page", XML_PREVIOUS_PAGE ), + TOKEN( "print", XML_PRINT ), + TOKEN( "print-content", XML_PRINT_CONTENT ), + TOKEN( "print-date", XML_PRINT_DATE ), + TOKEN( "print-orientation", XML_PRINT_ORIENTATION ), + TOKEN( "print-page-order", XML_PRINT_PAGE_ORDER ), + TOKEN( "print-range", XML_PRINT_RANGE ), + TOKEN( "print-ranges", XML_PRINT_RANGES ), + TOKEN( "print-time", XML_PRINT_TIME ), + TOKEN( "printable", XML_PRINTABLE ), + TOKEN( "printed-by", XML_PRINTED_BY ), + TOKEN( "proceedings", XML_PROCEEDINGS ), + TOKEN( "product", XML_PRODUCT ), + TOKEN( "projection", XML_PROJECTION ), + TOKEN( "properties", XML_PROPERTIES ), + TOKEN( "protect", XML_PROTECT ), + TOKEN( "protected", XML_PROTECTED ), + TOKEN( "protection-key", XML_PROTECTION_KEY ), + TOKEN( "protection-key-digest-algorithm", XML_PROTECTION_KEY_DIGEST_ALGORITHM ), + TOKEN( "protection-key-digest-algorithm-2", XML_PROTECTION_KEY_DIGEST_ALGORITHM_2 ), + TOKEN( "prsubset", XML_PRSUBSET ), + TOKEN( "publisher", XML_PUBLISHER ), + TOKEN( "punctuation-wrap", XML_PUNCTUATION_WRAP ), + TOKEN( "purple", XML_PURPLE ), + TOKEN( "pyramid", XML_PYRAMID ), + TOKEN( "qrcode", XML_QRCODE ), + TOKEN( "qrcode-border", XML_QRCODE_BORDER ), + TOKEN( "qrcode-errorcorrection", XML_QRCODE_ERROR_CORRECTION ), + TOKEN( "quarter", XML_QUARTER ), + TOKEN( "query-name", XML_QUERY_NAME ), + TOKEN( "quo-vadis", XML_QUO_VADIS ), + TOKEN( "quotient", XML_QUOTIENT ), + TOKEN( "r", XML_R ), + TOKEN( "radar", XML_RADAR ), + TOKEN( "random", XML_RANDOM ), + TOKEN( "range-address", XML_RANGE_ADDRESS ), + TOKEN( "range-usable-as", XML_RANGE_USABLE_AS ), + TOKEN( "recreate-on-edit", XML_RECREATE_ON_EDIT ), + TOKEN( "rect", XML_RECT ), + TOKEN( "red", XML_RED ), + TOKEN( "ref-name", XML_REF_NAME ), + TOKEN( "reference", XML_REFERENCE ), + TOKEN( "reference-end", XML_REFERENCE_END ), + TOKEN( "reference-format", XML_REFERENCE_FORMAT ), + TOKEN( "reference-mark", XML_REFERENCE_MARK ), + TOKEN( "reference-mark-end", XML_REFERENCE_MARK_END ), + TOKEN( "reference-mark-start", XML_REFERENCE_MARK_START ), + TOKEN( "reference-ref", XML_REFERENCE_REF ), + TOKEN( "reference-start", XML_REFERENCE_START ), + TOKEN( "reference-type", XML_REFERENCE_TYPE ), + TOKEN( "refresh-delay", XML_REFRESH_DELAY ), + TOKEN( "region-center", XML_REGION_CENTER ), + TOKEN( "region-left", XML_REGION_LEFT ), + TOKEN( "region-right", XML_REGION_RIGHT ), + TOKEN( "register-true", XML_REGISTER_TRUE ), + TOKEN( "register-truth-ref-style-name", XML_REGISTER_TRUTH_REF_STYLE_NAME ), + TOKEN( "rejected", XML_REJECTED ), + TOKEN( "rejecting-change-id", XML_REJECTING_CHANGE_ID ), + TOKEN( "rejection", XML_REJECTION ), + TOKEN( "rel-column-width", XML_REL_COLUMN_WIDTH ), + TOKEN( "rel-height", XML_REL_HEIGHT ), + TOKEN( "rel-height-rel", XML_REL_HEIGHT_REL ), + TOKEN( "rel-width", XML_REL_WIDTH ), + TOKEN( "rel-width-rel", XML_REL_WIDTH_REL ), + TOKEN( "relative", XML_RELATIVE ), + TOKEN( "relative-tab-stop-position", XML_RELATIVE_TAB_STOP_POSITION ), + TOKEN( "reln", XML_RELN ), + TOKEN( "rem", XML_REM ), + TOKEN( "remove-dependents", XML_REMOVE_DEPENDENTS ), + TOKEN( "remove-precedents", XML_REMOVE_PRECEDENTS ), + TOKEN( "repeat", XML_REPEAT ), + TOKEN( "repeat-column", XML_REPEAT_COLUMN ), + TOKEN( "repeat-row", XML_REPEAT_ROW ), + TOKEN( "repeated", XML_REPEATED ), + TOKEN( "replace", XML_REPLACE ), + TOKEN( "report-type", XML_REPORT_TYPE ), + TOKEN( "restart-on-page", XML_RESTART_ON_PAGE ), + TOKEN( "revision", XML_REVISION ), + TOKEN( "ridge", XML_RIDGE ), + TOKEN( "right", XML_RIGHT ), + TOKEN( "right-outside", XML_RIGHT_OUTSIDE ), + TOKEN( "right-text", XML_RIGHT_TEXT ), + TOKEN( "right-arc", XML_RIGHTARC ), + TOKEN( "right-circle", XML_RIGHTCIRCLE ), + TOKEN( "ring", XML_RING ), + TOKEN( "role", XML_ROLE ), + TOKEN( "roll-from-bottom", XML_ROLL_FROM_BOTTOM ), + TOKEN( "roll-from-left", XML_ROLL_FROM_LEFT ), + TOKEN( "roll-from-right", XML_ROLL_FROM_RIGHT ), + TOKEN( "roman", XML_ROMAN ), + TOKEN( "root", XML_ROOT ), + TOKEN( "rotate", XML_ROTATE ), + TOKEN( "rotation", XML_ROTATION ), + TOKEN( "rotation-align", XML_ROTATION_ALIGN ), + TOKEN( "rotation-angle", XML_ROTATION_ANGLE ), + TOKEN( "round", XML_ROUND ), + TOKEN( "row", XML_ROW ), + TOKEN( "row-height", XML_ROW_HEIGHT ), + TOKEN( "row-number", XML_ROW_NUMBER ), + TOKEN( "rows", XML_ROWS ), + TOKEN( "rsid", XML_RSID ), + TOKEN( "paragraph-rsid", XML_PARRSID ), + TOKEN( "ruby", XML_RUBY ), + TOKEN( "ruby-align", XML_RUBY_ALIGN ), + TOKEN( "ruby-base", XML_RUBY_BASE ), + TOKEN( "ruby-position", XML_RUBY_POSITION ), + TOKEN( "ruby-text", XML_RUBY_TEXT ), + TOKEN( "run-through", XML_RUN_THROUGH ), + TOKEN( "rx", XML_RX ), + TOKEN( "ry", XML_RY ), + TOKEN( "s", XML_S ), + TOKEN( "scale", XML_SCALE ), + TOKEN( "scale-min", XML_SCALE_MIN ), + TOKEN( "scale-text", XML_SCALE_TEXT ), + TOKEN( "scale-to", XML_SCALE_TO ), + TOKEN( "scale-to-pages", XML_SCALE_TO_PAGES ), + TOKEN( "scatter", XML_SCATTER ), + TOKEN( "scenario", XML_SCENARIO ), + TOKEN( "scenario-ranges", XML_SCENARIO_RANGES ), + TOKEN( "scene", XML_SCENE ), + TOKEN( "school", XML_SCHOOL ), + TOKEN( "scientific-number", XML_SCIENTIFIC_NUMBER ), + TOKEN( "score-spaces", XML_SCORE_SPACES ), + TOKEN( "script", XML_SCRIPT ), + TOKEN( "script-asian", XML_SCRIPT_ASIAN ), + TOKEN( "script-complex", XML_SCRIPT_COMPLEX ), + TOKEN( "scroll", XML_SCROLL ), + TOKEN( "sdev", XML_SDEV ), + TOKEN( "search-criteria-must-apply-to-whole-cell", XML_SEARCH_CRITERIA_MUST_APPLY_TO_WHOLE_CELL ), + TOKEN( "sec", XML_SEC ), + TOKEN( "sech", XML_SECH ), + TOKEN( "second-date-time", XML_SECOND_DATE_TIME ), + TOKEN( "seconds", XML_SECONDS ), + TOKEN( "section", XML_SECTION ), + TOKEN( "section-desc", XML_SECTION_DESC ), + TOKEN( "section-name", XML_SECTION_NAME ), + TOKEN( "section-source", XML_SECTION_SOURCE ), + TOKEN( "select-page", XML_SELECT_PAGE ), + TOKEN( "select-protected-cells", XML_SELECT_PROTECTED_CELLS ), + TOKEN( "select-unprotected-cells", XML_SELECT_UNPROTECTED_CELLS ), + TOKEN( "selector", XML_SELECTOR ), + TOKEN( "semantics", XML_SEMANTICS ), + TOKEN( "semi-automatic", XML_SEMI_AUTOMATIC ), + TOKEN( "sender-city", XML_SENDER_CITY ), + TOKEN( "sender-company", XML_SENDER_COMPANY ), + TOKEN( "sender-country", XML_SENDER_COUNTRY ), + TOKEN( "sender-email", XML_SENDER_EMAIL ), + TOKEN( "sender-fax", XML_SENDER_FAX ), + TOKEN( "sender-firstname", XML_SENDER_FIRSTNAME ), + TOKEN( "sender-initials", XML_SENDER_INITIALS ), + TOKEN( "sender-lastname", XML_SENDER_LASTNAME ), + TOKEN( "sender-phone-private", XML_SENDER_PHONE_PRIVATE ), + TOKEN( "sender-phone-work", XML_SENDER_PHONE_WORK ), + TOKEN( "sender-position", XML_SENDER_POSITION ), + TOKEN( "sender-postal-code", XML_SENDER_POSTAL_CODE ), + TOKEN( "sender-state-or-province", XML_SENDER_STATE_OR_PROVINCE ), + TOKEN( "sender-street", XML_SENDER_STREET ), + TOKEN( "sender-title", XML_SENDER_TITLE ), + TOKEN( "sep", XML_SEP ), + TOKEN( "separation-character", XML_SEPARATION_CHARACTER ), + TOKEN( "separator", XML_SEPARATOR ), + TOKEN( "sequence", XML_SEQUENCE ), + TOKEN( "sequence-decl", XML_SEQUENCE_DECL ), + TOKEN( "sequence-decls", XML_SEQUENCE_DECLS ), + TOKEN( "sequence-ref", XML_SEQUENCE_REF ), + TOKEN( "series", XML_SERIES ), + TOKEN( "series-source", XML_SERIES_SOURCE ), + TOKEN( "server-map", XML_SERVER_MAP ), + TOKEN( "set", XML_SET ), + TOKEN( "setdiff", XML_SETDIFF ), + TOKEN( "settings", XML_SETTINGS ), + TOKEN( "shade-mode", XML_SHADE_MODE ), + TOKEN( "shadow", XML_SHADOW ), + TOKEN( "shadow-color", XML_SHADOW_COLOR ), + TOKEN( "shadow-offset-x", XML_SHADOW_OFFSET_X ), + TOKEN( "shadow-offset-y", XML_SHADOW_OFFSET_Y ), + TOKEN( "shadow-slant", XML_SHADOW_SLANT ), + TOKEN( "shadow-transparency", XML_SHADOW_TRANSPARENCY ), + TOKEN( "shape", XML_SHAPE ), + TOKEN( "shape-id", XML_SHAPE_ID ), + TOKEN( "shapes", XML_SHAPES ), + TOKEN( "sheet-name", XML_SHEET_NAME ), + TOKEN( "shininess", XML_SHININESS ), + TOKEN( "short", XML_SHORT ), + TOKEN( "show", XML_SHOW ), + TOKEN( "show-accepted-changes", XML_SHOW_ACCEPTED_CHANGES ), + TOKEN( "show-changes", XML_SHOW_CHANGES ), + TOKEN( "show-changes-by-author", XML_SHOW_CHANGES_BY_AUTHOR ), + TOKEN( "show-changes-by-author-name", XML_SHOW_CHANGES_BY_AUTHOR_NAME ), + TOKEN( "show-changes-by-comment", XML_SHOW_CHANGES_BY_COMMENT ), + TOKEN( "show-changes-by-comment-text", XML_SHOW_CHANGES_BY_COMMENT_TEXT ), + TOKEN( "show-changes-by-datetime", XML_SHOW_CHANGES_BY_DATETIME ), + TOKEN( "show-changes-by-datetime-first-datetime", XML_SHOW_CHANGES_BY_DATETIME_FIRST_DATETIME ), + TOKEN( "show-changes-by-datetime-mode", XML_SHOW_CHANGES_BY_DATETIME_MODE ), + TOKEN( "show-changes-by-datetime-second-datetime", XML_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME ), + TOKEN( "show-changes-by-ranges", XML_SHOW_CHANGES_BY_RANGES ), + TOKEN( "show-changes-by-ranges-list", XML_SHOW_CHANGES_BY_RANGES_LIST ), + TOKEN( "show-logo", XML_SHOW_LOGO ), + TOKEN( "show-rejected-changes", XML_SHOW_REJECTED_CHANGES ), + TOKEN( "show-shape", XML_SHOW_SHAPE ), + TOKEN( "show-text", XML_SHOW_TEXT ), + TOKEN( "show-unit", XML_SHOW_UNIT ), + TOKEN( "show-value", XML_SHOW_VALUE ), + TOKEN( "shows", XML_SHOWS ), + TOKEN( "side-by-side", XML_SIDE_BY_SIDE ), + TOKEN( "silver", XML_SILVER ), + TOKEN( "simple", XML_SIMPLE ), + TOKEN( "sin", XML_SIN ), + TOKEN( "since-date-time", XML_SINCE_DATE_TIME ), + TOKEN( "since-save", XML_SINCE_SAVE ), + TOKEN( "sinh", XML_SINH ), + TOKEN( "size", XML_SIZE ), + TOKEN( "size-protect", XML_SIZE_PROTECT ), + TOKEN( "slant", XML_SLANT ), + TOKEN( "slant-x", XML_SLANT_X ), + TOKEN( "slant-y", XML_SLANT_Y ), + TOKEN( "slide", XML_SLIDE ), + TOKEN( "slow", XML_SLOW ), + TOKEN( "softedge-radius", XML_SOFTEDGE_RADIUS ), + TOKEN( "solid", XML_SOLID ), + TOKEN( "solid-type", XML_SOLID_TYPE ), + TOKEN( "sort", XML_SORT ), + TOKEN( "sort-ascending", XML_SORT_ASCENDING ), + TOKEN( "sort-by", XML_SORT_BY ), + TOKEN( "sort-by-position", XML_SORT_BY_POSITION ), + TOKEN( "sort-groups", XML_SORT_GROUPS ), + TOKEN( "sort-key", XML_SORT_KEY ), + TOKEN( "sound", XML_SOUND ), + TOKEN( "source-cell-range", XML_SOURCE_CELL_RANGE ), + TOKEN( "source-cell-range-addresses", XML_SOURCE_CELL_RANGE_ADDRESSES ), + TOKEN( "source-field-name", XML_SOURCE_FIELD_NAME ), + TOKEN( "source-name", XML_SOURCE_NAME ), + TOKEN( "source-range-address", XML_SOURCE_RANGE_ADDRESS ), + TOKEN( "source-service", XML_SOURCE_SERVICE ), + TOKEN( "space-before", XML_SPACE_BEFORE ), + TOKEN( "span", XML_SPAN ), + TOKEN( "specular", XML_SPECULAR ), + TOKEN( "specular-color", XML_SPECULAR_COLOR ), + TOKEN( "speed", XML_SPEED ), + TOKEN( "sphere", XML_SPHERE ), + TOKEN( "spiral", XML_SPIRAL ), + TOKEN( "spiral-in", XML_SPIRAL_IN ), + TOKEN( "spiral-inward-left", XML_SPIRAL_INWARD_LEFT ), + TOKEN( "spiral-inward-right", XML_SPIRAL_INWARD_RIGHT ), + TOKEN( "spiral-out", XML_SPIRAL_OUT ), + TOKEN( "spiral-outward-left", XML_SPIRAL_OUTWARD_LEFT ), + TOKEN( "spiral-outward-right", XML_SPIRAL_OUTWARD_RIGHT ), + TOKEN( "spiralin-left", XML_SPIRALIN_LEFT ), + TOKEN( "spiralin-right", XML_SPIRALIN_RIGHT ), + TOKEN( "spiralout-left", XML_SPIRALOUT_LEFT ), + TOKEN( "spiralout-right", XML_SPIRALOUT_RIGHT ), + TOKEN( "splines", XML_SPLINES ), + TOKEN( "split", XML_SPLIT ), + TOKEN( "split-column", XML_SPLIT_COLUMN ), + TOKEN( "split-position", XML_SPLIT_POSITION ), + TOKEN( "split-row", XML_SPLIT_ROW ), + TOKEN( "spreadsheet", XML_SPREADSHEET ), + TOKEN( "spreadMethod", XML_SPREADMETHOD ), + TOKEN( "sql-statement", XML_SQL_STATEMENT ), + TOKEN( "stacked", XML_STACKED ), + TOKEN( "stagger-even", XML_STAGGER_EVEN ), + TOKEN( "stagger-odd", XML_STAGGER_ODD ), + TOKEN( "standard", XML_STANDARD ), + TOKEN( "standard-deviation", XML_STANDARD_DEVIATION ), + TOKEN( "starbasic", XML_STARBASIC ), + TOKEN( "start", XML_START ), + TOKEN( "start-angle", XML_START_ANGLE ), + TOKEN( "start-color", XML_START_COLOR ), + TOKEN( "start-column", XML_START_COLUMN ), + TOKEN( "start-glue-point", XML_START_GLUE_POINT ), + TOKEN( "start-guide", XML_START_GUIDE ), + TOKEN( "start-intensity", XML_START_INTENSITY ), + TOKEN( "start-line-spacing-horizontal", XML_START_LINE_SPACING_HORIZONTAL ), + TOKEN( "start-line-spacing-vertical", XML_START_LINE_SPACING_VERTICAL ), + TOKEN( "start-numbering-at", XML_START_NUMBERING_AT ), + TOKEN( "start-page", XML_START_PAGE ), + TOKEN( "start-position", XML_START_POSITION ), + TOKEN( "start-row", XML_START_ROW ), + TOKEN( "start-scale", XML_START_SCALE ), + TOKEN( "start-shape", XML_START_SHAPE ), + TOKEN( "start-table", XML_START_TABLE ), + TOKEN( "start-value", XML_START_VALUE ), + TOKEN( "start-with-navigator", XML_START_WITH_NAVIGATOR ), + TOKEN( "statistics", XML_STATISTICS ), + TOKEN( "status", XML_STATUS ), + TOKEN( "stay-on-top", XML_STAY_ON_TOP ), + TOKEN( "stdev", XML_STDEV ), + TOKEN( "stdevp", XML_STDEVP ), + TOKEN( "steps", XML_STEPS ), + TOKEN( "step-size", XML_STEP_SIZE ), + TOKEN( "stock", XML_STOCK ), + TOKEN( "stock-updown-bars", XML_STOCK_UPDOWN_BARS ), + TOKEN( "stock-with-volume", XML_STOCK_WITH_VOLUME ), + TOKEN( "stop", XML_STOP ), + TOKEN( "stop-color", XML_STOP_COLOR ), + TOKEN( "stop-opacity", XML_STOP_OPACITY ), + TOKEN( "stretch", XML_STRETCH ), + TOKEN( "stretch-from-bottom", XML_STRETCH_FROM_BOTTOM ), + TOKEN( "stretch-from-left", XML_STRETCH_FROM_LEFT ), + TOKEN( "stretch-from-right", XML_STRETCH_FROM_RIGHT ), + TOKEN( "stretch-from-top", XML_STRETCH_FROM_TOP ), + TOKEN( "stretchy", XML_STRETCHY ), + TOKEN( "strict", XML_STRICT ), + TOKEN( "string", XML_STRING ), + TOKEN( "string-value", XML_STRING_VALUE ), + TOKEN( "string-value-if-false", XML_STRING_VALUE_IF_FALSE ), + TOKEN( "string-value-if-true", XML_STRING_VALUE_IF_TRUE ), + TOKEN( "stripes", XML_STRIPES ), + TOKEN( "stroke", XML_STROKE ), + TOKEN( "stroke-color", XML_STROKE_COLOR ), + TOKEN( "stroke-dash", XML_STROKE_DASH ), + TOKEN( "stroke-linecap", XML_STROKE_LINECAP ), + TOKEN( "stroke-linejoin", XML_STROKE_LINEJOIN ), + TOKEN( "stroke-opacity", XML_STROKE_OPACITY ), + TOKEN( "stroke-width", XML_STROKE_WIDTH ), + TOKEN( "structure-protected", XML_STRUCTURE_PROTECTED ), + TOKEN( "style", XML_STYLE ), + TOKEN( "style-name", XML_STYLE_NAME ), + TOKEN( "styles", XML_STYLES ), + TOKEN( "stylesheet", XML_STYLESHEET ), + TOKEN( "sub-table", XML_SUB_TABLE ), + TOKEN( "subject", XML_SUBJECT ), + TOKEN( "subset", XML_SUBSET ), + TOKEN( "subtitle", XML_SUBTITLE ), + TOKEN( "subtotal-field", XML_SUBTOTAL_FIELD ), + TOKEN( "subtotal-rule", XML_SUBTOTAL_RULE ), + TOKEN( "subtotal-rules", XML_SUBTOTAL_RULES ), + TOKEN( "sub-view-size", XML_SUB_VIEW_SIZE ), + TOKEN( "suffix", XML_SUFFIX ), + TOKEN( "sum", XML_SUM ), + TOKEN( "swiss", XML_SWISS ), + TOKEN( "symbol", XML_SYMBOL ), + TOKEN( "symbol-height", XML_SYMBOL_HEIGHT ), + TOKEN( "symbol-image-name", XML_SYMBOL_IMAGE_NAME ), + TOKEN( "symbol-width", XML_SYMBOL_WIDTH ), + TOKEN( "system", XML_SYSTEM ), + TOKEN( "tab-color", XML_TAB_COLOR ), + TOKEN( "tab-stop", XML_TAB_STOP ), + TOKEN( "tab-stop-distance", XML_TAB_STOP_DISTANCE ), + TOKEN( "tab-stops", XML_TAB_STOPS ), + TOKEN( "table", XML_TABLE ), + TOKEN( "table-background", XML_TABLE_BACKGROUND ), + TOKEN( "table-cell", XML_TABLE_CELL ), + TOKEN( "table-centering", XML_TABLE_CENTERING ), + TOKEN( "table-column", XML_TABLE_COLUMN ), + TOKEN( "table-column-group", XML_TABLE_COLUMN_GROUP ), + TOKEN( "table-columns", XML_TABLE_COLUMNS ), + TOKEN( "table-count", XML_TABLE_COUNT ), + TOKEN( "table-header", XML_TABLE_HEADER ), + TOKEN( "table-header-columns", XML_TABLE_HEADER_COLUMNS ), + TOKEN( "table-header-rows", XML_TABLE_HEADER_ROWS ), + TOKEN( "table-index", XML_TABLE_INDEX ), + TOKEN( "table-index-entry-template", XML_TABLE_INDEX_ENTRY_TEMPLATE ), + TOKEN( "table-index-source", XML_TABLE_INDEX_SOURCE ), + TOKEN( "table-name", XML_TABLE_NAME ), + TOKEN( "table-of-content", XML_TABLE_OF_CONTENT ), + TOKEN( "table-of-content-entry-template", XML_TABLE_OF_CONTENT_ENTRY_TEMPLATE ), + TOKEN( "table-of-content-source", XML_TABLE_OF_CONTENT_SOURCE ), + TOKEN( "table-page", XML_TABLE_PAGE ), + TOKEN( "table-protection", XML_TABLE_PROTECTION ), + TOKEN( "table-row", XML_TABLE_ROW ), + TOKEN( "table-row-group", XML_TABLE_ROW_GROUP ), + TOKEN( "table-rows", XML_TABLE_ROWS ), + TOKEN( "table-source", XML_TABLE_SOURCE ), + TOKEN( "table-view", XML_TABLE_VIEW ), + TOKEN( "tables", XML_TABLES ), + TOKEN( "tan", XML_TAN ), + TOKEN( "tanh", XML_TANH ), + TOKEN( "target-cell-address", XML_TARGET_CELL_ADDRESS ), + TOKEN( "target-frame", XML_TARGET_FRAME ), + TOKEN( "target-frame-name", XML_TARGET_FRAME_NAME ), + TOKEN( "target-range-address", XML_TARGET_RANGE_ADDRESS ), + TOKEN( "tb-rl", XML_TB_RL ), + TOKEN( "teal", XML_TEAL ), + TOKEN( "techreport", XML_TECHREPORT ), + TOKEN( "template", XML_TEMPLATE ), + TOKEN( "template-name", XML_TEMPLATE_NAME ), + TOKEN( "tendsto", XML_TENDSTO ), + TOKEN( "texture-filter", XML_TEX_FILTER ), + TOKEN( "texture-generation-mode-x", XML_TEX_GENERATION_MODE_X ), + TOKEN( "texture-generation-mode-y", XML_TEX_GENERATION_MODE_Y ), + TOKEN( "texture-kind", XML_TEX_KIND ), + TOKEN( "texture-mode", XML_TEX_MODE ), + TOKEN( "text", XML_TEXT ), + TOKEN( "text-align", XML_TEXT_ALIGN ), + TOKEN( "text-align-last", XML_TEXT_ALIGN_LAST ), + TOKEN( "text-align-source", XML_TEXT_ALIGN_SOURCE ), + TOKEN( "text-autospace", XML_TEXT_AUTOSPACE ), + TOKEN( "text-background-color", XML_TEXT_BACKGROUND_COLOR ), + TOKEN( "text-blinking", XML_TEXT_BLINKING ), + TOKEN( "text-box", XML_TEXT_BOX ), + TOKEN( "text-combine", XML_TEXT_COMBINE ), + TOKEN( "text-combine-end-char", XML_TEXT_COMBINE_END_CHAR ), + TOKEN( "text-combine-start-char", XML_TEXT_COMBINE_START_CHAR ), + TOKEN( "text-content", XML_TEXT_CONTENT ), + TOKEN( "text-conversion-dictionary", XML_TEXT_CONVERSION_DICTIONARY ), + TOKEN( "text-crossing-out", XML_TEXT_CROSSING_OUT ), + TOKEN( "text-emphasize", XML_TEXT_EMPHASIZE ), + TOKEN( "text-global", XML_TEXT_GLOBAL ), + TOKEN( "text-indent", XML_TEXT_INDENT ), + TOKEN( "text-input", XML_TEXT_INPUT ), + TOKEN( "text-justify", XML_TEXT_JUSTIFY ), + TOKEN( "text-outline", XML_TEXT_OUTLINE ), + TOKEN( "text-only", XML_TEXT_ONLY ), + TOKEN( "text-position", XML_TEXT_POSITION ), + TOKEN( "text-rotation-angle", XML_TEXT_ROTATION_ANGLE ), + TOKEN( "text-rotation-scale", XML_TEXT_ROTATION_SCALE ), + TOKEN( "text-scale", XML_TEXT_SCALE ), + TOKEN( "text-shadow", XML_TEXT_SHADOW ), + TOKEN( "text-style", XML_TEXT_STYLE ), + TOKEN( "text-transform", XML_TEXT_TRANSFORM ), + TOKEN( "text-underline", XML_TEXT_UNDERLINE ), + TOKEN( "text-underline-color", XML_TEXT_UNDERLINE_COLOR ), + TOKEN( "textarea-horizontal-align", XML_TEXTAREA_HORIZONTAL_ALIGN ), + TOKEN( "textarea-vertical-align", XML_TEXTAREA_VERTICAL_ALIGN ), + TOKEN( "textual", XML_TEXTUAL ), + TOKEN( "thick", XML_THICK ), + TOKEN( "thin", XML_THIN ), + TOKEN( "three-dimensional", XML_THREE_DIMENSIONAL ), + TOKEN( "thumbnail", XML_THUMBNAIL ), + TOKEN( "tick-marks-major-inner", XML_TICK_MARKS_MAJOR_INNER ), + TOKEN( "tick-marks-major-outer", XML_TICK_MARKS_MAJOR_OUTER ), + TOKEN( "tick-marks-minor-inner", XML_TICK_MARKS_MINOR_INNER ), + TOKEN( "tick-marks-minor-outer", XML_TICK_MARKS_MINOR_OUTER ), + TOKEN( "tile-repeat-offset", XML_TILE_REPEAT_OFFSET ), + TOKEN( "time", XML_TIME ), + TOKEN( "time-adjust", XML_TIME_ADJUST ), + TOKEN( "time-style", XML_TIME_STYLE ), + TOKEN( "time-value", XML_TIME_VALUE ), + TOKEN( "times", XML_TIMES ), + TOKEN( "title", XML_TITLE ), + TOKEN( "to-another-table", XML_TO_ANOTHER_TABLE ), + TOKEN( "to-bottom", XML_TO_BOTTOM ), + TOKEN( "to-center", XML_TO_CENTER ), + TOKEN( "to-left", XML_TO_LEFT ), + TOKEN( "to-lower-left", XML_TO_LOWER_LEFT ), + TOKEN( "to-lower-right", XML_TO_LOWER_RIGHT ), + TOKEN( "to-right", XML_TO_RIGHT ), + TOKEN( "to-top", XML_TO_TOP ), + TOKEN( "to-upper-left", XML_TO_UPPER_LEFT ), + TOKEN( "to-upper-right", XML_TO_UPPER_RIGHT ), + TOKEN( "toc-mark", XML_TOC_MARK ), + TOKEN( "toc-mark-end", XML_TOC_MARK_END ), + TOKEN( "toc-mark-start", XML_TOC_MARK_START ), + TOKEN( "top", XML_TOP ), + TOKEN( "top-left", XML_TOP_LEFT ), + TOKEN( "top percent", XML_TOP_PERCENT ), + TOKEN( "top-right", XML_TOP_RIGHT ), + TOKEN( "top values", XML_TOP_VALUES ), + TOKEN( "top-arc", XML_TOPARC ), + TOKEN( "top-circle", XML_TOPCIRCLE ), + TOKEN( "trace-dependents", XML_TRACE_DEPENDENTS ), + TOKEN( "trace-errors", XML_TRACE_ERRORS ), + TOKEN( "trace-precedents", XML_TRACE_PRECEDENTS ), + TOKEN( "track-changes", XML_TRACK_CHANGES ), + TOKEN( "tracked-changes", XML_TRACKED_CHANGES ), + TOKEN( "tracked-changes-view-settings", XML_TRACKED_CHANGES_VIEW_SETTINGS ), + TOKEN( "transform", XML_TRANSFORM ), + TOKEN( "transition-on-click", XML_TRANSITION_ON_CLICK ), + TOKEN( "transparency", XML_TRANSPARENCY ), + TOKEN( "transparency-name", XML_TRANSPARENCY_NAME ), + TOKEN( "transparent", XML_TRANSPARENT ), + TOKEN( "transpose", XML_TRANSPOSE ), + TOKEN( "true", XML_TRUE ), + TOKEN( "truncate-on-overflow", XML_TRUNCATE_ON_OVERFLOW ), + TOKEN( "try-staggering-first", XML_TRY_STAGGERING_FIRST ), + TOKEN( "tspan", XML_TSPAN ), + TOKEN( "ttb", XML_TTB ), + TOKEN( "type", XML_TYPE ), + TOKEN( "dot-dash", XML_DOT_DASH ), + TOKEN( "dot-dot-dash", XML_DOT_DOT_DASH ), + TOKEN( "long-dash", XML_LONG_DASH ), + TOKEN( "show-sign-date", XML_SHOW_SIGN_DATE ), + TOKEN( "signatureline", XML_SIGNATURELINE ), + TOKEN( "signing-instructions", XML_SIGNING_INSTRUCTIONS ), + TOKEN( "single", XML_SINGLE ), + TOKEN( "small-wave", XML_SMALL_WAVE ), + TOKEN( "suggested-signer-email", XML_SUGGESTED_SIGNER_EMAIL ), + TOKEN( "suggested-signer-name", XML_SUGGESTED_SIGNER_NAME ), + TOKEN( "suggested-signer-title", XML_SUGGESTED_SIGNER_TITLE ), + TOKEN( "wave", XML_WAVE ), + TOKEN( "unformatted-text", XML_UNFORMATTED_TEXT ), + TOKEN( "union", XML_UNION ), + TOKEN( "unit", XML_UNIT ), + TOKEN( "unordered-list", XML_UNORDERED_LIST ), + TOKEN( "unpublished", XML_UNPUBLISHED ), + TOKEN( "up", XML_UP ), + TOKEN( "uplimit", XML_UPLIMIT ), + TOKEN( "upright", XML_UPRIGHT ), + TOKEN( "url", XML_URL ), + TOKEN( "use", XML_USE ), + TOKEN( "use-caption", XML_USE_CAPTION ), + TOKEN( "use-cell-protection", XML_USE_CELL_PROTECTION ), + TOKEN( "use-chart-objects", XML_USE_CHART_OBJECTS ), + TOKEN( "use-condition", XML_USE_CONDITION ), + TOKEN( "use-draw-objects", XML_USE_DRAW_OBJECTS ), + TOKEN( "use-floating-frames", XML_USE_FLOATING_FRAMES ), + TOKEN( "use-graphics", XML_USE_GRAPHICS ), + TOKEN( "use-image-objects", XML_USE_IMAGE_OBJECTS ), + TOKEN( "use-index-marks", XML_USE_INDEX_MARKS ), + TOKEN( "use-index-source-styles", XML_USE_INDEX_SOURCE_STYLES ), + TOKEN( "use-keys-as-entries", XML_USE_KEYS_AS_ENTRIES ), + TOKEN( "use-label", XML_USE_LABEL ), + TOKEN( "use-math-objects", XML_USE_MATH_OBJECTS ), + TOKEN( "use-objects", XML_USE_OBJECTS ), + TOKEN( "use-optimal-column-width", XML_USE_OPTIMAL_COLUMN_WIDTH ), + TOKEN( "use-optimal-row-height", XML_USE_OPTIMAL_ROW_HEIGHT ), + TOKEN( "use-other-objects", XML_USE_OTHER_OBJECTS ), + TOKEN( "use-spreadsheet-objects", XML_USE_SPREADSHEET_OBJECTS ), + TOKEN( "use-styles", XML_USE_STYLES ), + TOKEN( "use-tables", XML_USE_TABLES ), + TOKEN( "use-window-font-color", XML_USE_WINDOW_FONT_COLOR ), + TOKEN( "used-hierarchy", XML_USED_HIERARCHY ), + TOKEN( "user-defined", XML_USER_DEFINED ), + TOKEN( "user-field-decl", XML_USER_FIELD_DECL ), + TOKEN( "user-field-decls", XML_USER_FIELD_DECLS ), + TOKEN( "user-field-get", XML_USER_FIELD_GET ), + TOKEN( "user-field-input", XML_USER_FIELD_INPUT ), + TOKEN( "user-index", XML_USER_INDEX ), + TOKEN( "user-index-entry-template", XML_USER_INDEX_ENTRY_TEMPLATE ), + TOKEN( "user-index-mark", XML_USER_INDEX_MARK ), + TOKEN( "user-index-mark-end", XML_USER_INDEX_MARK_END ), + TOKEN( "user-index-mark-start", XML_USER_INDEX_MARK_START ), + TOKEN( "user-index-source", XML_USER_INDEX_SOURCE ), + TOKEN( "user-transformed", XML_USER_TRANSFORMED ), + TOKEN( "username", XML_USERNAME ), + TOKEN( "value", XML_VALUE ), + TOKEN( "value-type", XML_VALUE_TYPE ), + TOKEN( "values-cell-range-address", XML_VALUES_CELL_RANGE_ADDRESS ), + TOKEN( "var", XML_VAR ), + TOKEN( "variable", XML_VARIABLE ), + TOKEN( "variable-decl", XML_VARIABLE_DECL ), + TOKEN( "variable-decls", XML_VARIABLE_DECLS ), + TOKEN( "variable-get", XML_VARIABLE_GET ), + TOKEN( "variable-input", XML_VARIABLE_INPUT ), + TOKEN( "variable-set", XML_VARIABLE_SET ), + TOKEN( "variance", XML_VARIANCE ), + TOKEN( "varp", XML_VARP ), + TOKEN( "vector", XML_VECTOR ), + TOKEN( "verb", XML_VERB ), + TOKEN( "version", XML_VERSION ), + TOKEN( "version-entry", XML_VERSION_ENTRY ), + TOKEN( "version-list", XML_VERSION_LIST ), + TOKEN( "vertical", XML_VERTICAL ), + TOKEN( "vertical-align", XML_VERTICAL_ALIGN ), + TOKEN( "vertical-justify", XML_VERTICAL_JUSTIFY ), + TOKEN( "vertical-lines", XML_VERTICAL_LINES ), + TOKEN( "vertical-pos", XML_VERTICAL_POS ), + TOKEN( "vertical-rel", XML_VERTICAL_REL ), + TOKEN( "vertical-segments", XML_VERTICAL_SEGMENTS ), + TOKEN( "vertical-split-mode", XML_VERTICAL_SPLIT_MODE ), + TOKEN( "vertical-split-position", XML_VERTICAL_SPLIT_POSITION ), + TOKEN( "vertical-stripes", XML_VERTICAL_STRIPES ), + TOKEN( "view", XML_VIEW ), + TOKEN( "viewBox", XML_VIEWBOX ), + TOKEN( "view-id", XML_VIEW_ID ), + TOKEN( "view-settings", XML_VIEW_SETTINGS ), + TOKEN( "visibility", XML_VISIBILITY ), + TOKEN( "visible", XML_VISIBLE ), + TOKEN( "visible-area", XML_VISIBLE_AREA ), + TOKEN( "visible-area-height", XML_VISIBLE_AREA_HEIGHT ), + TOKEN( "visible-area-left", XML_VISIBLE_AREA_LEFT ), + TOKEN( "visible-area-top", XML_VISIBLE_AREA_TOP ), + TOKEN( "visible-area-width", XML_VISIBLE_AREA_WIDTH ), + TOKEN( "visited-style-name", XML_VISITED_STYLE_NAME ), + TOKEN( "volatile", XML_VOLATILE ), + TOKEN( "volume", XML_VOLUME ), + TOKEN( "vpn", XML_VPN ), + TOKEN( "vrp", XML_VRP ), + TOKEN( "vup", XML_VUP ), + TOKEN( "wall", XML_WALL ), + TOKEN( "warning", XML_WARNING ), + TOKEN( "watermark", XML_WATERMARK ), + TOKEN( "wavyline", XML_WAVYLINE ), + TOKEN( "wavyline-from-bottom", XML_WAVYLINE_FROM_BOTTOM ), + TOKEN( "wavyline-from-left", XML_WAVYLINE_FROM_LEFT ), + TOKEN( "wavyline-from-right", XML_WAVYLINE_FROM_RIGHT ), + TOKEN( "wavyline-from-top", XML_WAVYLINE_FROM_TOP ), + TOKEN( "week-of-year", XML_WEEK_OF_YEAR ), + TOKEN( "white", XML_WHITE ), + TOKEN( "whole-page", XML_WHOLE_PAGE ), + TOKEN( "widows", XML_WIDOWS ), + TOKEN( "width", XML_WIDTH ), + TOKEN( "word", XML_WORD ), + TOKEN( "word-count", XML_WORD_COUNT ), + TOKEN( "wrap", XML_WRAP ), + TOKEN( "wrap-contour", XML_WRAP_CONTOUR ), + TOKEN( "wrap-contour-mode", XML_WRAP_CONTOUR_MODE ), + TOKEN( "wrap-option", XML_WRAP_OPTION ), + TOKEN( "writing-mode", XML_WRITING_MODE ), + TOKEN( "www", XML_WWW ), + TOKEN( "x", XML_X ), + TOKEN( "x1", XML_X1 ), + TOKEN( "x2", XML_X2 ), + TOKEN( "x-mac-roman", XML_X_MAC_ROMAN ), + TOKEN( "x-symbol", XML_X_SYMBOL ), + TOKEN( "x-system", XML_X_SYSTEM ), + TOKEN( "xor", XML_XOR ), + TOKEN( "y", XML_Y ), + TOKEN( "y1", XML_Y1 ), + TOKEN( "y2", XML_Y2 ), + TOKEN( "year", XML_YEAR ), + TOKEN( "yellow", XML_YELLOW ), + TOKEN( "zero-values", XML_ZERO_VALUES ), + TOKEN( "z-index", XML_ZINDEX ), + TOKEN( "zoom-type", XML_ZOOM_TYPE ), + TOKEN( "zoom-value", XML_ZOOM_VALUE ), + + TOKEN( "enable", XML_ENABLE ), + TOKEN( "use-regular-expressions", XML_USE_REGULAR_EXPRESSIONS ), + TOKEN( "use-wildcards", XML_USE_WILDCARDS ), + TOKEN( "data-source-has-labels", XML_DATA_SOURCE_HAS_LABELS ), + TOKEN( "link-data-style-to-source", XML_LINK_DATA_STYLE_TO_SOURCE ), + TOKEN( "sort-algorithm", XML_SORT_ALGORITHM ), + TOKEN( "straight-line", XML_STRAIGHT_LINE ), + TOKEN( "angled-line", XML_ANGLED_LINE ), + TOKEN( "angled-connector-line", XML_ANGLED_CONNECTOR_LINE ), + + TOKEN( "application/x-www-form-urlencoded", XML_APPLICATION_X_WWW_FORM_URLENCODED ), + TOKEN( "multipart/formdata", XML_MULTIPART_FORMDATA ), + TOKEN( "application/text", XML_APPLICATION_TEXT ), + TOKEN( "get", XML_GET ), + TOKEN( "post", XML_POST ), + TOKEN( "query", XML_QUERY ), + TOKEN( "parent", XML_PARENT ), + TOKEN( "records", XML_RECORDS ), + TOKEN( "push", XML_PUSH ), + TOKEN( "submit", XML_SUBMIT ), + TOKEN( "reset", XML_RESET ), + TOKEN( "value-list", XML_VALUE_LIST ), + TOKEN( "sql", XML_SQL ), + TOKEN( "sql-pass-through", XML_SQL_PASS_THROUGH ), + TOKEN( "table-fields", XML_TABLE_FIELDS ), + TOKEN( "unchecked", XML_UNCHECKED ), + TOKEN( "checked", XML_CHECKED ), + TOKEN( "unknown", XML_UNKNOWN ), + + TOKEN( "roll-from-top", XML_ROLL_FROM_TOP ), + + TOKEN( "binary-data", XML_BINARY_DATA ), + TOKEN( "notify-on-update-of-table", XML_NOTIFY_ON_UPDATE_OF_TABLE ), + + TOKEN( "0", XML_0 ), + TOKEN( "play", XML_PLAY ), + TOKEN( "handout-master", XML_HANDOUT_MASTER ), + TOKEN( "text-style-name", XML_TEXT_STYLE_NAME ), + TOKEN( "escape-direction", XML_ESCAPE_DIRECTION ), + TOKEN( "glue-point", XML_GLUE_POINT ), + TOKEN( "primary-x", XML_PRIMARY_X ), + TOKEN( "secondary-x", XML_SECONDARY_X ), + TOKEN( "primary-y", XML_PRIMARY_Y ), + TOKEN( "secondary-y", XML_SECONDARY_Y ), + TOKEN( "primary-z", XML_PRIMARY_Z ), + + TOKEN( "caption-type", XML_CAPTION_TYPE ), + TOKEN( "caption-angle-type", XML_CAPTION_ANGLE_TYPE ), + TOKEN( "caption-angle", XML_CAPTION_ANGLE ), + TOKEN( "caption-gap", XML_CAPTION_GAP ), + TOKEN( "caption-escape-direction", XML_CAPTION_ESCAPE_DIRECTION ), + TOKEN( "caption-escape", XML_CAPTION_ESCAPE ), + TOKEN( "caption-line-length", XML_CAPTION_LINE_LENGTH ), + TOKEN( "caption-fit-line-length", XML_CAPTION_FIT_LINE_LENGTH ), + TOKEN( "free", XML_FREE ), + TOKEN( "transition-type", XML_TRANSITION_TYPE ), + TOKEN( "transition-style", XML_TRANSITION_STYLE ), + TOKEN( "transition-speed", XML_TRANSITION_SPEED ), + TOKEN( "duration", XML_DURATION ), + TOKEN( "background-size", XML_BACKGROUND_SIZE ), + TOKEN( "background-objects-visible", XML_BACKGROUND_OBJECTS_VISIBLE ), + TOKEN( "background-visible", XML_BACKGROUND_VISIBLE ), + + TOKEN( "move-from-upperleft", XML_MOVE_FROM_UPPERLEFT ), + TOKEN( "move-from-upperright", XML_MOVE_FROM_UPPERRIGHT ), + TOKEN( "move-from-lowerright", XML_MOVE_FROM_LOWERRIGHT ), + TOKEN( "move-from-lowerleft", XML_MOVE_FROM_LOWERLEFT ), + TOKEN( "uncover-to-left", XML_UNCOVER_TO_LEFT ), + TOKEN( "uncover-to-upperleft", XML_UNCOVER_TO_UPPERLEFT ), + TOKEN( "uncover-to-top", XML_UNCOVER_TO_TOP ), + TOKEN( "uncover-to-upperright", XML_UNCOVER_TO_UPPERRIGHT ), + TOKEN( "uncover-to-right", XML_UNCOVER_TO_RIGHT ), + TOKEN( "uncover-to-lowerright", XML_UNCOVER_TO_LOWERRIGHT ), + TOKEN( "uncover-to-bottom", XML_UNCOVER_TO_BOTTOM ), + TOKEN( "uncover-to-lowerleft", XML_UNCOVER_TO_LOWERLEFT ), + TOKEN( "vertical-checkerboard", XML_VERTICAL_CHECKERBOARD ), + TOKEN( "horizontal-checkerboard", XML_HORIZONTAL_CHECKERBOARD ), + + TOKEN( "notify-on-update-of-ranges", XML_NOTIFY_ON_UPDATE_OF_RANGES ), + + TOKEN( "byte", XML_BYTE ), + TOKEN( "macro", XML_MACRO ), + TOKEN( "location", XML_LOCATION ), + TOKEN( "application", XML_APPLICATION ), + + TOKEN( "symbol-image", XML_SYMBOL_IMAGE ), + TOKEN( "text-overlap", XML_TEXT_OVERLAP ), + TOKEN( "spline-order", XML_SPLINE_ORDER ), + TOKEN( "spline-resolution", XML_SPLINE_RESOLUTION ), + TOKEN( "paper-tray-name", XML_PAPER_TRAY_NAME ), + + TOKEN( "column-mapping", XML_COLUMN_MAPPING ), + TOKEN( "row-mapping", XML_ROW_MAPPING ), + + TOKEN( "table-formula", XML_TABLE_FORMULA ), + + TOKEN( "embedded-text", XML_EMBEDDED_TEXT ), + + TOKEN( "merge-last-paragraph", XML_MERGE_LAST_PARAGRAPH ), + + TOKEN( "stock-loss-marker", XML_STOCK_LOSS_MARKER ), + TOKEN( "stock-gain-marker", XML_STOCK_GAIN_MARKER ), + TOKEN( "stock-range-line", XML_STOCK_RANGE_LINE ), + + TOKEN( "rl-tb", XML_RL_TB ), + TOKEN( "tb-lr", XML_TB_LR ), + TOKEN( "bt-lr", XML_BT_LR ), + TOKEN( "lr", XML_LR ), + TOKEN( "rl", XML_RL ), + TOKEN( "tb", XML_TB ), + + TOKEN( "layout-grid-color", XML_LAYOUT_GRID_COLOR ), + TOKEN( "layout-grid-lines", XML_LAYOUT_GRID_LINES ), + TOKEN( "layout-grid-base-height", XML_LAYOUT_GRID_BASE_HEIGHT ), + TOKEN( "layout-grid-ruby-height", XML_LAYOUT_GRID_RUBY_HEIGHT ), + TOKEN( "layout-grid-mode", XML_LAYOUT_GRID_MODE ), + TOKEN( "layout-grid-ruby-below", XML_LAYOUT_GRID_RUBY_BELOW ), + TOKEN( "layout-grid-print", XML_LAYOUT_GRID_PRINT ), + TOKEN( "layout-grid-display", XML_LAYOUT_GRID_DISPLAY ), + + //text grid enhancement for better CJK support + TOKEN( "default-page-layout", XML_DEFAULT_PAGE_LAYOUT ), + TOKEN( "layout-grid-standard-mode", XML_LAYOUT_GRID_STANDARD_MODE ), + TOKEN( "layout-grid-base-width", XML_LAYOUT_GRID_BASE_WIDTH ), + TOKEN( "layout-grid-snap-to-characters", XML_LAYOUT_GRID_SNAP_TO_CHARS ), + TOKEN( "layout-grid-snap-to", XML_LAYOUT_GRID_SNAP_TO ), + + TOKEN( "snap-to-layout-grid", XML_SNAP_TO_LAYOUT_GRID ), + + TOKEN( "dont-balance-text-columns", XML_DONT_BALANCE_TEXT_COLUMNS ), + + TOKEN( "glyph-orientation-vertical", XML_GLYPH_ORIENTATION_VERTICAL ), + + TOKEN( "marked-invalid", XML_MARKED_INVALID ), + + // Regression curve & properties + TOKEN( "regression-curve", XML_REGRESSION_CURVE ), + TOKEN( "regression-type", XML_REGRESSION_TYPE ), + // Extended regression curve properties - ODF 1.2 extended + TOKEN( "regression-name", XML_REGRESSION_CURVE_NAME ), + TOKEN( "regression-extrapolate-forward", XML_REGRESSION_EXTRAPOLATE_FORWARD ), + TOKEN( "regression-extrapolate-backward", XML_REGRESSION_EXTRAPOLATE_BACKWARD ), + TOKEN( "regression-max-degree", XML_REGRESSION_MAX_DEGREE ), + TOKEN( "regression-min-degree", XML_REGRESSION_MIN_DEGREE ), + TOKEN( "regression-moving-type", XML_REGRESSION_MOVING_TYPE ), + TOKEN( "regression-period", XML_REGRESSION_PERIOD ), + TOKEN( "regression-force-intercept", XML_REGRESSION_FORCE_INTERCEPT ), + TOKEN( "regression-intercept-value", XML_REGRESSION_INTERCEPT_VALUE ), + TOKEN( "regression-x-name", XML_REGRESSION_X_NAME ), + TOKEN( "regression-y-name", XML_REGRESSION_Y_NAME ), + + TOKEN( "error-indicator", XML_ERROR_INDICATOR ), + + TOKEN( "table-type", XML_TABLE_TYPE ), + + TOKEN( "display-factor", XML_DISPLAY_FACTOR ), + + TOKEN( "transliteration-format", XML_TRANSLITERATION_FORMAT ), + TOKEN( "transliteration-language", XML_TRANSLITERATION_LANGUAGE ), + TOKEN( "transliteration-country", XML_TRANSLITERATION_COUNTRY ), + TOKEN( "transliteration-style", XML_TRANSLITERATION_STYLE ), + + TOKEN( "key1-phonetic", XML_KEY1_PHONETIC ), + TOKEN( "key2-phonetic", XML_KEY2_PHONETIC ), + TOKEN( "string-value-phonetic", XML_STRING_VALUE_PHONETIC ), + + TOKEN( "background-transparency", XML_BACKGROUND_TRANSPARENCY ), + TOKEN( "background-image-transparency", XML_BACKGROUND_IMAGE_TRANSPARENCY ), + + TOKEN( "dynamic-spacing", XML_DYNAMIC_SPACING ), + + TOKEN( "main-entry", XML_MAIN_ENTRY ), + + TOKEN( "use-outline-level", XML_USE_OUTLINE_LEVEL ), + + // #107245# New 3D properties which are possible for lathe and extrude 3d objects + TOKEN( "close-front", XML_CLOSE_FRONT ), + TOKEN( "close-back", XML_CLOSE_BACK ), + + TOKEN( "drop-down", XML_DROP_DOWN ), + TOKEN( "current-selected", XML_CURRENT_SELECTED ), + + TOKEN( "join-border", XML_JOIN_BORDER ), + + TOKEN( "display-list", XML_DISPLAY_LIST ), + TOKEN( "no", XML_NO ), + TOKEN( "unsorted", XML_UNSORTED ), + TOKEN( "font-independent-line-spacing", XML_FONT_INDEPENDENT_LINE_SPACING ), + + // Wrong! Do not write, use XML_SORT_ASCENDING instead. Only read. fdo#72548 + TOKEN( "sorted-ascending", XML_SORTED_ASCENDING ), + + TOKEN( "database", XML_DATABASE ), + TOKEN( "data-source", XML_DATASOURCE ), + TOKEN( "queries", XML_QUERIES ), + TOKEN( "reports", XML_REPORTS ), + TOKEN( "report", XML_REPORT ), + TOKEN( "as-template", XML_AS_TEMPLATE ), + + TOKEN( "connection-resource", XML_CONNECTION_RESOURCE ), + TOKEN( "suppress-version-columns", XML_SUPPRESS_VERSION_COLUMNS ), + TOKEN( "java-driver-class", XML_JAVA_DRIVER_CLASS ), + TOKEN( "extension", XML_EXTENSION ), + TOKEN( "is-first-row-header-line", XML_IS_FIRST_ROW_HEADER_LINE ), + TOKEN( "show-deleted", XML_SHOW_DELETED ), + TOKEN( "is-table-name-length-limited", XML_IS_TABLE_NAME_LENGTH_LIMITED ), + TOKEN( "system-driver-settings", XML_SYSTEM_DRIVER_SETTINGS ), + TOKEN( "enable-sql92-check", XML_ENABLE_SQL92_CHECK ), + TOKEN( "append-table-alias-name", XML_APPEND_TABLE_ALIAS_NAME ), + TOKEN( "parameter-name-substitution", XML_PARAMETER_NAME_SUBSTITUTION ), + TOKEN( "ignore-driver-privileges", XML_IGNORE_DRIVER_PRIVILEGES ), + TOKEN( "boolean-comparison-mode", XML_BOOLEAN_COMPARISON_MODE ), + TOKEN( "use-catalog", XML_USE_CATALOG ), + TOKEN( "base-dn", XML_BASE_DN ), + TOKEN( "max-row-count", XML_MAX_ROW_COUNT ), + TOKEN( "login", XML_LOGIN ), + TOKEN( "user-name", XML_USER_NAME ), + TOKEN( "is-password-required", XML_IS_PASSWORD_REQUIRED ), + TOKEN( "login-timeout", XML_LOGIN_TIMEOUT ), + TOKEN( "delimiter", XML_DELIMITER ), + TOKEN( "field", XML_FIELD ), + TOKEN( "decimal", XML_DECIMAL ), + TOKEN( "thousand", XML_THOUSAND ), + TOKEN( "table-filter", XML_TABLE_FILTER ), + TOKEN( "table-filter-pattern", XML_TABLE_FILTER_PATTERN ), + TOKEN( "table-type-filter", XML_TABLE_TYPE_FILTER ), + TOKEN( "auto-increment", XML_AUTO_INCREMENT ), + TOKEN( "additional-column-statement", XML_ADDITIONAL_COLUMN_STATEMENT ), + TOKEN( "row-retrieving-statement", XML_ROW_RETRIEVING_STATEMENT ), + TOKEN( "data-source-settings", XML_DATA_SOURCE_SETTINGS ), + TOKEN( "data-source-setting", XML_DATA_SOURCE_SETTING ), + TOKEN( "data-source-setting-value", XML_DATA_SOURCE_SETTING_VALUE ), + TOKEN( "data-source-setting-is-list", XML_DATA_SOURCE_SETTING_IS_LIST ), + TOKEN( "data-source-setting-type", XML_DATA_SOURCE_SETTING_TYPE ), + TOKEN( "data-source-setting-name", XML_DATA_SOURCE_SETTING_NAME ), + TOKEN( "component", XML_COMPONENT ), + TOKEN( "component-collection", XML_COMPONENT_COLLECTION ), + TOKEN( "query-collection", XML_QUERY_COLLECTION ), + TOKEN( "update-table", XML_UPDATE_TABLE ), + TOKEN( "filter-statement", XML_FILTER_STATEMENT ), + TOKEN( "order-statement", XML_ORDER_STATEMENT ), + TOKEN( "escape-processing", XML_ESCAPE_PROCESSING ), + TOKEN( "keys", XML_KEYS ), + TOKEN( "indices", XML_INDICES ), + TOKEN( "type-name", XML_TYPE_NAME ), + TOKEN( "precision", XML_PRECISION ), + TOKEN( "is-nullable", XML_IS_NULLABLE ), + TOKEN( "is-autoincrement", XML_IS_AUTOINCREMENT ), + TOKEN( "default-value", XML_DEFAULT_VALUE ), + TOKEN( "referenced-table-name", XML_REFERENCED_TABLE_NAME ), + TOKEN( "update-rule", XML_UPDATE_RULE ), + TOKEN( "delete-rule", XML_DELETE_RULE ), + TOKEN( "key-columns", XML_KEY_COLUMNS ), + TOKEN( "key-column", XML_KEY_COLUMN ), + TOKEN( "related-column-name", XML_RELATED_COLUMN_NAME ), + TOKEN( "catalog-name", XML_CATALOG_NAME ), + TOKEN( "is-unique", XML_IS_UNIQUE ), + TOKEN( "is-clustered", XML_IS_CLUSTERED ), + TOKEN( "index-columns", XML_INDEX_COLUMNS ), + TOKEN( "index-column", XML_INDEX_COLUMN ), + TOKEN( "is-ascending", XML_IS_ASCENDING ), + TOKEN( "schema-name", XML_SCHEMA_NAME ), + TOKEN( "db", XML_NP_DB ), + TOKEN( "http://openoffice.org/2004/database", XML_N_DB ), + TOKEN( "apply-filter", XML_APPLY_FILTER ), + TOKEN( "apply-order", XML_APPLY_ORDER ), + TOKEN( "automatic-print-range", XML_AUTOMATIC_PRINT_RANGE ), + + TOKEN( "selection", XML_SELECTION ), + TOKEN( "selection-indexes", XML_SELECTION_INDEXES ), + + TOKEN( "scale-to-X", XML_SCALE_TO_X ), + TOKEN( "scale-to-Y", XML_SCALE_TO_Y ), + + TOKEN( "keep-together", XML_KEEP_TOGETHER ), + + TOKEN( "use-header-name", XML_USE_HEADER_NAME ), + TOKEN( "use-footer-name", XML_USE_FOOTER_NAME ), + TOKEN( "use-date-time-name", XML_USE_DATE_TIME_NAME ), + TOKEN( "display-header", XML_DISPLAY_HEADER ), + TOKEN( "display-footer", XML_DISPLAY_FOOTER ), + TOKEN( "display-page-number", XML_DISPLAY_PAGE_NUMBER ), + TOKEN( "display-date-time", XML_DISPLAY_DATE_TIME ), + TOKEN( "source" , XML_SOURCE ), + TOKEN( "current-date", XML_CURRENT_DATE ), + + TOKEN( "header-decl", XML_HEADER_DECL ), + TOKEN( "footer-decl", XML_FOOTER_DECL ), + TOKEN( "date-time-decl", XML_DATE_TIME_DECL ), + + TOKEN( "selected-page", XML_SELECTED_PAGE ), + + // DVO, OD 01.10.2003 #i18732# + TOKEN( "flow-with-text", XML_FLOW_WITH_TEXT ), + TOKEN( "with-tab", XML_WITH_TAB ), // #i21237# + + TOKEN( "custom-shape" , XML_CUSTOM_SHAPE ), + TOKEN( "engine" , XML_ENGINE ), + TOKEN( "enhanced-geometry" , XML_ENHANCED_GEOMETRY ), + TOKEN( "text-rotate-angle" , XML_TEXT_ROTATE_ANGLE ), + TOKEN( "mirror-vertical" , XML_MIRROR_VERTICAL ), + TOKEN( "mirror-horizontal" , XML_MIRROR_HORIZONTAL ), + TOKEN( "extrusion-allowed" , XML_EXTRUSION_ALLOWED ), + TOKEN( "text-path-allowed" , XML_TEXT_PATH_ALLOWED ), + TOKEN( "concentric-gradient-fill-allowed" , XML_CONCENTRIC_GRADIENT_FILL_ALLOWED ), + TOKEN( "extrusion" , XML_EXTRUSION ), + TOKEN( "extrusion-brightness" , XML_EXTRUSION_BRIGHTNESS ), + TOKEN( "extrusion-depth" , XML_EXTRUSION_DEPTH ), + TOKEN( "extrusion-diffusion" , XML_EXTRUSION_DIFFUSION ), + TOKEN( "extrusion-number-of-line-segments" , XML_EXTRUSION_NUMBER_OF_LINE_SEGMENTS ), + TOKEN( "extrusion-light-face" , XML_EXTRUSION_LIGHT_FACE ), + TOKEN( "extrusion-first-light-harsh" , XML_EXTRUSION_FIRST_LIGHT_HARSH ), + TOKEN( "extrusion-second-light-harsh" , XML_EXTRUSION_SECOND_LIGHT_HARSH ), + TOKEN( "extrusion-first-light-level" , XML_EXTRUSION_FIRST_LIGHT_LEVEL ), + TOKEN( "extrusion-second-light-level" , XML_EXTRUSION_SECOND_LIGHT_LEVEL ), + TOKEN( "extrusion-first-light-direction" , XML_EXTRUSION_FIRST_LIGHT_DIRECTION ), + TOKEN( "extrusion-second-light-direction" , XML_EXTRUSION_SECOND_LIGHT_DIRECTION ), + TOKEN( "extrusion-metal" , XML_EXTRUSION_METAL ), + TOKEN( "extrusion-rotation-angle" , XML_EXTRUSION_ROTATION_ANGLE ), + TOKEN( "extrusion-rotation-center" , XML_EXTRUSION_ROTATION_CENTER ), + TOKEN( "extrusion-shininess" , XML_EXTRUSION_SHININESS ), + TOKEN( "extrusion-skew" , XML_EXTRUSION_SKEW ), + TOKEN( "extrusion-specularity" , XML_EXTRUSION_SPECULARITY ), + TOKEN( "extrusion-projection-mode" , XML_EXTRUSION_PROJECTION_MODE ), + TOKEN( "extrusion-viewpoint" , XML_EXTRUSION_VIEWPOINT ), + TOKEN( "extrusion-origin" , XML_EXTRUSION_ORIGIN ), + TOKEN( "extrusion-color" , XML_EXTRUSION_COLOR ), + TOKEN( "secondary-fill-color" , XML_SECONDARY_FILL_COLOR ), + TOKEN( "enhanced-path" , XML_ENHANCED_PATH ), + TOKEN( "path-stretchpoint-x" , XML_PATH_STRETCHPOINT_X ), + TOKEN( "path-stretchpoint-y" , XML_PATH_STRETCHPOINT_Y ), + TOKEN( "text-areas" , XML_TEXT_AREAS ), + TOKEN( "glue-points" , XML_GLUE_POINTS ), + TOKEN( "glue-point-type" , XML_GLUE_POINT_TYPE ), + TOKEN( "glue-point-leaving-direction" , XML_GLUE_POINT_LEAVING_DIRECTIONS ), + TOKEN( "text-path" , XML_TEXT_PATH ), + TOKEN( "text-path-mode" , XML_TEXT_PATH_MODE ), + TOKEN( "text-path-scale" , XML_TEXT_PATH_SCALE ), + TOKEN( "text-path-same-letter-heights" , XML_TEXT_PATH_SAME_LETTER_HEIGHTS ), + TOKEN( "modifiers" , XML_MODIFIERS ), + TOKEN( "equation" , XML_EQUATION ), + TOKEN( "xstretch", XML_XSTRETCH ), + TOKEN( "ystretch", XML_YSTRETCH ), + TOKEN( "hasstroke", XML_HASSTROKE ), + TOKEN( "hasfill", XML_HASFILL ), + TOKEN( "logwidth", XML_LOGWIDTH ), + TOKEN( "logheight", XML_LOGHEIGHT ), + TOKEN( "handle" , XML_HANDLE ), + TOKEN( "handle-mirror-vertical" , XML_HANDLE_MIRROR_VERTICAL ), + TOKEN( "handle-mirror-horizontal" , XML_HANDLE_MIRROR_HORIZONTAL ), + TOKEN( "handle-switched" , XML_HANDLE_SWITCHED ), + TOKEN( "handle-position" , XML_HANDLE_POSITION ), + TOKEN( "handle-range-x-minimum" , XML_HANDLE_RANGE_X_MINIMUM ), + TOKEN( "handle-range-x-maximum" , XML_HANDLE_RANGE_X_MAXIMUM ), + TOKEN( "handle-range-y-minimum" , XML_HANDLE_RANGE_Y_MINIMUM ), + TOKEN( "handle-range-y-maximum" , XML_HANDLE_RANGE_Y_MAXIMUM ), + TOKEN( "handle-polar" , XML_HANDLE_POLAR ), + TOKEN( "handle-radius-range-minimum" , XML_HANDLE_RADIUS_RANGE_MINIMUM ), + TOKEN( "handle-radius-range-maximum" , XML_HANDLE_RADIUS_RANGE_MAXIMUM ), + TOKEN( "rectangle" , XML_RECTANGLE ), + TOKEN( "roundrectangle" , XML_ROUNDRECTANGLE ), + TOKEN( "oval" , XML_OVAL ), + TOKEN( "cloud" , XML_CLOUD ), + TOKEN( "boundingcube" , XML_BOUNDINGCUBE ), + TOKEN( "wireframe" , XML_WIREFRAME ), + TOKEN( "segments" , XML_SEGMENTS ), + TOKEN( "word-wrap" , XML_WORD_WRAP ), + TOKEN( "collapsing" , XML_COLLAPSING ), + TOKEN( "separating" , XML_SEPARATING ), + TOKEN( "border-model" , XML_BORDER_MODEL ), + TOKEN( "data-pilot-field-reference", XML_DATA_PILOT_FIELD_REFERENCE ), + TOKEN( "member-difference", XML_MEMBER_DIFFERENCE ), + TOKEN( "member-percentage", XML_MEMBER_PERCENTAGE ), + TOKEN( "member-percentage-difference", XML_MEMBER_PERCENTAGE_DIFFERENCE ), + TOKEN( "running-total", XML_RUNNING_TOTAL ), + TOKEN( "row-percentage", XML_ROW_PERCENTAGE ), + TOKEN( "column-percentage", XML_COLUMN_PERCENTAGE ), + TOKEN( "total-percentage", XML_TOTAL_PERCENTAGE ), + TOKEN( "field-name", XML_FIELD_NAME ), + TOKEN( "member-type", XML_MEMBER_TYPE ), + TOKEN( "named", XML_NAMED ), + TOKEN( "member-name", XML_MEMBER_NAME ), + TOKEN( "display-member-mode", XML_DISPLAY_MEMBER_MODE ), + TOKEN( "member-count", XML_MEMBER_COUNT ), + TOKEN( "data-field", XML_DATA_FIELD ), + TOKEN( "data-pilot-display-info", XML_DATA_PILOT_DISPLAY_INFO ), + TOKEN( "sort-mode", XML_SORT_MODE ), + TOKEN( "data-pilot-sort-info", XML_DATA_PILOT_SORT_INFO ), + TOKEN( "add-empty-lines", XML_ADD_EMPTY_LINES ), + TOKEN( "tabular-layout", XML_TABULAR_LAYOUT ), + TOKEN( "outline-subtotals-top", XML_OUTLINE_SUBTOTALS_TOP ), + TOKEN( "outline-subtotals-bottom", XML_OUTLINE_SUBTOTALS_BOTTOM ), + TOKEN( "layout-mode", XML_LAYOUT_MODE ), + TOKEN( "data-pilot-layout-info", XML_DATA_PILOT_LAYOUT_INFO ), + TOKEN( "symbol-color", XML_SYMBOL_COLOR ), + TOKEN( "3d" , XML_3D ), + TOKEN( "image-position" , XML_IMAGE_POSITION ), + TOKEN( "image-align" , XML_IMAGE_ALIGN ), + TOKEN( "diagonal-bl-tr", XML_DIAGONAL_BL_TR ), + TOKEN( "diagonal-bl-tr-width", XML_DIAGONAL_BL_TR_WIDTH ), + TOKEN( "diagonal-tl-br", XML_DIAGONAL_TL_BR ), + TOKEN( "diagonal-tl-br-width", XML_DIAGONAL_TL_BR_WIDTH ), + TOKEN( "repeat-content", XML_REPEAT_CONTENT ), + TOKEN( "shrink-to-fit", XML_SHRINK_TO_FIT ), + + // OD 2004-05-05 #i28701# + TOKEN( "wrap-influence-on-position", XML_WRAP_INFLUENCE_ON_POSITION ), + // Tokens have been renamed and <XML_ITERATIVE> has been added (#i35017#) + TOKEN( "once-successive", XML_ONCE_SUCCESSIVE ), + TOKEN( "once-concurrent", XML_ONCE_CONCURRENT ), + TOKEN( "allow-overlap", XML_ALLOW_OVERLAP ), + + // Names for OOo format only + TOKEN( "http://openoffice.org/2000/office", XML_N_OFFICE_OOO ), + TOKEN( "http://openoffice.org/2000/meta", XML_N_META_OOO ), + TOKEN( "http://openoffice.org/2000/style", XML_N_STYLE_OOO ), + TOKEN( "http://openoffice.org/2000/datastyle", XML_N_NUMBER_OOO ), + TOKEN( "http://openoffice.org/2000/text", XML_N_TEXT_OOO ), + TOKEN( "http://openoffice.org/2000/table", XML_N_TABLE_OOO ), + TOKEN( "http://openoffice.org/2000/drawing", XML_N_DRAW_OOO ), + TOKEN( "http://openoffice.org/2000/dr3d", XML_N_DR3D_OOO ), + TOKEN( "http://openoffice.org/2000/presentation",XML_N_PRESENTATION_OOO ), + TOKEN( "urn:oasis:names:tc:openoffice:xmlns:presentation:1.0",XML_N_PRESENTATION_OASIS ), + TOKEN( "http://openoffice.org/2000/chart", XML_N_CHART_OOO ), + TOKEN( "http://openoffice.org/2001/config", XML_N_CONFIG_OOO ), + TOKEN( "http://openoffice.org/2000/form", XML_N_FORM_OOO ), + TOKEN( "http://openoffice.org/2000/script", XML_N_SCRIPT_OOO ), + + TOKEN( "global", XML_GLOBAL ), + + TOKEN( "note-class", XML_NOTE_CLASS ), + TOKEN( "note-citation", XML_NOTE_CITATION ), + TOKEN( "note-body", XML_NOTE_BODY ), + TOKEN( "notes-configuration", XML_NOTES_CONFIGURATION ), + TOKEN( "note-ref", XML_NOTE_REF ), + TOKEN( "is-sub-table", XML_IS_SUB_TABLE ), + TOKEN( "page-layout", XML_PAGE_LAYOUT ), + TOKEN( "page-layout-name", XML_PAGE_LAYOUT_NAME ), + TOKEN( "graphic-properties", XML_GRAPHIC_PROPERTIES ), + TOKEN( "drawing-page-properties", XML_DRAWING_PAGE_PROPERTIES ), + TOKEN( "page-layout-properties", XML_PAGE_LAYOUT_PROPERTIES ), + TOKEN( "header-footer-properties", XML_HEADER_FOOTER_PROPERTIES ), + TOKEN( "text-properties", XML_TEXT_PROPERTIES ), + TOKEN( "paragraph-properties", XML_PARAGRAPH_PROPERTIES ), + TOKEN( "ruby-properties", XML_RUBY_PROPERTIES ), + TOKEN( "section-properties", XML_SECTION_PROPERTIES ), + TOKEN( "table-properties", XML_TABLE_PROPERTIES ), + TOKEN( "table-column-properties", XML_TABLE_COLUMN_PROPERTIES ), + TOKEN( "table-row-properties", XML_TABLE_ROW_PROPERTIES ), + TOKEN( "table-cell-properties", XML_TABLE_CELL_PROPERTIES ), + TOKEN( "list-level-properties", XML_LIST_LEVEL_PROPERTIES ), + TOKEN( "chart-properties", XML_CHART_PROPERTIES ), + TOKEN( "drawing-page", XML_DRAWING_PAGE ), + TOKEN( "graphics", XML_GRAPHICS ), + TOKEN( "tab", XML_TAB ), + TOKEN( "text-underline-mode", XML_TEXT_UNDERLINE_MODE ), + TOKEN( "text-line-through-mode", XML_TEXT_LINE_THROUGH_MODE ), + TOKEN( "continuous", XML_CONTINUOUS ), + TOKEN( "skip-white-space", XML_SKIP_WHITE_SPACE ), + TOKEN( "scripts", XML_SCRIPTS ), + TOKEN( "font-face-decls", XML_FONT_FACE_DECLS ), + TOKEN( "font-face", XML_FONT_FACE ), + TOKEN( "font-face-src", XML_FONT_FACE_SRC ), + TOKEN( "font-face-uri", XML_FONT_FACE_URI ), + TOKEN( "font-face-format", XML_FONT_FACE_FORMAT ), + TOKEN( "font-adornments", XML_FONT_ADORNMENTS ), + TOKEN( "inch", XML_INCH ), + TOKEN( "space-after", XML_SPACE_AFTER ), + TOKEN( "start-indent", XML_START_INDENT ), + TOKEN( "end-indent", XML_END_INDENT ), + + // chart Oasis format additions + TOKEN( "interval-minor-divisor", XML_INTERVAL_MINOR_DIVISOR ), + TOKEN( "date-string", XML_DATE_STRING ), + + TOKEN( "text-underline-style", XML_TEXT_UNDERLINE_STYLE ), + TOKEN( "text-underline-type", XML_TEXT_UNDERLINE_TYPE ), + TOKEN( "text-underline-width", XML_TEXT_UNDERLINE_WIDTH ), + + TOKEN( "text-overline-type", XML_TEXT_OVERLINE_TYPE ), + TOKEN( "text-overline-style", XML_TEXT_OVERLINE_STYLE ), + TOKEN( "text-overline-width", XML_TEXT_OVERLINE_WIDTH ), + TOKEN( "text-overline-color", XML_TEXT_OVERLINE_COLOR ), + TOKEN( "text-overline-mode", XML_TEXT_OVERLINE_MODE ), + + TOKEN( "text-line-through-style", XML_TEXT_LINE_THROUGH_STYLE ), + TOKEN( "text-line-through-type", XML_TEXT_LINE_THROUGH_TYPE ), + TOKEN( "text-line-through-width", XML_TEXT_LINE_THROUGH_WIDTH ), + TOKEN( "text-line-through-text", XML_TEXT_LINE_THROUGH_TEXT ), + + TOKEN( "leader-style", XML_LEADER_STYLE ), + TOKEN( "leader-text", XML_LEADER_TEXT ), + + TOKEN( "bold-dotted", XML_BOLD_DOTTED ), + TOKEN( "bold-dash", XML_BOLD_DASH ), + TOKEN( "bold-long-dash", XML_BOLD_LONG_DASH ), + TOKEN( "bold-dot-dash", XML_BOLD_DOT_DASH ), + TOKEN( "bold-dot-dot-dash", XML_BOLD_DOT_DOT_DASH ), + TOKEN( "bold-wave", XML_BOLD_WAVE ), + TOKEN( "double-wave", XML_DOUBLE_WAVE ), + TOKEN( "double-line", XML_DOUBLE_LINE ), + TOKEN( "thick-line", XML_THICK_LINE ), + TOKEN( "single-line", XML_SINGLE_LINE ), + TOKEN( "slash", XML_SLASH ), + TOKEN( "text-line-through-color", XML_TEXT_LINE_THROUGH_COLOR ), + TOKEN( "text-line-through-text-style", XML_TEXT_LINE_THROUGH_TEXT_STYLE ), + TOKEN( "leader-color", XML_LEADER_COLOR ), + TOKEN( "leader-type", XML_LEADER_TYPE ), + TOKEN( "leader-width", XML_LEADER_WIDTH ), + TOKEN( "leader-text-style", XML_LEADER_TEXT_STYLE ), + + TOKEN( "opacity", XML_OPACITY ), + TOKEN( "opacity-name", XML_OPACITY_NAME ), + TOKEN( "shadow-opacity", XML_SHADOW_OPACITY ), + TOKEN( "always", XML_ALWAYS ), + TOKEN( "count-in-text-boxes", XML_COUNT_IN_TEXT_BOXES ), + + TOKEN( "ooo", XML_NP_OOO ), + TOKEN( "http://openoffice.org/2004/office", XML_N_OOO ), + TOKEN( "ooow", XML_NP_OOOW ), + TOKEN( "http://openoffice.org/2004/writer", XML_N_OOOW ), + TOKEN( "oooc", XML_NP_OOOC ), + TOKEN( "http://openoffice.org/2004/calc", XML_N_OOOC ), + TOKEN( "dom", XML_NP_DOM ), + TOKEN( "http://www.w3.org/2001/xml-events", XML_N_DOM ), + + TOKEN( "event-listeners", XML_EVENT_LISTENERS ), + TOKEN( "event-listener", XML_EVENT_LISTENER ), + + TOKEN( "form", XML_FORM ), + TOKEN( "void", XML_VOID ), + TOKEN( "property", XML_PROPERTY ), + TOKEN( "property-name", XML_PROPERTY_NAME ), + TOKEN( "list-property", XML_LIST_PROPERTY ), + TOKEN( "list-value", XML_LIST_VALUE ), + TOKEN( "column-style-name", XML_COLUMN_STYLE_NAME ), + TOKEN( "textarea", XML_TEXTAREA ), + TOKEN( "fixed-text", XML_FIXED_TEXT ), + TOKEN( "file", XML_FILE ), + TOKEN( "formatted-text", XML_FORMATTED_TEXT ), + TOKEN( "button", XML_BUTTON ), + TOKEN( "checkbox", XML_CHECKBOX ), + TOKEN( "radio", XML_RADIO ), + TOKEN( "listbox", XML_LISTBOX ), + TOKEN( "combobox", XML_COMBOBOX ), + TOKEN( "image-frame", XML_IMAGE_FRAME ), + TOKEN( "value-range", XML_VALUE_RANGE ), + TOKEN( "generic-control", XML_GENERIC_CONTROL ), + TOKEN( "service-name", XML_SERVICE_NAME ), + TOKEN( "property-type", XML_PROPERTY_TYPE ), + TOKEN( "integer", XML_INTEGER ), + TOKEN( "property-is-void", XML_PROPERTY_IS_VOID ), + TOKEN( "property-is-list", XML_PROPERTY_IS_LIST ), + TOKEN( "property-value", XML_PROPERTY_VALUE ), + TOKEN( "mimetype", XML_MIMETYPE ), + TOKEN( "database-row-select", XML_DATABASE_ROW_SELECT ), + TOKEN( "control-implementation", XML_CONTROL_IMPLEMENTATION ), + TOKEN( "interpolation", XML_INTERPOLATION ), + TOKEN( "cubic-spline", XML_CUBIC_SPLINE ), + TOKEN( "b-spline", XML_B_SPLINE ), + TOKEN( "step-start", XML_STEP_START ), + TOKEN( "step-end", XML_STEP_END ), + TOKEN( "step-center-x", XML_STEP_CENTER_X ), + TOKEN( "step-center-y", XML_STEP_CENTER_Y ), + // the gnm: values should only used for reading Gnumeric ods file + // these values should never be written + TOKEN( "gnm:step-start", XML_GNM_STEP_START ), + TOKEN( "gnm:step-end", XML_GNM_STEP_END ), + TOKEN( "gnm:step-center-x", XML_GNM_STEP_CENTER_X ), + TOKEN( "gnm:step-center-y", XML_GNM_STEP_CENTER_Y ), + TOKEN( "urn:oasis:names:tc:opendocument:xmlns:database:1.0", XML_N_DB_OASIS ), + + TOKEN( "show-filter-button", XML_SHOW_FILTER_BUTTON ), + TOKEN( "drill-down-on-double-click", XML_DRILL_DOWN_ON_DOUBLE_CLICK ), + TOKEN( "header-grid-layout", XML_HEADER_GRID_LAYOUT ), + TOKEN( "grouped-by", XML_GROUPED_BY ), + TOKEN( "days", XML_DAYS ), + TOKEN( "months", XML_MONTHS ), + TOKEN( "quarters", XML_QUARTERS ), + TOKEN( "years", XML_YEARS ), + TOKEN( "date-start", XML_DATE_START ), + TOKEN( "date-end", XML_DATE_END ), + TOKEN( "step", XML_STEP ), + TOKEN( "data-pilot-groups", XML_DATA_PILOT_GROUPS ), + TOKEN( "data-pilot-group", XML_DATA_PILOT_GROUP ), + TOKEN( "data-pilot-group-member", XML_DATA_PILOT_GROUP_MEMBER ), + TOKEN( "japanese-candle-stick", XML_JAPANESE_CANDLE_STICK ), + TOKEN( "named-symbol", XML_NAMED_SYMBOL ), + TOKEN( "diamond", XML_DIAMOND ), + TOKEN( "arrow-down", XML_ARROW_DOWN ), + TOKEN( "arrow-up", XML_ARROW_UP ), + TOKEN( "arrow-right", XML_ARROW_RIGHT ), + TOKEN( "arrow-left", XML_ARROW_LEFT ), + TOKEN( "bow-tie", XML_BOW_TIE ), + TOKEN( "hourglass", XML_HOURGLASS ), + TOKEN( "symbol-name", XML_SYMBOL_NAME ), + TOKEN( "symbol-type", XML_SYMBOL_TYPE ), + TOKEN( "image-opacity", XML_IMAGE_OPACITY ), // #i25616# + + TOKEN( "default-outline-level", XML_DEFAULT_OUTLINE_LEVEL ), + TOKEN( "show-details", XML_SHOW_DETAILS ), + TOKEN( "show-empty", XML_SHOW_EMPTY ), + TOKEN( "repeat-item-labels", XML_REPEAT_ITEM_LABELS ), + TOKEN( "iterative", XML_ITERATIVE ), + + TOKEN( "X", XML_uX ), + TOKEN( "dlg", XML_NP_DLG ), + TOKEN( "http://openoffice.org/2000/dialog", XML_N_DLG ), + TOKEN( "script-data", XML_SCRIPT_DATA ), + TOKEN( "libraries", XML_LIBRARIES ), + TOKEN( "source-code", XML_SOURCE_CODE ), + TOKEN( "readonly", XML_READONLY ), + TOKEN( "z", XML_Z ), + TOKEN( "dimension", XML_DIMENSION ), + TOKEN( "validation-name", XML_VALIDATION_NAME ), + + TOKEN( "screen", XML_SCREEN ), + TOKEN( "printer", XML_PRINTER ), + + // XForms token + TOKEN( "model", XML_MODEL ), + TOKEN( "schema", XML_SCHEMA ), + TOKEN( "bind", XML_BIND ), + TOKEN( "instance", XML_INSTANCE ), + TOKEN( "submission", XML_SUBMISSION ), + TOKEN( "ref", XML_REF ), + TOKEN( "src", XML_SRC ), + TOKEN( "method", XML_METHOD ), + TOKEN( "nodeset", XML_NODESET ), + TOKEN( "indent", XML_INDENT ), + TOKEN( "omit-xml-declaration", XML_OMIT_XML_DECLARATION ), + TOKEN( "standalone", XML_STANDALONE ), + TOKEN( "cdata-section-elements", XML_CDATA_SECTION_ELEMENTS ), + TOKEN( "required", XML_REQUIRED ), + TOKEN( "relevant", XML_RELEVANT ), + TOKEN( "calculate", XML_CALCULATE ), + TOKEN( "constraint", XML_CONSTRAINT ), + TOKEN( "maxOccurs", XML_MAXOCCURS /* (maxOccurs) */ ), + TOKEN( "minOccurs", XML_MINOCCURS /* (minOccurs) */ ), + TOKEN( "p3ptype", XML_P3PTYPE ), + TOKEN( "mediatype", XML_MEDIATYPE ), + TOKEN( "includenamespaceprefixes", XML_INCLUDENAMESPACEPREFIXES ), + + // XForms/XSD Schema tokens + TOKEN( "base", XML_BASE ), + TOKEN( "targetNamespace", XML_TARGETNAMESPACE ), + TOKEN( "simpleType", XML_SIMPLETYPE ), + TOKEN( "restriction", XML_RESTRICTION ), + TOKEN( "maxLength", XML_MAXLENGTH ), + TOKEN( "minLength", XML_MINLENGTH ), + TOKEN( "minInclusive", XML_MININCLUSIVE ), + TOKEN( "minExclusive", XML_MINEXCLUSIVE ), + TOKEN( "maxInclusive", XML_MAXINCLUSIVE ), + TOKEN( "maxExclusive", XML_MAXEXCLUSIVE ), + TOKEN( "pattern", XML_PATTERN ), + TOKEN( "enumeration", XML_ENUMERATION ), + TOKEN( "whiteSpace", XML_WHITESPACE ), + TOKEN( "totalDigits", XML_TOTALDIGITS ), + TOKEN( "fractionDigits", XML_FRACTIONDIGITS ), + TOKEN( "preserve", XML_PRESERVE ), + TOKEN( "anyURI", XML_ANYURI ), + TOKEN( "dateTime", XML_DATETIME_XSD ), + TOKEN( "main-etry", XML_MAIN_ETRY), + + TOKEN( "remove", XML_REMOVE ), + TOKEN( "hold", XML_HOLD ), + TOKEN( "transition", XML_TRANSITION ), + TOKEN( "inherit", XML_INHERIT ), + TOKEN( "fillDefault", XML_FILLDEFAULT ), + TOKEN( "restart", XML_RESTART ), + TOKEN( "restartDefault", XML_RESTARTDEFAULT ), + TOKEN( "whenNotActive", XML_WHENNOTACTIVE ), + TOKEN( "never", XML_NEVER ), + TOKEN( "accelerate", XML_ACCELERATE ), + TOKEN( "decelerate", XML_DECELERATE ), + TOKEN( "autoReverse", XML_AUTOREVERSE ), + TOKEN( "indefinite", XML_INDEFINITE ), + TOKEN( "repeatCount", XML_REPEATCOUNT ), + TOKEN( "repeatDur", XML_REPEATDUR ), + TOKEN( "endsync", XML_ENDSYNC ), + TOKEN( "first", XML_FIRST ), + TOKEN( "last", XML_LAST ), + TOKEN( "media", XML_MEDIA ), + TOKEN( "dur", XML_DUR ), + TOKEN( "begin", XML_BEGIN ), + TOKEN( "whole", XML_WHOLE ), + TOKEN( "from", XML_FROM ), + TOKEN( "to", XML_TO ), + TOKEN( "by", XML_BY ), + TOKEN( "values", XML_VALUES ), + TOKEN( "keyTimes", XML_KEYTIMES ), + TOKEN( "keySplines", XML_KEYSPLINES ), + TOKEN( "calcMode", XML_CALCMODE ), + TOKEN( "discrete", XML_DISCRETE ), + TOKEN( "paced", XML_PACED ), + TOKEN( "spline", XML_SPLINE ), + TOKEN( "accumulate", XML_ACCUMULATE ), + TOKEN( "additive", XML_ADDITIVE ), + TOKEN( "multiply", XML_MULTIPLY ), + TOKEN( "animate", XML_ANIMATE ), + TOKEN( "animateMotion", XML_ANIMATEMOTION ), + TOKEN( "animateTransform", XML_ANIMATETRANSFORM ), + TOKEN( "animateColor", XML_ANIMATECOLOR ), + TOKEN( "transitionFilter", XML_TRANSITIONFILTER ), + TOKEN( "attributeName", XML_ATTRIBUTENAME ), + + TOKEN( "smil", XML_NP_SMIL ), + TOKEN( "http://www.w3.org/2001/SMIL20/", XML_N_SMIL ), + + TOKEN( "anim", XML_NP_ANIMATION ), + TOKEN( "urn:oasis:names:tc:opendocument:xmlns:animation:1.0", XML_N_ANIMATION ), + TOKEN( "urn:oasis:names:tc:openoffice:xmlns:animation:1.0", XML_N_ANIMATION_OOO ), + + TOKEN( "par", XML_PAR ), + TOKEN( "seq", XML_SEQ ), + + TOKEN( "translate", XML_TRANSLATE ), + TOKEN( "skewX", XML_SKEWX ), + TOKEN( "skewY", XML_SKEWY ), + + TOKEN( "audio", XML_AUDIO ), + + TOKEN( "color-interpolation", XML_COLOR_INTERPOLATION ), + TOKEN( "color-interpolation-direction", XML_COLOR_INTERPOLATION_DIRECTION ), + TOKEN( "hsl", XML_HSL ), + TOKEN( "rgb", XML_RGB ), + + TOKEN( "barWipe", XML_BARWIPE ), + TOKEN( "boxWipe", XML_BOXWIPE ), + TOKEN( "fourBoxWipe", XML_FOURBOXWIPE ), + TOKEN( "barnDoorWipe", XML_BARNDOORWIPE ), + TOKEN( "diagonalWipe", XML_DIAGONALWIPE ), + TOKEN( "bowTieWipe", XML_BOWTIEWIPE ), + TOKEN( "miscDiagonalWipe", XML_MISCDIAGONALWIPE ), + TOKEN( "veeWipe", XML_VEEWIPE ), + TOKEN( "barnVeeWipe", XML_BARNVEEWIPE ), + TOKEN( "zigZagWipe", XML_ZIGZAGWIPE ), + TOKEN( "barnZigZagWipe", XML_BARNZIGZAGWIPE ), + TOKEN( "irisWipe", XML_IRISWIPE ), + TOKEN( "triangleWipe", XML_TRIANGLEWIPE ), + TOKEN( "arrowHeadWipe", XML_ARROWHEADWIPE ), + TOKEN( "pentagonWipe", XML_PENTAGONWIPE ), + TOKEN( "hexagonWipe", XML_HEXAGONWIPE ), + TOKEN( "ellipseWipe", XML_ELLIPSEWIPE ), + TOKEN( "eyeWipe", XML_EYEWIPE ), + TOKEN( "roundRectWipe", XML_ROUNDRECTWIPE ), + TOKEN( "starWipe", XML_STARWIPE ), + TOKEN( "miscShapeWipe", XML_MISCSHAPEWIPE ), + TOKEN( "clockWipe", XML_CLOCKWIPE ), + TOKEN( "pinWheelWipe", XML_PINWHEELWIPE ), + TOKEN( "singleSweepWipe", XML_SINGLESWEEPWIPE ), + TOKEN( "fanWipe", XML_FANWIPE ), + TOKEN( "doubleFanWipe", XML_DOUBLEFANWIPE ), + TOKEN( "doubleSweepWipe", XML_DOUBLESWEEPWIPE ), + TOKEN( "saloonDoorWipe", XML_SALOONDOORWIPE ), + TOKEN( "windshieldWipe", XML_WINDSHIELDWIPE ), + TOKEN( "snakeWipe", XML_SNAKEWIPE ), + TOKEN( "spiralWipe", XML_SPIRALWIPE ), + TOKEN( "parallelSnakesWipe", XML_PARALLELSNAKESWIPE ), + TOKEN( "boxSnakesWipe", XML_BOXSNAKESWIPE ), + TOKEN( "waterfallWipe", XML_WATERFALLWIPE ), + TOKEN( "pushWipe", XML_PUSHWIPE ), + TOKEN( "slideWipe", XML_SLIDEWIPE ), + TOKEN( "blindsWipe", XML_BLINDSWIPE ), + TOKEN( "randomBarWipe", XML_RANDOMBARWIPE ), + TOKEN( "checkerBoardWipe", XML_CHECKERBOARDWIPE ), + TOKEN( "zoom", XML_ZOOM ), + + TOKEN( "leftToRight", XML_LEFTTORIGHT ), + TOKEN( "topToBottom", XML_TOPTOBOTTOM ), + TOKEN( "topLeft", XML_TOPLEFT ), + TOKEN( "topRight", XML_TOPRIGHT ), + TOKEN( "bottomRight", XML_BOTTOMRIGHT ), + TOKEN( "bottomLeft", XML_BOTTOMLEFT ), + TOKEN( "topCenter", XML_TOPCENTER ), + TOKEN( "rightCenter", XML_RIGHTCENTER ), + TOKEN( "bottomCenter", XML_BOTTOMCENTER ), + TOKEN( "leftCenter", XML_LEFTCENTER ), + TOKEN( "cornersIn", XML_CORNERSIN ), + TOKEN( "cornersOut", XML_CORNERSOUT ), + TOKEN( "diagonalBottomLeft", XML_DIAGONALBOTTOMLEFT ), + TOKEN( "diagonalTopLeft", XML_DIAGONALTOPLEFT ), + TOKEN( "doubleBarnDoor", XML_DOUBLEBARNDOOR ), + TOKEN( "doubleDiamond", XML_DOUBLEDIAMOND ), + TOKEN( "fourPoint", XML_FOURPOINT ), + TOKEN( "fivePoint", XML_FIVEPOINT ), + TOKEN( "sixPoint", XML_SIXPOINT ), + TOKEN( "heart", XML_HEART ), + TOKEN( "keyhole", XML_KEYHOLE ), + TOKEN( "clockwiseTwelve", XML_CLOCKWISETWELVE ), + TOKEN( "clockwiseThree", XML_CLOCKWISETHREE ), + TOKEN( "clockwiseSix", XML_CLOCKWISESIX ), + TOKEN( "clockwiseNine", XML_CLOCKWISENINE ), + TOKEN( "twoBladeVertical", XML_TWOBLADEVERTICAL ), + TOKEN( "twoBladeHorizontal", XML_TWOBLADEHORIZONTAL ), + TOKEN( "fourBlade", XML_FOURBLADE ), + TOKEN( "clockwiseTop", XML_CLOCKWISETOP ), + TOKEN( "clockwiseRight", XML_CLOCKWISERIGHT ), + TOKEN( "clockwiseBottom", XML_CLOCKWISEBOTTOM ), + TOKEN( "clockwiseLeft", XML_CLOCKWISELEFT ), + TOKEN( "clockwiseTopLeft", XML_CLOCKWISETOPLEFT ), + TOKEN( "counterClockwiseBottomLeft", XML_COUNTERCLOCKWISEBOTTOMLEFT ), + TOKEN( "clockwiseBottomRight", XML_CLOCKWISEBOTTOMRIGHT ), + TOKEN( "counterClockwiseTopRight", XML_COUNTERCLOCKWISETOPRIGHT ), + TOKEN( "centerTop", XML_CENTERTOP ), + TOKEN( "centerRight", XML_CENTERRIGHT ), + TOKEN( "fanOutVertical", XML_FANOUTVERTICAL ), + TOKEN( "fanOutHorizontal", XML_FANOUTHORIZONTAL ), + TOKEN( "fanInVertical", XML_FANINVERTICAL ), + TOKEN( "fanInHorizontal", XML_FANINHORIZONTAL ), + TOKEN( "parallelVertical", XML_PARALLELVERTICAL ), + TOKEN( "parallelDiagonal", XML_PARALLELDIAGONAL ), + TOKEN( "oppositeVertical", XML_OPPOSITEVERTICAL ), + TOKEN( "oppositeHorizontal", XML_OPPOSITEHORIZONTAL ), + TOKEN( "parallelDiagonalTopLeft", XML_PARALLELDIAGONALTOPLEFT ), + TOKEN( "parallelDiagonalBottomLeft", XML_PARALLELDIAGONALBOTTOMLEFT ), + TOKEN( "topLeftHorizontal", XML_TOPLEFTHORIZONTAL ), + TOKEN( "topLeftDiagonal", XML_TOPLEFTDIAGONAL ), + TOKEN( "topLeftVertical", XML_TOPLEFTVERTICAL ), + TOKEN( "topRightDiagonal", XML_TOPRIGHTDIAGONAL ), + TOKEN( "bottomRightDiagonal", XML_BOTTOMRIGHTDIAGONAL ), + TOKEN( "bottomLeftDiagonal", XML_BOTTOMLEFTDIAGONAL ), + TOKEN( "topLeftClockwise", XML_TOPLEFTCLOCKWISE ), + TOKEN( "topRightClockwise", XML_TOPRIGHTCLOCKWISE ), + TOKEN( "bottomRightClockwise", XML_BOTTOMRIGHTCLOCKWISE ), + TOKEN( "bottomLeftClockwise", XML_BOTTOMLEFTCLOCKWISE ), + TOKEN( "topLeftCounterClockwise", XML_TOPLEFTCOUNTERCLOCKWISE ), + TOKEN( "topRightCounterClockwise", XML_TOPRIGHTCOUNTERCLOCKWISE ), + TOKEN( "bottomRightCounterClockwise", XML_BOTTOMRIGHTCOUNTERCLOCKWISE ), + TOKEN( "bottomLeftCounterClockwise", XML_BOTTOMLEFTCOUNTERCLOCKWISE ), + TOKEN( "verticalTopSame", XML_VERTICALTOPSAME ), + TOKEN( "verticalBottomSame", XML_VERTICALBOTTOMSAME ), + TOKEN( "verticalTopLeftOpposite", XML_VERTICALTOPLEFTOPPOSITE ), + TOKEN( "verticalBottomLeftOpposite", XML_VERTICALBOTTOMLEFTOPPOSITE ), + TOKEN( "horizontalLeftSame", XML_HORIZONTALLEFTSAME ), + TOKEN( "horizontalRightSame", XML_HORIZONTALRIGHTSAME ), + TOKEN( "horizontalTopLeftOpposite", XML_HORIZONTALTOPLEFTOPPOSITE ), + TOKEN( "horizontalTopRightOpposite", XML_HORIZONTALTOPRIGHTOPPOSITE ), + TOKEN( "diagonalBottomLeftOpposite", XML_DIAGONALBOTTOMLEFTOPPOSITE ), + TOKEN( "diagonalTopLeftOpposite", XML_DIAGONALTOPLEFTOPPOSITE ), + TOKEN( "twoBoxTop", XML_TWOBOXTOP ), + TOKEN( "twoBoxBottom", XML_TWOBOXBOTTOM ), + TOKEN( "twoBoxLeft", XML_TWOBOXLEFT ), + TOKEN( "twoBoxRight", XML_TWOBOXRIGHT ), + TOKEN( "fourBoxVertical", XML_FOURBOXVERTICAL ), + TOKEN( "fourBoxHorizontal", XML_FOURBOXHORIZONTAL ), + TOKEN( "verticalLeft", XML_VERTICALLEFT ), + TOKEN( "verticalRight", XML_VERTICALRIGHT ), + TOKEN( "horizontalLeft", XML_HORIZONTALLEFT ), + TOKEN( "horizontalRight", XML_HORIZONTALRIGHT ), + TOKEN( "fromLeft", XML_FROMLEFT ), + TOKEN( "fromTop", XML_FROMTOP ), + TOKEN( "fromRight", XML_FROMRIGHT ), + TOKEN( "fromBottom", XML_FROMBOTTOM ), + TOKEN( "crossfade", XML_CROSSFADE ), + TOKEN( "fadeToColor", XML_FADETOCOLOR ), + TOKEN( "fadeFromColor", XML_FADEFROMCOLOR ), + TOKEN( "fadeOverColor", XML_FADEOVERCOLOR ), + TOKEN( "threeBlade", XML_THREEBLADE ), + TOKEN( "eightBlade", XML_EIGHTBLADE ), + TOKEN( "oneBlade", XML_ONEBLADE ), + TOKEN( "across", XML_ACROSS ), + TOKEN( "combHorizontal", XML_COMBHORIZONTAL ), + TOKEN( "combVertical", XML_COMBVERTICAL ), + TOKEN( "rotateIn", XML_ROTATEIN ), + TOKEN( "rotateOut", XML_ROTATEOUT ), + TOKEN( "fromTopLeft", XML_FROMTOPLEFT ), + TOKEN( "fromTopRight", XML_FROMTOPRIGHT ), + TOKEN( "fromBottomLeft", XML_FROMBOTTOMLEFT ), + TOKEN( "fromBottomRight", XML_FROMBOTTOMRIGHT ), + + TOKEN( "subtype", XML_SUBTYPE ), + TOKEN( "out", XML_OUT ), + + TOKEN( "forward", XML_FORWARD ), + TOKEN( "reverse", XML_REVERSE ), + + TOKEN( "fadeColor", XML_FADECOLOR ), + + TOKEN( "onbegin", XML_ONBEGIN ), + TOKEN( "onend", XML_ONEND ), + TOKEN( "click", XML_CLICK ), + TOKEN( "doubleclick", XML_DOUBLECLICK ), + TOKEN( "mouseover", XML_MOUSEOVER ), + TOKEN( "mouseout", XML_MOUSEOUT ), + + TOKEN( "node-type", XML_NODE_TYPE ), + TOKEN( "preset-id", XML_PRESET_ID ), + TOKEN( "preset-sub-type", XML_PRESET_SUB_TYPE ), + TOKEN( "preset-class", XML_PRESET_CLASS ), + TOKEN( "preset-property", XML_PRESET_PROPERTY ), + TOKEN( "custom", XML_CUSTOM ), + TOKEN( "entrance", XML_ENTRANCE ), + TOKEN( "exit", XML_EXIT ), + TOKEN( "emphasis", XML_EMPHASIS ), + TOKEN( "motion-path", XML_MOTION_PATH ), + TOKEN( "ole-action", XML_OLE_ACTION ), + TOKEN( "media-call", XML_MEDIA_CALL ), + TOKEN( "on-click", XML_ON_CLICK ), + TOKEN( "with-previous", XML_WITH_PREVIOUS ), + TOKEN( "after-previous", XML_AFTER_PREVIOUS ), + TOKEN( "main-sequence", XML_MAIN_SEQUENCE ), + TOKEN( "timing-root", XML_TIMING_ROOT ), + TOKEN( "interactive-sequence",XML_INTERACTIVE_SEQUENCE ), + + TOKEN( "sub-item", XML_SUB_ITEM ), + TOKEN( "iterate-type", XML_ITERATE_TYPE ), + TOKEN( "iterate-interval", XML_ITERATE_INTERVAL ), + TOKEN( "iterate", XML_ITERATE ), + TOKEN( "by-paragraph", XML_BY_PARAGRAPH ), + TOKEN( "by-word", XML_BY_WORD ), + TOKEN( "by-letter", XML_BY_LETTER ), + + TOKEN( "after-effect", XML_AFTER_EFFECT ), + TOKEN( "master", XML_MASTER ), + + TOKEN( "group-id", XML_GROUP_ID ), + TOKEN( "targetElement", XML_TARGETELEMENT ), + TOKEN( "toggle-pause", XML_TOGGLE_PAUSE ), + TOKEN( "master-element", XML_MASTER_ELEMENT ), + TOKEN( "stop-audio", XML_STOP_AUDIO ), + + TOKEN( "audio-level", XML_AUDIO_LEVEL ), + + TOKEN( "urn:oasis:names:tc", XML_URN_OASIS_NAMES_TC ), + TOKEN( "opendocument", XML_OPENDOCUMENT), + TOKEN( "1.0", XML_1_0 ), + + TOKEN( "is-list-header", XML_IS_LIST_HEADER ), + TOKEN( "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0", XML_N_SVG_COMPAT ), + TOKEN( "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0", XML_N_FO_COMPAT ), + TOKEN( "urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0", XML_N_SMIL_COMPAT ), + TOKEN( "http://www.w3.org/2001/SMIL20", XML_N_SMIL_OLD ), + TOKEN( "xforms-submission", XML_XFORMS_SUBMISSION ), + TOKEN( "xforms-list-source", XML_XFORMS_LIST_SOURCE ), + + TOKEN( "http://www.w3.org/", XML_URI_W3_PREFIX ), + TOKEN( "/xforms", XML_URI_XFORMS_SUFFIX ), + /* XML_HORIZONTAL_ON_LEFT_PAGES and XML_HORIZONTAL_ON_RIGHT_PAGES + are replaced by XML_HORIZONTAL_ON_EVEN and XML_HORIZONTAL_ON_ODD. (#i49139#) + */ + TOKEN( "horizontal-on-even", XML_HORIZONTAL_ON_EVEN ), + TOKEN( "urn:oasis:names:tc:opendocument:xmlns:report:1.0", XML_N_RPT_OASIS ), + TOKEN( "http://openoffice.org/2005/report", XML_N_RPT ), + TOKEN( "group", XML_GROUP ), + TOKEN( "groups", XML_GROUPS ), + TOKEN( "report-header", XML_REPORT_HEADER ), + TOKEN( "page-header", XML_PAGE_HEADER ), + TOKEN( "detail", XML_DETAIL ), + TOKEN( "page-footer", XML_PAGE_FOOTER ), + TOKEN( "report-footer", XML_REPORT_FOOTER ), + TOKEN( "start-new-column", XML_START_NEW_COLUMN ), + TOKEN( "reset-page-number", XML_RESET_PAGE_NUMBER ), + TOKEN( "print-header-on-each-page", XML_PRINT_HEADER_ON_EACH_PAGE ), + TOKEN( "sort-expression", XML_SORT_EXPRESSION ), + TOKEN( "group-expression", XML_GROUP_EXPRESSION ), + TOKEN( "group-header", XML_GROUP_HEADER ), + TOKEN( "group-footer", XML_GROUP_FOOTER ), + TOKEN( "header-on-new-page", XML_HEADER_ON_NEW_PAGE), + TOKEN( "footer-on-new-page", XML_FOOTER_ON_NEW_PAGE), + TOKEN( "page-print-option", XML_PAGE_PRINT_OPTION ), + TOKEN( "pre-evaluated", XML_PRE_EVALUATED), + TOKEN( "command-type", XML_COMMAND_TYPE ), + TOKEN( "master-fields", XML_MASTER_FIELDS ), + TOKEN( "detail-fields", XML_DETAIL_FIELDS ), + TOKEN( "conditional-print-expression", XML_CONDITIONAL_PRINT_EXPRESSION ), + TOKEN( "report-component", XML_REPORT_COMPONENT ), + TOKEN( "print-repeated-values", XML_PRINT_REPEATED_VALUES ), + TOKEN( "repeat-section", XML_REPEAT_SECTION ), + TOKEN( "force-new-column", XML_FORCE_NEW_COLUMN ), + TOKEN( "group-on", XML_GROUP_ON), + TOKEN( "force-new-page", XML_FORCE_NEW_PAGE), + TOKEN( "group-interval", XML_GROUP_INTERVAL), + TOKEN( "print-when-group-change", XML_PRINT_WHEN_GROUP_CHANGE), + TOKEN( "report-element", XML_REPORT_ELEMENT), + TOKEN( "list-source", XML_LIST_SOURCE), + TOKEN( "list-source-type", XML_LIST_SOURCE_TYPE), + TOKEN( "image-data", XML_IMAGE_DATA), + TOKEN( "selected", XML_SELECTED), + TOKEN( "current-state", XML_CURRENT_STATE), + TOKEN( "is-tristate", XML_IS_TRISTATE), + TOKEN( "all-pages", XML_ALL_PAGES), + TOKEN( "not-with-report-header", XML_NOT_WITH_REPORT_HEADER ), + TOKEN( "not-with-report-footer", XML_NOT_WITH_REPORT_FOOTER ), + TOKEN( "not-with-report-header-nor-footer", XML_NOT_WITH_REPORT_HEADER_NOR_FOOTER ), + TOKEN( "before-section", XML_BEFORE_SECTION ), + TOKEN( "after-section", XML_AFTER_SECTION ), + TOKEN( "before-after-section", XML_BEFORE_AFTER_SECTION), + TOKEN( "prefix-characters", XML_PREFIX_CHARACTERS ), + TOKEN( "quartal", XML_QUARTAL ), + TOKEN( "week", XML_WEEK ), + TOKEN( "whole-group", XML_WHOLE_GROUP ), + TOKEN( "with-first-detail", XML_WITH_FIRST_DETAIL ), + TOKEN( "top-down", XML_TOP_DOWN ), + TOKEN( "bottom-up", XML_BOTTOM_UP ), + TOKEN( "hour", XML_HOUR ), + TOKEN( "minute", XML_MINUTE ), + TOKEN( "rpt", XML_NP_RPT ), + TOKEN( "format-condition", XML_FORMAT_CONDITION ), + TOKEN( "expression1", XML_EXPRESSION1 ), + TOKEN( "expression2", XML_EXPRESSION2 ), + TOKEN( "equal", XML_EQUAL ), + TOKEN( "not_equal", XML_NOT_EQUAL ), + TOKEN( "less", XML_LESS ), + TOKEN( "greater", XML_GREATER ), + TOKEN( "less_equal", XML_LESS_EQUAL ), + TOKEN( "greater_equal", XML_GREATER_EQUAL ), + TOKEN( "between", XML_BETWEEN ), + TOKEN( "not_between", XML_NOT_BETWEEN ), + TOKEN( "table-template", XML_TABLE_TEMPLATE ), + TOKEN( "first-row", XML_FIRST_ROW ), + TOKEN( "last-row", XML_LAST_ROW ), + TOKEN( "first-column", XML_FIRST_COLUMN ), + TOKEN( "last-column", XML_LAST_COLUMN ), + TOKEN( "even-rows", XML_EVEN_ROWS ), + TOKEN( "odd-rows", XML_ODD_ROWS ), + TOKEN( "even-columns", XML_EVEN_COLUMNS ), + TOKEN( "odd-columns", XML_ODD_COLUMNS ), + // table styles + TOKEN( "first-row-even-column", XML_FIRST_ROW_EVEN_COLUMN ), + TOKEN( "last-row-even-column", XML_LAST_ROW_EVEN_COLUMN ), + TOKEN( "first-row-end-column", XML_FIRST_ROW_END_COLUMN ), + TOKEN( "first-row-start-column", XML_FIRST_ROW_START_COLUMN ), + TOKEN( "last-row-end-column", XML_LAST_ROW_END_COLUMN ), + TOKEN( "last-row-start-column", XML_LAST_ROW_START_COLUMN ), + + TOKEN( "horizontal-on-odd", XML_HORIZONTAL_ON_ODD ), + // Password error from 1.4 to 2.0 Beta (#i45874#) + TOKEN( "restart-numbering", XML_RESTART_NUMBERING), + // OpenDocument <text:numbered-paragraph> element not supported on OpenDocument import (#i52127#) + TOKEN( "numbered-paragraph", XML_NUMBERED_PARAGRAPH), + TOKEN( "master-detail-fields", XML_MASTER_DETAIL_FIELDS), + TOKEN( "master-detail-field", XML_MASTER_DETAIL_FIELD), + TOKEN( "sub-document", XML_SUB_DOCUMENT), + TOKEN( "fixed-content", XML_FIXED_CONTENT), + TOKEN( "initial-formula", XML_INITIAL_FORMULA), + TOKEN( "deep-traversing", XML_DEEP_TRAVERSING), + TOKEN( "preserve-IRI", XML_PRESERVE_IRI), + TOKEN( "sort-by-x-values", XML_SORT_BY_X_VALUES ), + TOKEN( "page-continuation", XML_PAGE_CONTINUATION ), + TOKEN( "right-angled-axes", XML_RIGHT_ANGLED_AXES ), + TOKEN( "soft-page-break", XML_SOFT_PAGE_BREAK ), + TOKEN( "use-soft-page-breaks", XML_USE_SOFT_PAGE_BREAKS ), + TOKEN( "percentage-data-style-name", XML_PERCENTAGE_DATA_STYLE_NAME ), + TOKEN( "value-and-percentage", XML_VALUE_AND_PERCENTAGE ), + TOKEN( "group-bars-per-axis", XML_GROUP_BARS_PER_AXIS ), + TOKEN( "include-hidden-cells", XML_INCLUDE_HIDDEN_CELLS ), + TOKEN( "auto-position", XML_AUTOMATIC_POSITION ), + TOKEN( "auto-size", XML_AUTOMATIC_SIZE ), + TOKEN( "reverse-direction", XML_REVERSE_DIRECTION ), + TOKEN( "label-separator", XML_LABEL_SEPARATOR ), + TOKEN( "label-position", XML_LABEL_POSITION ), + TOKEN( "avoid-overlap", XML_AVOID_OVERLAP ), + TOKEN( "near-origin", XML_NEAR_ORIGIN ), + TOKEN( "dependency", XML_DEPENDENCY ), + TOKEN( "nav-order", XML_NAV_ORDER ), + + TOKEN( "use-first-row-styles", XML_USE_FIRST_ROW_STYLES ), + TOKEN( "use-last-row-styles", XML_USE_LAST_ROW_STYLES ), + TOKEN( "use-first-column-styles", XML_USE_FIRST_COLUMN_STYLES ), + TOKEN( "use-last-column-styles", XML_USE_LAST_COLUMN_STYLES ), + TOKEN( "use-banding-rows-styles", XML_USE_BANDING_ROWS_STYLES ), + TOKEN( "use-banding-columns-styles", XML_USE_BANDING_COLUMNS_STYLES ), + + TOKEN( "automatic-content", XML_AUTOMATIC_CONTENT ), + TOKEN( "display-r-square", XML_DISPLAY_R_SQUARE ), + TOKEN( "display-equation", XML_DISPLAY_EQUATION ), + // db odf 12 + TOKEN( "table-representations", XML_TABLE_REPRESENTATIONS ), + TOKEN( "table-representation", XML_TABLE_REPRESENTATION ), + TOKEN( "schema-definition", XML_SCHEMA_DEFINITION ), + TOKEN( "connection-data", XML_CONNECTION_DATA ), + TOKEN( "database-description", XML_DATABASE_DESCRIPTION ), + TOKEN( "compound-database", XML_COMPOUND_DATABASE ), + TOKEN( "file-based-database", XML_FILE_BASED_DATABASE ), + TOKEN( "server-database", XML_SERVER_DATABASE ), + TOKEN( "media-type", XML_MEDIA_TYPE ), + TOKEN( "hostname", XML_HOSTNAME ), + TOKEN( "port", XML_PORT ), + TOKEN( "local-socket", XML_LOCAL_SOCKET ), + TOKEN( "use-system-user", XML_USE_SYSTEM_USER ), + TOKEN( "driver-settings", XML_DRIVER_SETTINGS ), + TOKEN( "java-classpath", XML_JAVA_CLASSPATH ), + TOKEN( "character-set", XML_CHARACTER_SET ), + TOKEN( "application-connection-settings", XML_APPLICATION_CONNECTION_SETTINGS ), + TOKEN( "table-include-filter", XML_TABLE_INCLUDE_FILTER ), + TOKEN( "default-row-style-name", XML_DEFAULT_ROW_STYLE_NAME), + TOKEN( "angle-offset", XML_ANGLE_OFFSET ), + // Core implementation for direct cross-references (#i81002#) + TOKEN( "number-no-superior", XML_NUMBER_NO_SUPERIOR ), + TOKEN( "number-all-superior", XML_NUMBER_ALL_SUPERIOR ), + TOKEN( "list-level-position-and-space-mode", XML_LIST_LEVEL_POSITION_AND_SPACE_MODE ), + TOKEN( "label-width-and-position", XML_LABEL_WIDTH_AND_POSITION ), + TOKEN( "label-alignment", XML_LABEL_ALIGNMENT ), + TOKEN( "list-level-label-alignment", XML_LIST_LEVEL_LABEL_ALIGNMENT ), + TOKEN( "label-followed-by", XML_LABEL_FOLLOWED_BY ), + TOKEN( "listtab", XML_LISTTAB ), + TOKEN( "space", XML_SPACE ), + TOKEN( "nothing", XML_NOTHING ), + TOKEN( "list-tab-stop-position", XML_LIST_TAB_STOP_POSITION ), + + // bm: chart error bar extensions (ODF 1.2) + TOKEN( "standard-error", XML_STANDARD_ERROR ), + TOKEN( "cell-range" , XML_CELL_RANGE ), + TOKEN( "error-lower-range", XML_ERROR_LOWER_RANGE ), + TOKEN( "error-upper-range", XML_ERROR_UPPER_RANGE ), + + TOKEN( "continue-list", XML_CONTINUE_LIST ), + TOKEN( "style-override", XML_STYLE_OVERRIDE ), + + // XForms: Changes to model should optionally set document's modified state. (#i90243#) + TOKEN( "xforms-settings", XML_XFORM_MODEL_SETTINGS ), + + // ODF 1.2 metadata + TOKEN( "meta-field", XML_META_FIELD ), + TOKEN( "about", XML_ABOUT ), + TOKEN( "datatype", XML_DATATYPE ), + TOKEN( "transformation", XML_TRANSFORMATION ), + + // ODF 1.2 numbered-paragraph + TOKEN( "list-id", XML_LIST_ID ), + + TOKEN( "treat-empty-cells", XML_TREAT_EMPTY_CELLS ), + TOKEN( "leave-gap", XML_LEAVE_GAP ), + TOKEN( "use-zero", XML_USE_ZERO ), + TOKEN( "ignore", XML_IGNORE ), + + // enhanced fields + TOKEN( "fieldmark", XML_FIELDMARK ), + TOKEN( "fieldmark-start", XML_FIELDMARK_START ), + TOKEN( "fieldmark-end", XML_FIELDMARK_END ), + + TOKEN( "image-scale", XML_IMAGE_SCALE ), + TOKEN( "isotropic", XML_ISOTROPIC ), + TOKEN( "anisotropic", XML_ANISOTROPIC ), + + TOKEN( "axis-position", XML_AXIS_POSITION ), + TOKEN( "axis-label-position", XML_AXIS_LABEL_POSITION ), + TOKEN( "near-axis", XML_NEAR_AXIS ), + TOKEN( "near-axis-other-side", XML_NEAR_AXIS_OTHER_SIDE ), + TOKEN( "outside-start", XML_OUTSIDE_START ), + TOKEN( "outside-end", XML_OUTSIDE_END ), + TOKEN( "tick-mark-position", XML_TICK_MARK_POSITION ), + TOKEN( "at-labels", XML_AT_LABELS ), + TOKEN( "at-axis", XML_AT_AXIS ), + TOKEN( "at-labels-and-axis", XML_AT_LABELS_AND_AXIS ), + TOKEN( "filled-radar", XML_FILLED_RADAR ), + TOKEN( "surface", XML_SURFACE ), + + TOKEN( "mathvariant", XML_MATHVARIANT ), + TOKEN( "mathsize", XML_MATHSIZE ), + TOKEN( "mathweight", XML_MATHWEIGHT ), + TOKEN( "mathcolor", XML_MATHCOLOR ), + + TOKEN( "contains", XML_CONTAINS ), + TOKEN( "does-not-contain", XML_DOES_NOT_CONTAIN ), + TOKEN( "begins-with", XML_BEGINS_WITH ), + TOKEN( "does-not-begin-with", XML_DOES_NOT_BEGIN_WITH ), + TOKEN( "ends-with", XML_ENDS_WITH ), + TOKEN( "does-not-end-with", XML_DOES_NOT_END_WITH ), + + TOKEN( "chartooo", XML_NP_CHART_EXT ), + TOKEN( "http://openoffice.org/2010/chart", XML_N_CHART_EXT ), + TOKEN( "coordinate-region", XML_COORDINATE_REGION ), + + TOKEN( "diagonal-bl-tr-widths", XML_DIAGONAL_BL_TR_WIDTHS ), + TOKEN( "diagonal-tl-br-widths", XML_DIAGONAL_TL_BR_WIDTHS ), + + TOKEN( "outside-minimum", XML_OUTSIDE_MINIMUM ), + TOKEN( "outside-maximum", XML_OUTSIDE_MAXIMUM ), + + TOKEN( "legend-expansion", XML_LEGEND_EXPANSION), + TOKEN( "legend-expansion-aspect-ratio", XML_LEGEND_EXPANSION_ASPECT_RATIO), + TOKEN( "balanced", XML_BALANCED), + TOKEN( "high", XML_HIGH), + TOKEN( "wide", XML_WIDE), + + TOKEN( "axis-type", XML_AXIS_TYPE ), //#i25706# + TOKEN( "date-scale", XML_DATE_SCALE ), + TOKEN( "base-time-unit", XML_BASE_TIME_UNIT ), + TOKEN( "major-interval-value", XML_MAJOR_INTERVAL_VALUE ), + TOKEN( "minor-interval-value", XML_MINOR_INTERVAL_VALUE ), + TOKEN( "major-interval-unit", XML_MAJOR_INTERVAL_UNIT ), + TOKEN( "minor-interval-unit", XML_MINOR_INTERVAL_UNIT ), + + TOKEN( "min-value", XML_MIN_VALUE ), + TOKEN( "max-value", XML_MAX_VALUE ), + + TOKEN( "margin", XML_MARGIN), + + TOKEN( "propertry-mapping", XML_PROPERTY_MAPPING), + TOKEN( "provider", XML_PROVIDER), + TOKEN( "data-mappings", XML_DATA_MAPPINGS), + TOKEN( "data-mapping", XML_DATA_MAPPING), + TOKEN( "frequency", XML_DATA_FREQUENCY), + TOKEN( "data-transformations", XML_DATA_TRANSFORMATIONS), + TOKEN( "column-remove-transformation", XML_COLUMN_REMOVE_TRANSFORMATION), + TOKEN( "column-split-transformation", XML_COLUMN_SPLIT_TRANSFORMATION), + TOKEN( "column-merge-transformation", XML_COLUMN_MERGE_TRANSFORMATION), + TOKEN( "column-sort-transformation", XML_COLUMN_SORT_TRANSFORMATION), + TOKEN( "column-text-transformation", XML_COLUMN_TEXT_TRANSFORMATION), + TOKEN( "column-aggregate-transformation", XML_COLUMN_AGGREGATE_TRANSFORMATION), + TOKEN( "column-number-transformation", XML_COLUMN_NUMBER_TRANSFORMATION), + + TOKEN( "sort-param", XML_SORT_PARAM ), + TOKEN( "merge-string", XML_MERGE_STRING ), + TOKEN( "trim", XML_TRIM ), + TOKEN( "round-up", XML_ROUND_UP ), + TOKEN( "round-down", XML_ROUND_DOWN ), + TOKEN( "log-base-10", XML_LOG_10 ), + TOKEN( "number-square", XML_SQUARE ), + TOKEN( "square-root", XML_SQUARE_ROOT ), + TOKEN( "even", XML_EVEN ), + TOKEN( "odd", XML_ODD ), + TOKEN( "sign", XML_SIGN ), + TOKEN( "replace-string", XML_REPLACE_STRING ), + TOKEN( "column-replacenull-transformation", XML_COLUMN_REPLACENULL_TRANSFORMATION ), + TOKEN( "column-datetime-transformation", XML_COLUMN_DATETIME_TRANSFORMATION ), + TOKEN( "start-of-year", XML_START_OF_YEAR ), + TOKEN( "end-of-year", XML_END_OF_YEAR ), + TOKEN( "month-name", XML_MONTH_NAME ), + TOKEN( "start-of-month", XML_START_OF_MONTH ), + TOKEN( "end-of-month", XML_END_OF_MONTH ), + TOKEN( "day-of-year", XML_DAY_OF_YEAR ), + TOKEN( "start-of-quarter", XML_START_OF_QUARTER ), + TOKEN( "end-of-quarter", XML_END_OF_QUARTER ), + + // regina, ODF1.2 additional symbols in charts + TOKEN( "star", XML_STAR ), + TOKEN( "asterisk", XML_ASTERISK ), + TOKEN( "horizontal-bar", XML_HORIZONTAL_BAR ), + TOKEN( "vertical-bar", XML_VERTICAL_BAR ), + + TOKEN( "std-weight", XML_ERROR_STANDARD_WEIGHT ), + + // erAck: 2013-07-02 BCP 47 language tags + TOKEN( "rfc-language-tag", XML_RFC_LANGUAGE_TAG ), + TOKEN( "rfc-language-tag-asian", XML_RFC_LANGUAGE_TAG_ASIAN ), + TOKEN( "rfc-language-tag-complex", XML_RFC_LANGUAGE_TAG_COMPLEX ), + TOKEN( "data-table-show-horz-border", XML_DATA_TABLE_SHOW_HORZ_BORDER ), + TOKEN( "data-table-show-vert-border", XML_DATA_TABLE_SHOW_VERT_BORDER ), + TOKEN( "data-table-show-outline", XML_DATA_TABLE_SHOW_OUTLINE ), + TOKEN( "display-units", XML_CHART_DUNITS_DISPLAYUNITS ), + TOKEN( "display-units-built-in-unit", XML_CHART_DUNITS_BUILTINUNIT ), + TOKEN( "external-data", XML_EXTERNALDATA), + + TOKEN( "exponent-interval", XML_EXPONENT_INTERVAL ), + TOKEN( "forced-exponent-sign", XML_FORCED_EXPONENT_SIGN ), + TOKEN( "min-decimal-places", XML_MIN_DECIMAL_PLACES ), + TOKEN( "max-denominator-value", XML_MAX_DENOMINATOR_VALUE ), + TOKEN( "max-numerator-digits", XML_MAX_NUMERATOR_DIGITS ), + TOKEN( "zeros-numerator-digits", XML_ZEROS_NUMERATOR_DIGITS ), + TOKEN( "zeros-denominator-digits", XML_ZEROS_DENOMINATOR_DIGITS ), + TOKEN( "integer-fraction-delimiter", XML_INTEGER_FRACTION_DELIMITER ), + + // for optional language-dependent reference formats + TOKEN( "reference-language", XML_REFERENCE_LANGUAGE ), + TOKEN( "newline", XML_NEWLINE ), + TOKEN( "creator-initials", XML_CREATOR_INITIALS ), + + // tdf#115007 spell out numbers, dates, money amounts and cross references + TOKEN( "transliteration-spellout", XML_TRANSLITERATION_SPELLOUT ), + + // For recording whether comments/annotations are resolved + TOKEN( "resolved", XML_RESOLVED ), + + TOKEN( "page-content-bottom", XML_PAGE_CONTENT_BOTTOM ), + +#if OSL_DEBUG_LEVEL > 0 + { 0, nullptr, std::nullopt, XML_TOKEN_END } +#else + { 0, nullptr, std::nullopt /* XML_TOKEN_END */ } +#endif + }; + + // get OUString representation of token + const OUString& GetXMLToken( enum XMLTokenEnum eToken ) + { +#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG + static bool s_bChecked = false; + if (!s_bChecked) + { + // check the consistency of the token list. Below, we use the + // ordinal value of the token as index into the token list, so we + // should make sure that every entry is at the proper position + std::set<OString> tokenSet; + bool foundDuplicate = false; + const XMLTokenEntry* pEntry = aTokenList; + const XMLTokenEntry* pEntryEnd = + pEntry + SAL_N_ELEMENTS(aTokenList); + sal_uInt16 nPos = 0; + while (pEntry < pEntryEnd) + { + SAL_WARN_IF(nPos != static_cast<sal_uInt16>(pEntry->eToken), "xmloff", + "inconsistency at pos " << nPos << " for token " + << OUString( pEntry->pChar, pEntry->nLength, RTL_TEXTENCODING_ASCII_US )); + assert(nPos == static_cast<sal_uInt16>(pEntry->eToken)); + // Inconsistency in the token list! + // The positions in xmltoken.hxx and xmltoken.cxx need to match. + + // verify that we have no duplicates, which can mess us up when doing fast-parser import + if (pEntry->nLength && nPos >= XML_MM) + // ignoring the zero-length fake entries and the namespace prefix entries + { + auto pair = tokenSet.insert(OString(pEntry->pChar, pEntry->nLength)); + if (!pair.second) + { + SAL_WARN("xmloff", "duplicate token string " + << OUString( pEntry->pChar, pEntry->nLength, RTL_TEXTENCODING_ASCII_US )); + foundDuplicate = true; + } + } + ++pEntry; + ++nPos; + } + assert(!foundDuplicate && "duplicate token string"); + + s_bChecked = true; // it's all static, checking once is enough + } +#endif + assert(XML_TOKEN_INVALID < eToken); + assert(eToken < XML_TOKEN_END); + assert(sal_uInt16(eToken) < SAL_N_ELEMENTS(aTokenList)); + + XMLTokenEntry* pToken = &aTokenList[static_cast<sal_uInt16>(eToken)]; + if (!pToken->xOUString) + pToken->xOUString = OUString( pToken->pChar, pToken->nLength, + RTL_TEXTENCODING_ASCII_US ); + return *pToken->xOUString; + } + + // does rString represent eToken? + bool IsXMLToken( + const OUString& rString, + enum XMLTokenEnum eToken ) + { + assert(XML_TOKEN_INVALID < eToken); + assert(eToken < XML_TOKEN_END); + + const XMLTokenEntry* pToken = &aTokenList[static_cast<sal_uInt16>(eToken)]; + return rString.equalsAsciiL( pToken->pChar, pToken->nLength ); + } + + bool IsXMLToken( + const sax_fastparser::FastAttributeList::FastAttributeIter& aIter, + enum XMLTokenEnum eToken ) + { + assert(XML_TOKEN_INVALID < eToken); + assert(eToken < XML_TOKEN_END); + + const XMLTokenEntry* pToken = &aTokenList[static_cast<sal_uInt16>(eToken)]; + return aIter.isString( pToken->pChar ); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/xmluconv.cxx b/xmloff/source/core/xmluconv.cxx new file mode 100644 index 000000000..e6492898d --- /dev/null +++ b/xmloff/source/core/xmluconv.cxx @@ -0,0 +1,871 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <string_view> + +#include <xmloff/xmluconv.hxx> + +#include <com/sun/star/util/DateTime.hpp> +#include <com/sun/star/util/Date.hpp> +#include <rtl/ustrbuf.hxx> +#include <osl/diagnose.h> +#include <sal/log.hxx> +#include <xmloff/xmlement.hxx> +#include <xmloff/xmltoken.hxx> +#include <rtl/math.hxx> + +#include <tools/date.hxx> +#include <tools/time.hxx> +#include <tools/fldunit.hxx> + +#include <com/sun/star/drawing/Position3D.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/util/XNumberFormatsSupplier.hpp> +#include <com/sun/star/style/NumberingType.hpp> +#include <com/sun/star/text/DefaultNumberingProvider.hpp> +#include <com/sun/star/text/XDefaultNumberingProvider.hpp> +#include <com/sun/star/text/XNumberingTypeInfo.hpp> +#include <com/sun/star/i18n/CharacterClassification.hpp> +#include <com/sun/star/i18n/UnicodeType.hpp> +#include <basegfx/vector/b3dvector.hxx> + +#include <sax/tools/converter.hxx> + + +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::text; +using namespace com::sun::star::style; +using namespace ::com::sun::star::i18n; +using namespace ::xmloff::token; + + +const sal_Int8 XML_MAXDIGITSCOUNT_TIME = 11; +#define XML_NULLDATE "NullDate" + +struct SvXMLUnitConverter::Impl +{ + sal_Int16 m_eCoreMeasureUnit; /*css::util::MeasureUnit*/ + sal_Int16 m_eXMLMeasureUnit; /*css::util::MeasureUnit*/ + util::Date m_aNullDate; + mutable uno::Reference< text::XNumberingTypeInfo > m_xNumTypeInfo; + mutable uno::Reference< i18n::XCharacterClassification > m_xCharClass; + uno::Reference< uno::XComponentContext > m_xContext; + + Impl(uno::Reference<uno::XComponentContext> const& xContext, + sal_Int16 const eCoreMeasureUnit, + sal_Int16 const eXMLMeasureUnit) + : m_eCoreMeasureUnit(eCoreMeasureUnit) + , m_eXMLMeasureUnit(eXMLMeasureUnit) + , m_aNullDate(30, 12, 1899) + , m_xContext(xContext) + { + OSL_ENSURE( m_xContext.is(), "got no service manager" ); + } + + void createNumTypeInfo() const; +}; + + +void SvXMLUnitConverter::Impl::createNumTypeInfo() const +{ + Reference<XDefaultNumberingProvider> xDefNum = DefaultNumberingProvider::create(m_xContext); + m_xNumTypeInfo.set(xDefNum, uno::UNO_QUERY); +} + +const uno::Reference< text::XNumberingTypeInfo >& +SvXMLUnitConverter::getNumTypeInfo() const +{ + if (!m_pImpl->m_xNumTypeInfo.is()) + { + m_pImpl->createNumTypeInfo(); + } + return m_pImpl->m_xNumTypeInfo; +} + +void SvXMLUnitConverter::SetCoreMeasureUnit(sal_Int16 const eCoreMeasureUnit/*css::util::MeasureUnit*/) +{ + m_pImpl->m_eCoreMeasureUnit = eCoreMeasureUnit; +} + +void SvXMLUnitConverter::SetXMLMeasureUnit(sal_Int16 const eXMLMeasureUnit/*css::util::MeasureUnit*/) +{ + m_pImpl->m_eXMLMeasureUnit = eXMLMeasureUnit; +} + +sal_Int16 SvXMLUnitConverter::GetXMLMeasureUnit() const +{ + return m_pImpl->m_eXMLMeasureUnit; +} + +/** constructs a SvXMLUnitConverter. The core measure unit is the + default unit for numerical measures, the XML measure unit is + the default unit for textual measures +*/ + +SvXMLUnitConverter::SvXMLUnitConverter( + const uno::Reference<uno::XComponentContext>& xContext, + sal_Int16 const eCoreMeasureUnit, + sal_Int16 const eXMLMeasureUnit) +: m_pImpl(new Impl(xContext, eCoreMeasureUnit, eXMLMeasureUnit)) +{ +} + +SvXMLUnitConverter::~SvXMLUnitConverter() +{ +} + +sal_Int16 SvXMLUnitConverter::GetMeasureUnit(FieldUnit const nFieldUnit) +{ + sal_Int16 eUnit = util::MeasureUnit::INCH; + switch( nFieldUnit ) + { + case FieldUnit::MM: + eUnit = util::MeasureUnit::MM; + break; + case FieldUnit::CM: + case FieldUnit::M: + case FieldUnit::KM: + eUnit = util::MeasureUnit::CM; + break; + case FieldUnit::TWIP: + eUnit = util::MeasureUnit::TWIP; + break; + case FieldUnit::POINT: + case FieldUnit::PICA: + eUnit = util::MeasureUnit::POINT; + break; + case FieldUnit::MM_100TH: + eUnit = util::MeasureUnit::MM_100TH; + break; + case FieldUnit::INCH: + eUnit = util::MeasureUnit::INCH; + break; + default: + assert(false); + break; + } + return eUnit; +} + +/** convert string to measure using optional min and max values*/ +bool SvXMLUnitConverter::convertMeasureToCore( sal_Int32& nValue, + const OUString& rString, + sal_Int32 nMin, sal_Int32 nMax ) const +{ + return ::sax::Converter::convertMeasure( nValue, rString, + m_pImpl->m_eCoreMeasureUnit, + nMin, nMax ); +} + +/** convert measure to string */ +void SvXMLUnitConverter::convertMeasureToXML( OUStringBuffer& rString, + sal_Int32 nMeasure ) const +{ + ::sax::Converter::convertMeasure( rString, nMeasure, + m_pImpl->m_eCoreMeasureUnit, + m_pImpl->m_eXMLMeasureUnit ); +} + +/** convert measure to string */ +OUString SvXMLUnitConverter::convertMeasureToXML( sal_Int32 nMeasure ) const +{ + OUStringBuffer s; + ::sax::Converter::convertMeasure( s, nMeasure, + m_pImpl->m_eCoreMeasureUnit, + m_pImpl->m_eXMLMeasureUnit ); + return s.makeStringAndClear(); +} + +/** convert string to enum using given enum map, if the enum is + not found in the map, this method will return false +*/ +bool SvXMLUnitConverter::convertEnumImpl( sal_uInt16& rEnum, + const OUString& rValue, + const SvXMLEnumStringMapEntry<sal_uInt16> *pMap ) +{ + while( pMap->GetName() ) + { + if( rValue.equalsAsciiL( pMap->GetName(), pMap->GetNameLength() ) ) + { + rEnum = pMap->GetValue(); + return true; + } + ++pMap; + } + + return false; +} + +/** convert string to enum using given token map, if the enum is + not found in the map, this method will return false */ +bool SvXMLUnitConverter::convertEnumImpl( + sal_uInt16& rEnum, + const OUString& rValue, + const SvXMLEnumMapEntry<sal_uInt16> *pMap ) +{ + while( pMap->GetToken() != XML_TOKEN_INVALID ) + { + if( IsXMLToken( rValue, pMap->GetToken() ) ) + { + rEnum = pMap->GetValue(); + return true; + } + ++pMap; + } + return false; +} + +/** convert enum to string using given token map with an optional + default token. If the enum is not found in the map, + this method will either use the given default or return + false if no default is set */ +bool SvXMLUnitConverter::convertEnumImpl( + OUStringBuffer& rBuffer, + sal_uInt16 nValue, + const SvXMLEnumMapEntry<sal_uInt16> *pMap, + enum XMLTokenEnum eDefault) +{ + enum XMLTokenEnum eTok = eDefault; + + while( pMap->GetToken() != XML_TOKEN_INVALID ) + { + if( pMap->GetValue() == nValue ) + { + eTok = pMap->GetToken(); + break; + } + ++pMap; + } + + // the map may have contained XML_TOKEN_INVALID + if( eTok == XML_TOKEN_INVALID ) + eTok = eDefault; + + if( eTok != XML_TOKEN_INVALID ) + rBuffer.append( GetXMLToken(eTok) ); + + return (eTok != XML_TOKEN_INVALID); +} + +static int lcl_gethex( int nChar ) +{ + if( nChar >= '0' && nChar <= '9' ) + return nChar - '0'; + else if( nChar >= 'a' && nChar <= 'f' ) + return nChar - 'a' + 10; + else if( nChar >= 'A' && nChar <= 'F' ) + return nChar - 'A' + 10; + else + return 0; +} + +static const char aHexTab[] = "0123456789abcdef"; + + +/** convert double number to string (using ::rtl::math) */ +void SvXMLUnitConverter::convertDouble(OUStringBuffer& rBuffer, + double fNumber) const +{ + ::sax::Converter::convertDouble(rBuffer, fNumber, + true/*bWriteUnits*/, m_pImpl->m_eCoreMeasureUnit, m_pImpl->m_eXMLMeasureUnit); +} + +/** convert string to double number (using ::rtl::math) */ +bool SvXMLUnitConverter::convertDouble(double& rValue, + const OUString& rString) const +{ + sal_Int16 const eSrcUnit = ::sax::Converter::GetUnitFromString( + rString, m_pImpl->m_eCoreMeasureUnit); + + return ::sax::Converter::convertDouble(rValue, rString, + eSrcUnit, m_pImpl->m_eCoreMeasureUnit); +} + +/** get the Null Date of the XModel and set it to the UnitConverter */ +bool SvXMLUnitConverter::setNullDate(const css::uno::Reference <css::frame::XModel>& xModel) +{ + css::uno::Reference <css::util::XNumberFormatsSupplier> xNumberFormatsSupplier (xModel, css::uno::UNO_QUERY); + if (xNumberFormatsSupplier.is()) + { + const css::uno::Reference <css::beans::XPropertySet> xPropertySet = xNumberFormatsSupplier->getNumberFormatSettings(); + return xPropertySet.is() && (xPropertySet->getPropertyValue(XML_NULLDATE) >>= m_pImpl->m_aNullDate); + } + return false; +} + +/** convert double to ISO Date Time String */ +void SvXMLUnitConverter::convertDateTime(OUStringBuffer& rBuffer, + const double& fDateTime, bool const bAddTimeIf0AM) +{ + convertDateTime(rBuffer, fDateTime, m_pImpl->m_aNullDate, bAddTimeIf0AM); +} + +/** convert ISO Date Time String to double */ +bool SvXMLUnitConverter::convertDateTime(double& fDateTime, + const OUString& rString) +{ + return convertDateTime(fDateTime, rString, m_pImpl->m_aNullDate); +} + +/** convert double to ISO Date Time String */ +void SvXMLUnitConverter::convertDateTime( OUStringBuffer& rBuffer, + const double& fDateTime, + const css::util::Date& aTempNullDate, + bool bAddTimeIf0AM ) +{ + double fValue = fDateTime; + const sal_Int32 nDays = static_cast <sal_Int32> (::rtl::math::approxFloor (fValue)); + Date aDate (aTempNullDate.Day, aTempNullDate.Month, aTempNullDate.Year); + aDate.AddDays( nDays); + fValue -= nDays; + const bool bHasTime = (fValue > 0.0); + + sal_Int16 nTempYear = aDate.GetYear(); + assert(nTempYear != 0); + if (nTempYear < 0) + { + rBuffer.append( '-'); + nTempYear = -nTempYear; + } + if (nTempYear < 1000) + rBuffer.append( '0'); + if (nTempYear < 100) + rBuffer.append( '0'); + if (nTempYear < 10) + rBuffer.append( '0'); + rBuffer.append( sal_Int32( nTempYear)); + rBuffer.append( '-'); + sal_uInt16 nTemp = aDate.GetMonth(); + assert(1 <= nTemp && nTemp <= 12); + if (nTemp < 10) + rBuffer.append( '0'); + rBuffer.append( sal_Int32( nTemp)); + rBuffer.append( '-'); + nTemp = aDate.GetDay(); + assert(1 <= nTemp && nTemp <= 31); + if (nTemp < 10) + rBuffer.append( '0'); + rBuffer.append( sal_Int32( nTemp)); + if (bHasTime || bAddTimeIf0AM) + { + double fCount; + if (nDays > 0) + fCount = ::rtl::math::approxFloor (log10(static_cast<double>(nDays))) + 1; + else if (nDays < 0) + fCount = ::rtl::math::approxFloor (log10(static_cast<double>(nDays * -1))) + 1; + else + fCount = 0.0; + const int nDigits = sal_Int16(fCount) + 4; // +4 for *86400 in seconds + const int nFractionDecimals = std::max( XML_MAXDIGITSCOUNT_TIME - nDigits, 0); + + sal_uInt16 nHour, nMinute, nSecond; + double fFractionOfSecond; + // Pass the original date+time value for proper scaling and rounding. + tools::Time::GetClock( fDateTime, nHour, nMinute, nSecond, fFractionOfSecond, nFractionDecimals); + + rBuffer.append( 'T'); + if (nHour < 10) + rBuffer.append( '0'); + rBuffer.append( sal_Int32( nHour)); + rBuffer.append( ':'); + if (nMinute < 10) + rBuffer.append( '0'); + rBuffer.append( sal_Int32( nMinute)); + rBuffer.append( ':'); + if (nSecond < 10) + rBuffer.append( '0'); + rBuffer.append( sal_Int32( nSecond)); + if (nFractionDecimals) + { + // nFractionDecimals+1 to not round up what GetClock() carefully + // truncated. + OUString aFraction( ::rtl::math::doubleToUString( fFractionOfSecond, + rtl_math_StringFormat_F, + nFractionDecimals + 1, '.', true)); + const sal_Int32 nLen = aFraction.getLength(); + if ( nLen > 2 ) + { + // Truncate nFractionDecimals+1 digit if it was not rounded to zero. + const sal_Int32 nCount = nLen - 2 - static_cast<int>(nLen > nFractionDecimals + 2); + rBuffer.append( '.'); + rBuffer.append( std::u16string_view(aFraction).substr(2, nCount)); // strip 0. + } + } + } +} + +/** convert ISO Date Time String to double */ +bool SvXMLUnitConverter::convertDateTime( double& fDateTime, + const OUString& rString, const css::util::Date& aTempNullDate) +{ + css::util::DateTime aDateTime; + bool bSuccess = ::sax::Converter::parseDateTime(aDateTime, rString); + + if (bSuccess) + { + const Date aTmpNullDate(aTempNullDate.Day, aTempNullDate.Month, aTempNullDate.Year); + const Date aTempDate(aDateTime.Day, aDateTime.Month, aDateTime.Year); + const sal_Int32 nTage = aTempDate - aTmpNullDate; + double fTempDateTime = nTage; + double Hour = aDateTime.Hours; + double Min = aDateTime.Minutes; + double Sec = aDateTime.Seconds; + double NanoSec = aDateTime.NanoSeconds; + fTempDateTime += Hour / ::tools::Time::hourPerDay; + fTempDateTime += Min / ::tools::Time::minutePerDay; + fTempDateTime += Sec / ::tools::Time::secondPerDay; + fTempDateTime += NanoSec / ::tools::Time::nanoSecPerDay; + fDateTime = fTempDateTime; + } + return bSuccess; +} + + +SvXMLTokenEnumerator::SvXMLTokenEnumerator( const OUString& rString, sal_Unicode cSeparator /* = ' ' */ ) +: maTokenString( rString ), mnNextTokenPos(0), mcSeparator( cSeparator ) +{ +} + +bool SvXMLTokenEnumerator::getNextToken( OUString& rToken ) +{ + if( -1 == mnNextTokenPos ) + return false; + + int nTokenEndPos = maTokenString.indexOf( mcSeparator, mnNextTokenPos ); + if( nTokenEndPos != -1 ) + { + rToken = maTokenString.copy( mnNextTokenPos, + nTokenEndPos - mnNextTokenPos ); + mnNextTokenPos = nTokenEndPos + 1; + + // if the mnNextTokenPos is at the end of the string, we have + // to deliver an empty token + if( mnNextTokenPos > maTokenString.getLength() ) + mnNextTokenPos = -1; + } + else + { + rToken = maTokenString.copy( mnNextTokenPos ); + mnNextTokenPos = -1; + } + + return true; +} + +static bool lcl_getPositions(const OUString& _sValue,OUString& _rContentX,OUString& _rContentY,OUString& _rContentZ) +{ + if(_sValue.isEmpty() || _sValue[0] != '(') + return false; + + sal_Int32 nPos(1); + sal_Int32 nFound = _sValue.indexOf(' ', nPos); + + if(nFound == -1 || nFound <= nPos) + return false; + + _rContentX = _sValue.copy(nPos, nFound - nPos); + + nPos = nFound + 1; + nFound = _sValue.indexOf(' ', nPos); + + if(nFound == -1 || nFound <= nPos) + return false; + + _rContentY = _sValue.copy(nPos, nFound - nPos); + + nPos = nFound + 1; + nFound = _sValue.indexOf(')', nPos); + + if(nFound == -1 || nFound <= nPos) + return false; + + _rContentZ = _sValue.copy(nPos, nFound - nPos); + return true; + +} +/** convert string to ::basegfx::B3DVector */ +bool SvXMLUnitConverter::convertB3DVector( ::basegfx::B3DVector& rVector, const OUString& rValue ) +{ + OUString aContentX,aContentY,aContentZ; + if ( !lcl_getPositions(rValue,aContentX,aContentY,aContentZ) ) + return false; + + rtl_math_ConversionStatus eStatus; + + rVector.setX(::rtl::math::stringToDouble(aContentX, '.', + ',', &eStatus)); + + if( eStatus != rtl_math_ConversionStatus_Ok ) + return false; + + rVector.setY(::rtl::math::stringToDouble(aContentY, '.', + ',', &eStatus)); + + if( eStatus != rtl_math_ConversionStatus_Ok ) + return false; + + rVector.setZ(::rtl::math::stringToDouble(aContentZ, '.', + ',', &eStatus)); + + + return ( eStatus == rtl_math_ConversionStatus_Ok ); +} + +/** convert ::basegfx::B3DVector to string */ +void SvXMLUnitConverter::convertB3DVector( OUStringBuffer &rBuffer, const ::basegfx::B3DVector& rVector ) +{ + rBuffer.append('('); + ::sax::Converter::convertDouble(rBuffer, rVector.getX()); + rBuffer.append(' '); + ::sax::Converter::convertDouble(rBuffer, rVector.getY()); + rBuffer.append(' '); + ::sax::Converter::convertDouble(rBuffer, rVector.getZ()); + rBuffer.append(')'); +} + +/** convert string to Position3D */ +bool SvXMLUnitConverter::convertPosition3D( drawing::Position3D& rPosition, + const OUString& rValue ) +{ + OUString aContentX,aContentY,aContentZ; + if ( !lcl_getPositions(rValue,aContentX,aContentY,aContentZ) ) + return false; + + if ( !convertDouble( rPosition.PositionX, aContentX ) ) + return false; + if ( !convertDouble( rPosition.PositionY, aContentY ) ) + return false; + return convertDouble( rPosition.PositionZ, aContentZ ); +} + +/** convert Position3D to string */ +void SvXMLUnitConverter::convertPosition3D( OUStringBuffer &rBuffer, + const drawing::Position3D& rPosition ) +{ + rBuffer.append( '(' ); + convertDouble( rBuffer, rPosition.PositionX ); + rBuffer.append( ' ' ); + convertDouble( rBuffer, rPosition.PositionY ); + rBuffer.append( ' ' ); + convertDouble( rBuffer, rPosition.PositionZ ); + rBuffer.append( ')' ); +} + +bool SvXMLUnitConverter::convertNumFormat( + sal_Int16& rType, + const OUString& rNumFmt, + const OUString& rNumLetterSync, + bool bNumberNone ) const +{ + bool bRet = true; + bool bExt = false; + + sal_Int32 nLen = rNumFmt.getLength(); + if( 0 == nLen ) + { + if( bNumberNone ) + rType = NumberingType::NUMBER_NONE; + else + bRet = false; + } + else if( 1 == nLen ) + { + switch( rNumFmt[0] ) + { + case '1': rType = NumberingType::ARABIC; break; + case 'a': rType = NumberingType::CHARS_LOWER_LETTER; break; + case 'A': rType = NumberingType::CHARS_UPPER_LETTER; break; + case 'i': rType = NumberingType::ROMAN_LOWER; break; + case 'I': rType = NumberingType::ROMAN_UPPER; break; + default: bExt = true; break; + } + if( !bExt && IsXMLToken( rNumLetterSync, XML_TRUE ) ) + { + switch( rType ) + { + case NumberingType::CHARS_LOWER_LETTER: + rType = NumberingType::CHARS_LOWER_LETTER_N; + break; + case NumberingType::CHARS_UPPER_LETTER: + rType = NumberingType::CHARS_UPPER_LETTER_N; + break; + } + } + } + else + { + bExt = true; + } + if( bExt ) + { + Reference < XNumberingTypeInfo > xInfo = getNumTypeInfo(); + if( xInfo.is() && xInfo->hasNumberingType( rNumFmt ) ) + { + rType = xInfo->getNumberingType( rNumFmt ); + } + else + { + rType = NumberingType::ARABIC; + } + } + + return bRet; +} + +void SvXMLUnitConverter::convertNumFormat( OUStringBuffer& rBuffer, + sal_Int16 nType ) const +{ + enum XMLTokenEnum eFormat = XML_TOKEN_INVALID; + switch( nType ) + { + case NumberingType::CHARS_UPPER_LETTER: eFormat = XML_A_UPCASE; break; + case NumberingType::CHARS_LOWER_LETTER: eFormat = XML_A; break; + case NumberingType::ROMAN_UPPER: eFormat = XML_I_UPCASE; break; + case NumberingType::ROMAN_LOWER: eFormat = XML_I; break; + case NumberingType::ARABIC: eFormat = XML_1; break; + case NumberingType::CHARS_UPPER_LETTER_N: eFormat = XML_A_UPCASE; break; + case NumberingType::CHARS_LOWER_LETTER_N: eFormat = XML_A; break; + case NumberingType::NUMBER_NONE: eFormat = XML__EMPTY; break; + + case NumberingType::CHAR_SPECIAL: + case NumberingType::PAGE_DESCRIPTOR: + case NumberingType::BITMAP: + SAL_WARN_IF( eFormat == XML_TOKEN_INVALID, "xmloff", "invalid number format" ); + break; + default: + break; + } + + if( eFormat != XML_TOKEN_INVALID ) + { + rBuffer.append( GetXMLToken(eFormat) ); + } + else + { + Reference < XNumberingTypeInfo > xInfo = getNumTypeInfo(); + if( xInfo.is() ) + rBuffer.append( xInfo->getNumberingIdentifier( nType ) ); + } +} + +void SvXMLUnitConverter::convertNumLetterSync( OUStringBuffer& rBuffer, + sal_Int16 nType ) +{ + enum XMLTokenEnum eSync = XML_TOKEN_INVALID; + switch( nType ) + { + case NumberingType::CHARS_UPPER_LETTER: + case NumberingType::CHARS_LOWER_LETTER: + case NumberingType::ROMAN_UPPER: + case NumberingType::ROMAN_LOWER: + case NumberingType::ARABIC: + case NumberingType::NUMBER_NONE: + break; + + case NumberingType::CHARS_UPPER_LETTER_N: + case NumberingType::CHARS_LOWER_LETTER_N: + eSync = XML_TRUE; + break; + + case NumberingType::CHAR_SPECIAL: + case NumberingType::PAGE_DESCRIPTOR: + case NumberingType::BITMAP: + SAL_WARN_IF( eSync == XML_TOKEN_INVALID, "xmloff", "invalid number format" ); + break; + } + if( eSync != XML_TOKEN_INVALID ) + rBuffer.append( GetXMLToken(eSync) ); +} + +void SvXMLUnitConverter::convertPropertySet(uno::Sequence<beans::PropertyValue>& rProps, + const uno::Reference<beans::XPropertySet>& aProperties) +{ + uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = aProperties->getPropertySetInfo(); + if (xPropertySetInfo.is()) + { + const uno::Sequence< beans::Property > aProps = xPropertySetInfo->getProperties(); + if (aProps.hasElements()) + { + rProps.realloc(aProps.getLength()); + beans::PropertyValue* pProps = rProps.getArray(); + for (const auto& rProp : aProps) + { + pProps->Name = rProp.Name; + pProps->Value = aProperties->getPropertyValue(rProp.Name); + ++pProps; + } + } + } +} + +void SvXMLUnitConverter::convertPropertySet(uno::Reference<beans::XPropertySet> const & rProperties, + const uno::Sequence<beans::PropertyValue>& aProps) +{ + if (aProps.hasElements()) + { + uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = rProperties->getPropertySetInfo(); + if (xPropertySetInfo.is()) + { + for (const auto& rProp : aProps) + { + if (xPropertySetInfo->hasPropertyByName(rProp.Name)) + rProperties->setPropertyValue(rProp.Name, rProp.Value); + } + } + } +} + + +OUString SvXMLUnitConverter::encodeStyleName( + const OUString& rName, + bool *pEncoded ) const +{ + if( pEncoded ) + *pEncoded = false; + + sal_Int32 nLen = rName.getLength(); + OUStringBuffer aBuffer( nLen*2 ); + + for( sal_Int32 i = 0; i < nLen; i++ ) + { + sal_Unicode c = rName[i]; + bool bValidChar = false; + if( c < 0x00ffU ) + { + bValidChar = + (c >= 0x0041 && c <= 0x005a) || + (c >= 0x0061 && c <= 0x007a) || + (c >= 0x00c0 && c <= 0x00d6) || + (c >= 0x00d8 && c <= 0x00f6) || + (c >= 0x00f8 && c <= 0x00ff) || + ( i > 0 && ( (c >= 0x0030 && c <= 0x0039) || + c == 0x00b7 || c == '-' || c == '.') ); + } + else + { + if( (c >= 0xf900U && c <= 0xfffeU) || + (c >= 0x20ddU && c <= 0x20e0U)) + { + bValidChar = false; + } + else if( (c >= 0x02bbU && c <= 0x02c1U) || c == 0x0559 || + c == 0x06e5 || c == 0x06e6 ) + { + bValidChar = true; + } + else if( c == 0x0387 ) + { + bValidChar = i > 0; + } + else + { + if (!m_pImpl->m_xCharClass.is()) + { + m_pImpl->m_xCharClass = CharacterClassification::create( m_pImpl->m_xContext ); + } + sal_Int16 nType = m_pImpl->m_xCharClass->getType(rName, i); + + switch( nType ) + { + case UnicodeType::UPPERCASE_LETTER: // Lu + case UnicodeType::LOWERCASE_LETTER: // Ll + case UnicodeType::TITLECASE_LETTER: // Lt + case UnicodeType::OTHER_LETTER: // Lo + case UnicodeType::LETTER_NUMBER: // Nl + bValidChar = true; + break; + case UnicodeType::NON_SPACING_MARK: // Ms + case UnicodeType::ENCLOSING_MARK: // Me + case UnicodeType::COMBINING_SPACING_MARK: //Mc + case UnicodeType::MODIFIER_LETTER: // Lm + case UnicodeType::DECIMAL_DIGIT_NUMBER: // Nd + bValidChar = i > 0; + break; + } + } + } + if( bValidChar ) + { + aBuffer.append( c ); + } + else + { + aBuffer.append( '_' ); + if( c > 0x0fff ) + aBuffer.append( static_cast< sal_Unicode >( + aHexTab[ (c >> 12) & 0x0f ] ) ); + if( c > 0x00ff ) + aBuffer.append( static_cast< sal_Unicode >( + aHexTab[ (c >> 8) & 0x0f ] ) ); + if( c > 0x000f ) + aBuffer.append( static_cast< sal_Unicode >( + aHexTab[ (c >> 4) & 0x0f ] ) ); + aBuffer.append( static_cast< sal_Unicode >( + aHexTab[ c & 0x0f ] ) ); + aBuffer.append( '_' ); + if( pEncoded ) + *pEncoded = true; + } + } + + // check for length + if( aBuffer.getLength() > ((1<<15)-1) ) + { + aBuffer = rName; + if( pEncoded ) + *pEncoded = false; + } + + + return aBuffer.makeStringAndClear(); +} + +/** convert string (hex) to number (sal_uInt32) */ +bool SvXMLUnitConverter::convertHex( sal_uInt32& nVal, + const OUString& rValue ) +{ + if( rValue.getLength() != 8 ) + return false; + + nVal = 0; + for ( int i = 0; i < 8; i++ ) + { + nVal = ( nVal << 4 ) + | sal::static_int_cast< sal_uInt32 >( lcl_gethex( rValue[i] ) ); + } + + return true; +} + +/** convert number (sal_uInt32) to string (hex) */ +void SvXMLUnitConverter::convertHex( OUStringBuffer& rBuffer, + sal_uInt32 nVal ) +{ + for ( int i = 0; i < 8; i++ ) + { + rBuffer.append( sal_Unicode( aHexTab[ nVal >> 28 ] ) ); + nVal <<= 4; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |