Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/xmloff/source/core/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 86 kB image not shown  

Quelle  xmlexp.cxx   Sprache: C

 
/* -*- 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 <config_wasm_strip.h>

#include <memory>
#include <sal/config.h>
#include <sal/log.hxx>

#include <mutex>
#include <stack>
#include <optional>
#include <utility>

#include <xmloff/unointerfacetouniqueidentifiermapper.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/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 <comphelper/propertyvalue.hxx>
#include <xmloff/namespacemap.hxx>
#include <xmloff/xmluconv.hxx>
#include <xmloff/xmlnamespace.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 <com/sun/star/frame/XModule.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 <comphelper/SetFlagContextHelper.hxx>
#include <PropertySetMerger.hxx>
#include <docmodel/theme/Theme.hxx>
#include <o3tl/enumrange.hxx>
#include <sax/tools/converter.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/XEncryptionProtectedStorage.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 ::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;

constexpr OUString XML_MODEL_SERVICE_WRITER = u"com.sun.star.text.TextDocument"_ustr;
constexpr OUString XML_MODEL_SERVICE_CALC = u"com.sun.star.sheet.SpreadsheetDocument"_ustr;
constexpr OUString XML_MODEL_SERVICE_DRAW = u"com.sun.star.drawing.DrawingDocument"_ustr;
constexpr OUString XML_MODEL_SERVICE_IMPRESS = u"com.sun.star.presentation.PresentationDocument"_ustr;
constexpr OUString XML_MODEL_SERVICE_MATH = u"com.sun.star.formula.FormulaProperties"_ustr;
constexpr OUString XML_MODEL_SERVICE_CHART = u"com.sun.star.chart.ChartDocument"_ustr;

constexpr OUStringLiteral XML_USEPRETTYPRINTING = u"UsePrettyPrinting";

constexpr OUString XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE = u"vnd.sun.star.GraphicObject:"_ustr;
constexpr OUString XML_EMBEDDEDOBJECT_URL_BASE = u"vnd.sun.star.EmbeddedObject:"_ustr;

const std::pair<OUString, OUString> aServiceMap[] = {
    { XML_MODEL_SERVICE_WRITER, XML_EXPORT_FILTER_WRITER },
    { XML_MODEL_SERVICE_CALC, XML_EXPORT_FILTER_CALC },
    { XML_MODEL_SERVICE_IMPRESS, XML_EXPORT_FILTER_IMPRESS }, // Impress supports DrawingDocument,
    { XML_MODEL_SERVICE_DRAW, XML_EXPORT_FILTER_DRAW }, // too, so it must appear before Draw
    { XML_MODEL_SERVICE_MATH, XML_EXPORT_FILTER_MATH },
    { XML_MODEL_SERVICE_CHART, XML_EXPORT_FILTER_CHART },
};

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;

    std::optional<SvtSaveOptions::ODFSaneDefaultVersion> m_oODFVersion;

    /// 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>, tools::Long > > mNamespaceMaps;
    /// counts depth (number of open elements/start tags)
    tools::Long mDepth;

    ::std::unique_ptr< ::xmloff::RDFaExportHelper> mpRDFaHelper;

    bool                                                mbExportTextNumberElement;
    bool                                                mbNullDateInitialized;

    void SetSchemeOf( std::u16string_view rOrigFileName )
    {
        size_t nSep = rOrigFileName.find(':');
        if( nSep != std::u16string_view::npos )
            msPackageURIScheme = rOrigFileName.substr( 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() )
        return;

    meModelType = SvtModuleOptions::ClassifyFactoryByModel( mxModel );

    // note: MATH documents will throw NotInitializedException; maybe unit test problem
    if (meModelType == SvtModuleOptions::EFactory::WRITER)
    {
        uno::Reference<frame::XModule> const xModule(mxModel, uno::UNO_QUERY);
        bool const isBaseForm(xModule.is() &&
            xModule->getIdentifier() == "com.sun.star.sdb.FormDesign");
        if (isBaseForm)
        {
            switch (GetODFSaneDefaultVersion())
            {
                case SvtSaveOptions::ODFSVER_013_EXTENDED:
                    SAL_INFO("xmloff.core""tdf#138209 force form export to ODF 1.2");
                    mpImpl->m_oODFVersion = SvtSaveOptions::ODFSVER_012_EXTENDED;
                    maUnitConv.overrideSaneDefaultVersion(SvtSaveOptions::ODFSVER_012_EXTENDED);
                    break;
                case SvtSaveOptions::ODFSVER_013:
                    SAL_INFO("xmloff.core""tdf#138209 force form export to ODF 1.2");
                    mpImpl->m_oODFVersion = SvtSaveOptions::ODFSVER_012;
                    maUnitConv.overrideSaneDefaultVersion(SvtSaveOptions::ODFSVER_012);
                    break;
                default:
                    break;
            }
        }
    }
}

SvXMLExport::SvXMLExport(
    const uno::Reference< uno::XComponentContext >& xContext,
    OUString implementationName,
    sal_Int16 const eDefaultMeasureUnit /*css::util::MeasureUnit*/,
    const enum XMLTokenEnum eClass, SvXMLExportFlags nExportFlags )
