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 20 kB image not shown  

Quelle  SettingsExportHelper.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 <sax/tools/converter.hxx>

#include <xmloff/SettingsExportHelper.hxx>
#include <xmloff/xmltoken.hxx>
#include <rtl/ref.hxx>
#include <sal/log.hxx>
#include <tools/debug.hxx>
#include <comphelper/diagnose_ex.hxx>
#include <comphelper/base64.hxx>
#include <comphelper/extract.hxx>
#include <unotools/securityoptions.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 <comphelper/indexedpropertyvalues.hxx>
#include <xmloff/XMLSettingsExportContext.hxx>
#include "xmlenums.hxx"

using namespace ::com::sun::star;
using namespace ::xmloff::token;

constexpr OUStringLiteral gsPrinterIndependentLayout( u"PrinterIndependentLayout" );
constexpr OUStringLiteral gsColorTableURL( u"ColorTableURL" );
constexpr OUStringLiteral gsLineEndTableURL( u"LineEndTableURL" );
constexpr OUStringLiteral gsHatchTableURL( u"HatchTableURL" );
constexpr OUStringLiteral gsDashTableURL( u"DashTableURL" );
constexpr OUStringLiteral gsGradientTableURL( u"GradientTableURL" );
constexpr OUStringLiteral gsBitmapTableURL( u"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 (uno::Reference<container::XNameAccess> aNamed; aAny >>= aNamed)
            {
                exportNameAccess(aNamed, rName);
            }
            else if (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 (uno::Reference<i18n::XForbiddenCharacters> xForbChars; aAny >>= xForbChars)
            {
                exportForbiddenCharacters(xForbChars, rName);
            }
            else if( aType.equals(cppu::UnoType<uno::Sequence<formula::SymbolDescriptor>>::get() ) )
            {
                uno::Sequence< formula::SymbolDescriptor > aProps;
                aAny >>= aProps;
                exportSymbolDescriptors(aProps, rName);
            }
            else {
                SAL_WARN("xmloff""this type (" << aType.getTypeName() << ") 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&&nbsp;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 );
        bool bSkipPrinterSettings = SvtSecurityOptions::IsOptionSet(
                                        SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo)
                                    && !SvtSecurityOptions::IsOptionSet(
                                           SvtSecurityOptions::EOption::DocKeepPrinterSettings);
        for (const auto& rProp : aProps)
        {
            if (bSkipPrinterSettings
                && (rProp.Name == "PrinterSetup" || rProp.Name == "PrinterName"))
                continue;
            CallTypeFunction(rProp.Value, rProp.Name);
        }
        m_rContext.EndElement( true );
    }
}
void XMLSettingsExportHelper::exportSymbolDescriptors(
                    const uno::Sequence < formula::SymbolDescriptor > &rProps,
                    const OUString& rName) const
{
    rtl::Reference< comphelper::IndexedPropertyValuesContainer > xBox = new comphelper::IndexedPropertyValuesContainer();

    static constexpr OUStringLiteral sName     ( u"Name" );
    static constexpr OUStringLiteral sExportName ( u"ExportName" );
    static constexpr OUStringLiteral sSymbolSet ( u"SymbolSet" );
    static constexpr OUStringLiteral sCharacter ( u"Character" );
    static constexpr OUStringLiteral sFontName ( u"FontName" );
    static constexpr OUStringLiteral sCharSet  ( u"CharSet" );
    static constexpr OUStringLiteral sFamily   ( u"Family" );
    static constexpr OUStringLiteral sPitch    ( u"Pitch" );
    static constexpr OUStringLiteral sWeight   ( u"Weight" );
    static constexpr OUStringLiteral sItalic   ( u"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::Any( 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 : 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), u""_ustr, false);
        }
        m_rContext.EndElement( true );
    }
}

void XMLSettingsExportHelper::exportForbiddenCharacters(
                    const uno::Reference<i18n::XForbiddenCharacters>& xForbChars,
                    const OUString& rName) const
{
    uno::Reference<linguistic2::XSupportedLocales> xLocales(xForbChars, css::uno::UNO_QUERY);

    SAL_WARN_IF( !(xForbChars.is() && xLocales.is()), "xmloff","XMLSettingsExportHelper::exportForbiddenCharacters: got illegal forbidden characters!" );

    if( !xForbChars.is() || !xLocales.is() )
        return;

    rtl::Reference< comphelper::IndexedPropertyValuesContainer > xBox = new comphelper::IndexedPropertyValuesContainer();
    const uno::Sequence< lang::Locale > aLocales( xLocales->getLocales() );

    /* FIXME-BCP47: this stupid and counterpart in
     * xmloff/source/core/DocumentSettingsContext.cxx
     * XMLConfigItemMapIndexedContext::EndElement() */


    static constexpr OUStringLiteral sLanguage  ( u"Language" );
    static constexpr OUStringLiteral sCountry   ( u"Country" );
    static constexpr OUStringLiteral sVariant   ( u"Variant" );
    static constexpr OUStringLiteral sBeginLine ( u"BeginLine" );
    static constexpr OUStringLiteral sEndLine   ( u"EndLine" );

    sal_Int32 nPos = 0;
    forconst 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::Any( 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, std::u16string_view rName ) const
{
    if( rName == gsPrinterIndependentLayout )
    {
        sal_Int16 nTmp = sal_Int16();
        if( rAny >>= nTmp )
        {
            if( nTmp == document::PrinterIndependentLayout::LOW_RESOLUTION )
                rAny <<= u"low-resolution"_ustr;
            else if( nTmp == document::PrinterIndependentLayout::DISABLED )
                rAny <<= u"disabled"_ustr;
            else if( nTmp == document::PrinterIndependentLayout::HIGH_RESOLUTION )
                rAny <<= u"high-resolution"_ustr;
        }
    }
    else if( (rName == gsColorTableURL) || (rName == gsLineEndTableURL) || (rName == gsHatchTableURL) ||
             (rName == gsDashTableURL) || (rName == gsGradientTableURL) || (rName == gsBitmapTableURL ) )
    {
        if( !mxStringSubstitution.is() )
        {
            try
            {
                const_cast< XMLSettingsExportHelper* >(this)->mxStringSubstitution =
                    util::PathSubstitution::create( m_rContext.GetComponentContext() );
            }
            catch( uno::Exception& )
            {
                DBG_UNHANDLED_EXCEPTION("xmloff.core");
            }
        }

        if( mxStringSubstitution.is() )
        {
            OUString aURL;
            rAny >>= aURL;
            aURL = mxStringSubstitution->reSubstituteVariables( aURL );
            rAny <<= aURL;
        }
    }
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

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

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet)  ¤

*© 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.