:   mpImpl( new SvXMLExport_Impl ),
    m_xContext(xContext), m_implementationName(std::move(implementationName)),
    mxAttrList( new comphelper::AttributeList ),
    mpNamespaceMap( new SvXMLNamespaceMap ),
    mpAuthorIDs( new SvtSecurityMapPersonalInfo ),
    maUnitConv(xContext, util::MeasureUnit::MM_100TH, eDefaultMeasureUnit, getSaneDefaultVersion()),
    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 implementationName,
    OUString fileName,
    sal_Int16 const eDefaultMeasureUnit /*css::util::MeasureUnit*/,
    const uno::Reference< xml::sax::XDocumentHandler > & rHandler)
:   mpImpl( new SvXMLExport_Impl ),
    m_xContext(xContext), m_implementationName(std::move(implementationName)),
    mxHandler( rHandler ),
    mxExtHandler( rHandler, uno::UNO_QUERY ),
    mxAttrList( new comphelper::AttributeList ),
    msOrigFileName(std::move( fileName )),
    mpNamespaceMap( new SvXMLNamespaceMap ),
    mpAuthorIDs( new SvtSecurityMapPersonalInfo ),
    maUnitConv(xContext, util::MeasureUnit::MM_100TH, eDefaultMeasureUnit, getSaneDefaultVersion()),
    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 implementationName,
    OUString fileName,
    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(std::move(implementationName)),
    mxModel( rModel ),
    mxHandler( rHandler ),
    mxExtHandler( rHandler, uno::UNO_QUERY ),
    mxNumberFormatsSupplier (rModel, uno::UNO_QUERY),
    mxAttrList( new comphelper::AttributeList ),
    msOrigFileName(std::move( fileName )),
    mpNamespaceMap( new SvXMLNamespaceMap ),
    mpAuthorIDs( new SvtSecurityMapPersonalInfo ),
    maUnitConv( xContext,
                util::MeasureUnit::MM_100TH,
                SvXMLUnitConverter::GetMeasureUnit(eDefaultFieldUnit),
                getSaneDefaultVersion()),
    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)
                {
                    static constexpr OUString sProgressMax(XML_PROGRESSMAX);
                    static constexpr OUString sProgressCurrent(XML_PROGRESSCURRENT);
                    static constexpr 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::Any(mpProgressBarHelper->GetRepeat()));
                }
                if (mpNumExport && (mnExportFlags & (SvXMLExportFlags::AUTOSTYLES | SvXMLExportFlags::STYLES)))
                {
                    static constexpr 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 >&&nbsp;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(u"com.sun.star.xml.NamespaceMap"_ustr);
            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.

    forconst auto& rAny : aArguments )
    {
        Reference<XInterface> xValue;
        rAny >>= xValue;

        // status indicator
        uno::Reference<task::XStatusIndicator> xTmpStatus( xValue, UNO_QUERY );
        if ( xTmpStatus.is() )
            mxStatusIndicator = std::move(xTmpStatus);

        // graphic storage handler
        uno::Reference<document::XGraphicStorageHandler> xGraphicStorageHandler(xValue, UNO_QUERY);
        if (xGraphicStorageHandler.is())
            mxGraphicStorageHandler = std::move(xGraphicStorageHandler);

        // object resolver
        uno::Reference<document::XEmbeddedObjectResolver> xTmpObjectResolver(
            xValue, UNO_QUERY );
        if ( xTmpObjectResolver.is() )
            mxEmbeddedResolver = std::move(xTmpObjectResolver);

        // document handler
        uno::Reference<xml::sax::XDocumentHandler> xTmpDocHandler(
            xValue, UNO_QUERY );
        if( xTmpDocHandler.is() )
        {
            mxHandler = std::move(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 = std::move(xTmpPropertySet);
    }

    if( !mxExportInfo.is() )
        return;

    uno::Reference< beans::XPropertySetInfo > xPropertySetInfo =
        mxExportInfo->getPropertySetInfo();
    static constexpr OUString sBaseURI = u"BaseURI"_ustr;
    if( xPropertySetInfo->hasPropertyByName(sBaseURI) )
    {
        uno::Any aAny = mxExportInfo->getPropertyValue(sBaseURI);
        aAny >>= msOrigFileName;
        mpImpl->msPackageURI = msOrigFileName;
        mpImpl->SetSchemeOf( msOrigFileName );
    }
    OUString sRelPath;
    static constexpr OUString sStreamRelPath = u"StreamRelPath"_ustr;
    if( xPropertySetInfo->hasPropertyByName(sStreamRelPath) )
    {
        uno::Any aAny = mxExportInfo->getPropertyValue(sStreamRelPath);
        aAny >>= sRelPath;
    }
    OUString sName;
    static constexpr OUString sStreamName = u"StreamName"_ustr;
    if( xPropertySetInfo->hasPropertyByName(sStreamName) )
    {
        uno::Any aAny = mxExportInfo->getPropertyValue(sStreamName);
        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#)
    static constexpr OUString sOutlineStyleAsNormalListStyle(
            u"OutlineStyleAsNormalListStyle"_ustr );
    if( xPropertySetInfo->hasPropertyByName( sOutlineStyleAsNormalListStyle ) )
    {
        uno::Any aAny = mxExportInfo->getPropertyValue( sOutlineStyleAsNormalListStyle );
        aAny >>= mpImpl->mbOutlineStyleAsNormalListStyle;
    }

    OUString sTargetStorage( u"TargetStorage"_ustr );
    if( xPropertySetInfo->hasPropertyByName( sTargetStorage ) )
        mxExportInfo->getPropertyValue( sTargetStorage ) >>= mpImpl->mxTargetStorage;

    static constexpr OUString sExportTextNumberElement(
            u"ExportTextNumberElement"_ustr );
    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

            forconst 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;
                }
            }
        }

        forconst 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 { u"com.sun.star.document.ExportFilter"_ustr, u"com.sun.star.xml.XMLExportFilter"_ustr };
}

OUString
SvXMLExport::EnsureNamespace(OUString const & i_rNamespace)
{
    static constexpr OUString aPreferredPrefix(u"gen"_ustr);
    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 );
        while( nKey != USHRT_MAX )
        {
            sPrefix = aPreferredPrefix + OUString::number(++n);
            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 );
        AddAttribute( GetXMLToken(XML_XMLNS) + ":" + sPrefix, i_rNamespace );
    }
    else
    {
        // If there is a prefix for the namespace, reuse that.
        sPrefix = GetNamespaceMap_().GetPrefixByKey( nKey );
    }
    return sPrefix;
}

void SvXMLExport::AddAttribute( sal_uInt16 nPrefixKey, const OUString& rName,
                              const OUString& rValue )
{
    AddAttribute(GetNamespaceMap_().GetQNameByKey(nPrefixKey, rName), rValue);
}

void SvXMLExport::AddAttribute( sal_uInt16 nPrefixKey,
                                enum XMLTokenEnum eName,
                                const OUString& rValue )
{
    AddAttribute(nPrefixKey, GetXMLToken(eName), rValue);
}

void SvXMLExport::AddAttribute( sal_uInt16 nPrefixKey,
                                enum XMLTokenEnum eName,
                                enum XMLTokenEnum eValue)
{
    AddAttribute(nPrefixKey, 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 )
{
    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 >&&nbsp;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,
                                truetrue );

        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,
                                truetrue );

        ExportStyles_( false );
    }

    // transfer style names (+ families) TO other components (if appropriate)
    if( ( mnExportFlags & SvXMLExportFlags::CONTENT ) || !mxExportInfo.is() )
        return;

    static constexpr OUString sStyleNames( u"StyleNames"_ustr );
    static constexpr OUString sStyleFamilies( u"StyleFamilies"_ustr );
    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, Any( aStyleNames ) );
        mxExportInfo->setPropertyValue( sStyleFamilies,
                                       Any( aStyleFamilies ) );
    }
}

void SvXMLExport::ImplExportAutoStyles()
{
    // transfer style names (+ families) FROM other components (if appropriate)
    OUString sStyleNames( u"StyleNames"_ustr );
    OUString sStyleFamilies( u"StyleFamilies"_ustr );
    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, truetrue );

        ExportAutoStyles_();
    }
}

void SvXMLExport::ImplExportMasterStyles()
{
    // <style:master-styles>
    SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_MASTER_STYLES,
                            truetrue );

    ExportMasterStyles_();
}

void SvXMLExport::ImplExportContent()
{
    CheckAttrList();

    {
        SvXMLElementExport aElement( *this, XML_NAMESPACE_OFFICE, XML_BODY,
                                  truetrue );
        {
            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,
                                        truetrue );

            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;
        defaultbreak;
    }

    // #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
}

// note: the point of this is presumably to mitigate SHA/1k info leak of plain text
void SvXMLExport::addChaffWhenEncryptedStorage()
{
    uno::Reference<embed::XEncryptionProtectedStorage> const xEncr(mpImpl->mxTargetStorage, uno::UNO_QUERY);

    if (xEncr.is() && xEncr->hasEncryptionData() && mxExtHandler.is())
    {
        uno::Sequence<beans::NamedValue> const algo(xEncr->getEncryptionAlgorithms());
        for (auto const& it : algo)
        {
            if (it.Name == "ChecksumAlgorithm")
            {
                if (!it.Value.hasValue())
                {
                    return// no checksum => no chaff
                }
                break;
            }
        }
        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_014_EXTENDED: [[fallthrough]];
    case SvtSaveOptions::ODFSVER_014: pVersion = "1.4"break;
    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(
                        getComponentContext()->getServiceManager()->createInstanceWithArgumentsAndContext(
                        u"com.sun.star.comp.Svx.GraphicExportHelper"_ustr, uno::Sequence<uno::Any>(), getComponentContext()),
                        uno::UNO_QUERY );
                    bOwnGraphicResolver = mxGraphicStorageHandler.is();
                }

                if( !mxEmbeddedResolver.is() )
                {
                    mxEmbeddedResolver.set(
                        xFactory->createInstance( u"com.sun.star.document.ExportEmbeddedObjectResolver"_ustr ), UNO_QUERY);
                    bOwnEmbeddedResolver = mxEmbeddedResolver.is();
                }
            }
            catch(const css::uno::Exception&)
            {
            }
        }
    }
    if( (getExportFlags() & SvXMLExportFlags::OASIS) == SvXMLExportFlags::NONE )
    {
        try
        {
            static ::comphelper::PropertyMapEntry const aInfoMap[] =
            {
                { u"Class"_ustr, 0,
                    ::cppu::UnoType<OUString>::get(),
                      PropertyAttribute::MAYBEVOID, 0},
            };
            Reference< XPropertySet > xConvPropSet(
                ::comphelper::GenericPropertySet_CreateInstance(
                        new ::comphelper::PropertySetInfo( aInfoMap ) ) );

            xConvPropSet->setPropertyValue( u"Class"_ustr, Any(GetXMLToken( eClass )) );

            Reference< XPropertySet > xPropSet =
                mxExportInfo.is()
                ?  PropertySetMerger_CreateInstance( mxExportInfo,
                                                     xConvPropSet )
                : xConvPropSet;

            Sequence<Any> aArgs{ Any(mxHandler), Any(xPropSet), Any(mxModel) };
            // get filter component
            Reference< xml::sax::XDocumentHandler > xTmpDocHandler(
                m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(u"com.sun.star.comp.Oasis2OOoTransformer"_ustr, aArgs, m_xContext),
                UNO_QUERY);
            SAL_WARN_IF(!xTmpDocHandler.is(), "xmloff.core""can't instantiate OASIS transformer component" );
            if( xTmpDocHandler.is() )
            {
                mxHandler = std::move(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, truetrue );

        // 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->Clear();
}

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,
                                truetrue );
        {
    // 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,
                                      truetrue );
            Characters(generator);
        }
    }
}

void SvXMLExport::ExportScripts_()
{
    SvXMLElementExport aElement( *this, XML_NAMESPACE_OFFICE, XML_SCRIPTS, truetrue );

    // 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, truetrue );

        // initialize Basic
        if ( mxModel.is() )
        {
            Reference< beans::XPropertySet > xPSet( mxModel, UNO_QUERY );
            if ( xPSet.is() )
                xPSet->getPropertyValue(u"BasicLibraries"_ustr);
        }

        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())
        return;

    // export (fill-)gradient-styles
    try
    {
        uno::Reference< container::XNameAccess > xGradient( xFact->createInstance(u"com.sun.star.drawing.GradientTable"_ustr), uno::UNO_QUERY );
        if( xGradient.is() )
        {
            XMLGradientStyleExport aGradientStyle( *this );

            if( xGradient->hasElements() )
            {
                const uno::Sequence< OUString > aNamesSeq ( xGradient->getElementNames() );
                forconst 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(u"com.sun.star.drawing.HatchTable"_ustr), uno::UNO_QUERY );
        if( xHatch.is() )
        {
            XMLHatchStyleExport aHatchStyle( *this );

            if( xHatch->hasElements() )
            {
                const uno::Sequence< OUString > aNamesSeq ( xHatch->getElementNames() );
                forconst 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(u"com.sun.star.drawing.BitmapTable"_ustr), uno::UNO_QUERY );
        if( xBitmap.is() )
        {
            if( xBitmap->hasElements() )
            {
                const uno::Sequence< OUString > aNamesSeq ( xBitmap->getElementNames() );
                forconst 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(u"com.sun.star.drawing.TransparencyGradientTable"_ustr), uno::UNO_QUERY );
        if( xTransGradient.is() )
        {
            XMLTransGradientStyleExport aTransGradientstyle( *this );

            if( xTransGradient->hasElements() )
            {
                const uno::Sequence< OUString > aNamesSeq ( xTransGradient->getElementNames() );
                forconst 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(u"com.sun.star.drawing.MarkerTable"_ustr), uno::UNO_QUERY );
        if( xMarker.is() )
        {
            XMLMarkerStyleExport aMarkerStyle( *this );

            if( xMarker->hasElements() )
            {
                const uno::Sequence< OUString > aNamesSeq ( xMarker->getElementNames() );
                forconst 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(u"com.sun.star.drawing.DashTable"_ustr), uno::UNO_QUERY );
        if( xDashes.is() )
        {
            XMLDashStyleExport aDashStyle( *this );

            if( xDashes->hasElements() )
            {
                const uno::Sequence< OUString > aNamesSeq ( xDashes->getElementNames() );
                forconst OUString& rStrName : aNamesSeq )
                {
                    try
                    {
                        uno::Any aValue = xDashes->getByName( rStrName );

                        aDashStyle.exportXML( rStrName, aValue );
                    }
                    catch(const container::NoSuchElementException&)
                    {
                    }
                }
            }
        }
    }
    catch(const lang::ServiceNotRegisteredException&)
    {
    }
}

void SvXMLExport::ExportThemeElement(std::shared_ptr<model::Theme> const& pTheme)
{
    if (!pTheme)
        return;

    if (!pTheme->GetName().isEmpty())
        AddAttribute(XML_NAMESPACE_LO_EXT, XML_NAME, pTheme->GetName());
    SvXMLElementExport aTheme(*this, XML_NAMESPACE_LO_EXT, XML_THEME, truetrue);

    auto pColorSet = pTheme->getColorSet();
    if (!pColorSet)
        return;
    if (!pColorSet->getName().isEmpty())
        AddAttribute(XML_NAMESPACE_LO_EXT, XML_NAME, pColorSet->getName());
    SvXMLElementExport aColorTable(*this, XML_NAMESPACE_LO_EXT, XML_THEME_COLORS, truetrue);

    static const XMLTokenEnum aColorTokens[] =
    {
        XML_DARK1, // Text 1
        XML_LIGHT1, // Background 1
        XML_DARK2, // Text 2
        XML_LIGHT2, // Background 2
        XML_ACCENT1,
        XML_ACCENT2,
        XML_ACCENT3,
        XML_ACCENT4,
        XML_ACCENT5,
        XML_ACCENT6,
        XML_HYPERLINK, // Hyperlink
        XML_FOLLOWED_HYPERLINK, // Followed hyperlink
    };

    for (auto eThemeColorType : o3tl::enumrange<model::ThemeColorType>())
    {
        if (eThemeColorType == model::ThemeColorType::Unknown)
            continue;

        auto nColor = size_t(eThemeColorType);
        AddAttribute(XML_NAMESPACE_LO_EXT, XML_NAME, GetXMLToken(aColorTokens[nColor]));
        OUStringBuffer sValue;
        sax::Converter::convertColor(sValue, pColorSet->getColor(eThemeColorType));
        AddAttribute(XML_NAMESPACE_LO_EXT, XML_COLOR, sValue.makeStringAndClear());
        SvXMLElementExport aColor(*this, XML_NAMESPACE_LO_EXT, XML_COLOR, truetrue);
    }
}

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()
{
// WASM_CHART change
// TODO: With Chart extracted this cannot really happen since
// no Chart could've been added at all
#if !ENABLE_WASM_STRIP_CHART
    return new SchXMLExportHelper(*this, *GetAutoStylePool());
#else
    return nullptr;
#endif
}

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())
        return;

    uno::Reference<container::XIndexAccess> xIndexAccess;
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=94 H=96 G=94

¤ Dauer der Verarbeitung: 0.23 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.