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

Quelle  txtvfldi.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 .
 */



/** @#file
 *
 *  export of all variable related text fields (and database display field)
 */

#include <txtvfldi.hxx>
#include <xmloff/xmltoken.hxx>
#include <xmloff/txtimp.hxx>
#include <xmloff/xmlnamespace.hxx>
#include <xmloff/namespacemap.hxx>
#include <xmloff/i18nmap.hxx>
#include <xmloff/xmlimp.hxx>
#include <xmloff/xmluconv.hxx>
#include <xmloff/xmlement.hxx>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/text/SetVariableType.hpp>
#include <com/sun/star/text/XDependentTextField.hpp>
#include <com/sun/star/text/XTextFieldsSupplier.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/XPropertySetInfo.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/style/NumberingType.hpp>
#include <com/sun/star/container/XIndexReplace.hpp>

#include <sax/tools/converter.hxx>

#include <rtl/ustring.hxx>
#include <osl/diagnose.h>
#include <sal/log.hxx>

#include <tools/debug.hxx>
#include <comphelper/diagnose_ex.hxx>


// service names
constexpr char16_t sAPI_fieldmaster_prefix[] = u"com.sun.star.text.FieldMaster.";
constexpr OUString sAPI_get_expression = u"GetExpression"_ustr;
constexpr OUString sAPI_set_expression = u"SetExpression"_ustr;
constexpr OUString sAPI_user      = u"User"_ustr;
constexpr OUString sAPI_database  = u"com.sun.star.text.TextField.Database"_ustr;

// property names
constexpr OUString sAPI_content   = u"Content"_ustr;
constexpr OUString sAPI_sub_type  = u"SubType"_ustr;
constexpr OUString sAPI_number_format = u"NumberFormat"_ustr;
constexpr OUString sAPI_is_visible = u"IsVisible"_ustr;
constexpr OUString sAPI_current_presentation = u"CurrentPresentation"_ustr;


using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::text;
using namespace ::com::sun::star::style;
using namespace ::xmloff::token;


// XMLVarFieldImportContext: superclass for all variable related fields


XMLVarFieldImportContext::XMLVarFieldImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp,
    const OUString& pServiceName,
    bool bFormula, bool bFormulaDefault,
    bool bDescription, bool bHelp, bool bHint, bool bVisible,
    bool bIsDisplayFormula,
    bool bType, bool bStyle, bool bValue,
    bool bPresentation) :
        XMLTextFieldImportContext(rImport, rHlp, pServiceName),
        aValueHelper(rImport, rHlp, bType, bStyle, bValue, false),
        bDisplayFormula(false),
        bDisplayNone(false),
        bFormulaOK(false),
        bDescriptionOK(false),
        bHelpOK(false),
        bHintOK(false),
        bDisplayOK(false),
        bSetFormula(bFormula),
        bSetFormulaDefault(bFormulaDefault),
        bSetDescription(bDescription),
        bSetHelp(bHelp),
        bSetHint(bHint),
        bSetVisible(bVisible),
        bSetDisplayFormula(bIsDisplayFormula),
        bSetPresentation(bPresentation)
{
}

void XMLVarFieldImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
        case XML_ELEMENT(TEXT, XML_NAME):
            sName = OUString::fromUtf8(sAttrValue);
            bValid = true;      // we assume: field with name is valid!
            break;
        case XML_ELEMENT(TEXT, XML_DESCRIPTION):
            sDescription = OUString::fromUtf8(sAttrValue);
            bDescriptionOK = true;
            break;
        case XML_ELEMENT(TEXT, XML_HELP):
            sHelp = OUString::fromUtf8(sAttrValue);
            bHelpOK = true;
            break;
        case XML_ELEMENT(TEXT, XML_HINT):
            sHint = OUString::fromUtf8(sAttrValue);
            bHintOK = true;
            break;
        case XML_ELEMENT(TEXT, XML_FORMULA):
            {
                OUString sTmp;
                sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
                        GetKeyByAttrValueQName(OUString::fromUtf8(sAttrValue), &sTmp);
                if( XML_NAMESPACE_OOOW == nPrefix )
                {
                    sFormula = sTmp;
                    bFormulaOK = true;
                }
                else
                    sFormula = OUString::fromUtf8(sAttrValue);
            }
            break;
        case XML_ELEMENT(TEXT, XML_DISPLAY):
            if (IsXMLToken(sAttrValue, XML_FORMULA))
            {
                bDisplayFormula = true;
                bDisplayNone = false;
                bDisplayOK = true;
            }
            else if (IsXMLToken(sAttrValue, XML_VALUE))
            {
                bDisplayFormula = false;
                bDisplayNone = false;
                bDisplayOK = true;
            }
            else if (IsXMLToken(sAttrValue, XML_NONE))
            {
                bDisplayFormula = false;
                bDisplayNone = true;
                bDisplayOK = true;
            } // else: no change
            DBG_ASSERT(!(bDisplayFormula && bDisplayNone),
                       "illegal display values");
            break;
        default:
            // delegate all others to value helper
            aValueHelper.ProcessAttribute(nAttrToken, sAttrValue);
            break;
    }
}

void XMLVarFieldImportContext::PrepareField(
    const Reference<XPropertySet> & xPropertySet)
{
    // bSetName: not implemented

    if (bSetFormula)
    {
        if (!bFormulaOK && bSetFormulaDefault)
        {
            sFormula = GetContent();
            bFormulaOK = true;
        }

        if (bFormulaOK)
        {
            xPropertySet->setPropertyValue(sAPI_content, Any(sFormula));
        }
    }

    if (bSetDescription && bDescriptionOK)
    {
        xPropertySet->setPropertyValue(u"Hint"_ustr, Any(sDescription));
    }

    if (bSetHelp && bHelpOK)
    {
        xPropertySet->setPropertyValue(u"Help"_ustr, Any(sHelp));
    }

    if (bSetHint && bHintOK)
    {
        xPropertySet->setPropertyValue(u"Tooltip"_ustr, Any(sHint));
    }

    if (bSetVisible && bDisplayOK)
    {
        bool bTmp = !bDisplayNone;
        xPropertySet->setPropertyValue(sAPI_is_visible, Any(bTmp));
    }

    // workaround for #no-bug#: display formula by default
    if (xPropertySet->getPropertySetInfo()->
                hasPropertyByName(u"IsShowFormula"_ustr) &&
        !bSetDisplayFormula)
    {
        bDisplayFormula = false;
        bSetDisplayFormula = true;
    }


    if (bSetDisplayFormula)
    {
        bool bTmp = bDisplayFormula && bDisplayOK;
        xPropertySet->setPropertyValue(u"IsShowFormula"_ustr, Any(bTmp));
    }

    // delegate to value helper
    aValueHelper.SetDefault(GetContent());
    aValueHelper.PrepareField(xPropertySet);

    // finally, set the current presentation
    if (bSetPresentation)
    {
        Any aAny;
        aAny <<= GetContent();
        xPropertySet->setPropertyValue(sAPI_current_presentation, aAny);
    }
}


// variable set fields


XMLSetVarFieldImportContext::XMLSetVarFieldImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp,
    const OUString& pServiceName, VarType eVarType,
    bool bFormula, bool bFormulaDefault,
    bool bDescription, bool bHelp, bool bHint, bool bVisible, bool bIsDisplayFormula,
    bool bType, bool bStyle, bool bValue, bool bPresentation) :
        XMLVarFieldImportContext(rImport, rHlp, pServiceName,
                                 bFormula, bFormulaDefault,
                                 bDescription, bHelp, bHint, bVisible, bIsDisplayFormula,
                                 bType, bStyle, bValue, bPresentation),
        eFieldType(eVarType)
{
}

void XMLSetVarFieldImportContext::endFastElement(sal_Int32 )
{
    // should we call PrepareField on the field, or rather on it's master?
    // currently: call on field (just like superclass)
    // possible alternatives: call on master
    //                        call field or master depending on variable
    //                        PrepareMaster() in addition to PrepareField()

    DBG_ASSERT(!GetServiceName().isEmpty(), "no service name for element!");

    if (bValid)
    {
        DBG_ASSERT(!GetName().isEmpty(), "variable name needed!");

        // find field master
        Reference<XPropertySet> xMaster;
        if (FindFieldMaster(xMaster))
        {
            // create field/Service
            Reference<XPropertySet> xPropSet;
            if (CreateField(xPropSet, "com.sun.star.text.TextField." + GetServiceName()))
            {
                Reference<XDependentTextField> xDepTextField(xPropSet, UNO_QUERY);
                if (xDepTextField.is())
                {
                    // attach field to field master
                    xDepTextField->attachTextFieldMaster(xMaster);

                    // attach field to document
                    Reference<XTextContent> xTextContent(xPropSet, UNO_QUERY);
                    if (xTextContent.is())
                    {
                        try {
                        // insert, set field properties and exit!
                        GetImportHelper().InsertTextContent(xTextContent);
                        PrepareField(xPropSet);
                        } catch (lang::IllegalArgumentException & /*e*/)
                        {
                            // ignore e: #i54023#
                        };
                        return;
                    }
                }
            }
        }
    }

    // above: exit on success; so for all error cases we end up here!
    // write element content
    GetImportHelper().InsertString(GetContent());
}

bool XMLSetVarFieldImportContext::FindFieldMaster(
    Reference<XPropertySet> & xMaster)
{
    // currently: delegate to XMLVariableDeclImportContext;
    // should eventually go here
    return XMLVariableDeclImportContext::FindFieldMaster(xMaster,
                                                         GetImport(),
                                                         GetImportHelper(),
                                                         GetName(),
                                                         eFieldType);
}


// sequence field


XMLSequenceFieldImportContext::XMLSequenceFieldImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp) :
        XMLSetVarFieldImportContext(rImport, rHlp, sAPI_set_expression,
                                    VarTypeSequence,
                                    // formula
                                    truetrue,
                                    falsefalsefalsefalse,
                                    false,
                                    falsefalsefalsetrue),

        sNumFormat(OUString('1')),
        sNumFormatSync(GetXMLToken(XML_FALSE)),
        bRefNameOK(false)
{
}

void XMLSequenceFieldImportContext::ProcessAttribute(
    sal_Int32 nAttrToken, std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
        case XML_ELEMENT(STYLE, XML_NUM_FORMAT):
            sNumFormat = OUString::fromUtf8(sAttrValue);
            break;
        case XML_ELEMENT(STYLE, XML_NUM_LETTER_SYNC):
            sNumFormatSync = OUString::fromUtf8(sAttrValue);
            break;
        case XML_ELEMENT(TEXT, XML_REF_NAME):
            sRefName = OUString::fromUtf8(sAttrValue);
            bRefNameOK = true;
            break;
        default:
            // delegate to super class (name, formula)
            XMLSetVarFieldImportContext::ProcessAttribute(nAttrToken,
                                                          sAttrValue);
            break;
    } // switch
}

void XMLSequenceFieldImportContext::PrepareField(
    const Reference<XPropertySet> & xPropertySet)
{
    // delegate to super class (formula)
    XMLSetVarFieldImportContext::PrepareField(xPropertySet);

    // set format
    sal_Int16 nNumType = NumberingType::ARABIC;
    GetImport().GetMM100UnitConverter().convertNumFormat( nNumType, sNumFormat, sNumFormatSync );
    xPropertySet->setPropertyValue(sAPI_number_format, Any(nNumType));

    // handle reference name
    if (bRefNameOK)
    {
        Any aAny = xPropertySet->getPropertyValue(u"SequenceValue"_ustr);
        sal_Int16 nValue = 0;
        aAny >>= nValue;
        GetImportHelper().InsertSequenceID(sRefName, GetName(), nValue);
    }
}


// variable set field


XMLVariableSetFieldImportContext::XMLVariableSetFieldImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp) :
        XMLSetVarFieldImportContext(rImport, rHlp, sAPI_set_expression,
                                    VarTypeSimple,
                                    // formula, value&type, style,
                                    // display none
                                    truetrue,
                                    falsefalsefalse,
                                    truefalse,
                                    truetruetrue,
                                    true)
{
}

void XMLVariableSetFieldImportContext::PrepareField(
        const Reference<XPropertySet> & xPropertySet)
{
    // set type
    Any aAny;
    aAny <<= (IsStringValue()? SetVariableType::STRING : SetVariableType::VAR);
    xPropertySet->setPropertyValue(sAPI_sub_type, aAny);

    // the remainder is handled by super class
    XMLSetVarFieldImportContext::PrepareField(xPropertySet);
}


// variable input field


XMLVariableInputFieldImportContext::XMLVariableInputFieldImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp) :
        XMLSetVarFieldImportContext(rImport, rHlp, sAPI_set_expression,
                                    VarTypeSimple,
                                    // description, display none/formula,
                                    // value&type, style, formula
                                    truetrue,
                                    truetruetrue,
                                    truefalse,
                                    truetruetrue,
                                    true)
{
}

void XMLVariableInputFieldImportContext::PrepareField(
        const Reference<XPropertySet> & xPropertySet)
{
    // set type (input field)
    Any aAny;
    xPropertySet->setPropertyValue(u"Input"_ustr, Any(true));

    // set type
    aAny <<= (IsStringValue()? SetVariableType::STRING : SetVariableType::VAR);
    xPropertySet->setPropertyValue(sAPI_sub_type, aAny);

    // the remainder is handled by super class
    XMLSetVarFieldImportContext::PrepareField(xPropertySet);
}


// user field


XMLUserFieldImportContext::XMLUserFieldImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp) :
        XMLSetVarFieldImportContext(rImport, rHlp, sAPI_user,
                                    VarTypeUserField,
                                    // display none/formula, style
                                    falsefalse,
                                    falsefalsefalsetrue,
                                    true,
                                    falsetruefalse,
                                    false)
{
}


// user input field


// bug: doesn't work (SO API lacking)
XMLUserFieldInputImportContext::XMLUserFieldInputImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp) :
        XMLVarFieldImportContext(rImport, rHlp, u"InputUser"_ustr,
                                 // description, style
                                 falsefalse,
                                 truefalsefalse,
                                 falsefalse,
                                 false /*???*/, true, false,
                                 false)
{
}

void XMLUserFieldInputImportContext::PrepareField(
    const Reference<XPropertySet> & xPropertySet)
{
    xPropertySet->setPropertyValue(sAPI_content, Any(GetName()));

    // delegate to super class
    XMLVarFieldImportContext::PrepareField(xPropertySet);
}


// variable get field


XMLVariableGetFieldImportContext::XMLVariableGetFieldImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp) :
        XMLVarFieldImportContext(rImport, rHlp, sAPI_get_expression,
                                 // style, display formula
                                 falsefalse,
                                 falsefalsefalse,
                                 falsetrue,
                                 truetruefalse,
                                 true)
{
}

void XMLVariableGetFieldImportContext::PrepareField(
        const Reference<XPropertySet> & xPropertySet)
{
    // set name
    xPropertySet->setPropertyValue(sAPI_content, Any(GetName()));

    // the remainder is handled by super class
    XMLVarFieldImportContext::PrepareField(xPropertySet);
}


// expression field


XMLExpressionFieldImportContext::XMLExpressionFieldImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp) :
        XMLVarFieldImportContext(rImport, rHlp, sAPI_get_expression,
                                 // formula, type, style, display formula
                                 truetrue,
                                 falsefalsefalse,
                                 falsetrue,
                                 truetruefalse,
                                 true)
{
    bValid = true;  // always valid
}


void XMLExpressionFieldImportContext::PrepareField(
    const Reference<XPropertySet> & xPropertySet)
{
    xPropertySet->setPropertyValue(sAPI_sub_type, Any(sal_Int16(SetVariableType::FORMULA)));

    // delegate to super class
    XMLVarFieldImportContext::PrepareField(xPropertySet);
}


// text input field


XMLTextInputFieldImportContext::XMLTextInputFieldImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp) :
        XMLVarFieldImportContext(rImport, rHlp, u"Input"_ustr,
                                 // description
                                 falsefalse,
                                 truetruetrue,
                                 falsefalse,
                                 falsefalsefalse,
                                 false)
{
    bValid = true;  // always valid
}

void XMLTextInputFieldImportContext::PrepareField(
    const Reference<XPropertySet> & xPropertySet)
{
    XMLVarFieldImportContext::PrepareField(xPropertySet);

    xPropertySet->setPropertyValue(sAPI_content, Any(GetContent()));
}


// table formula field


XMLTableFormulaImportContext::XMLTableFormulaImportContext(
    SvXMLImport& rImport,
    XMLTextImportHelper& rHlp) :
        XMLTextFieldImportContext(rImport, rHlp, u"TableFormula"_ustr),
        aValueHelper(rImport, rHlp, falsetruefalsetrue),
        bIsShowFormula(false)
{
}

void XMLTableFormulaImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
        case XML_ELEMENT(TEXT, XML_FORMULA):
            aValueHelper.ProcessAttribute( nAttrToken, sAttrValue );
            bValid = true;  // we need a formula!
            break;

        case XML_ELEMENT(STYLE, XML_DATA_STYLE_NAME):
            aValueHelper.ProcessAttribute( nAttrToken, sAttrValue );
            break;
        case XML_ELEMENT(TEXT, XML_DISPLAY):
            if ( sAttrValue == "formula" )
                 bIsShowFormula = true;
            break;
        default:
            // unknown attribute -> ignore
            XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
            break;
    }
}

void XMLTableFormulaImportContext::PrepareField(
    const Reference<XPropertySet> & xPropertySet)
{
    // set format and formula
    aValueHelper.PrepareField( xPropertySet );

    Any aAny;

    // set 'show formula' and presentation
    xPropertySet->setPropertyValue( u"IsShowFormula"_ustr, Any(bIsShowFormula) );

    aAny <<= GetContent();
    xPropertySet->setPropertyValue( u"CurrentPresentation"_ustr, aAny );
}


// variable declarations

// Should be adapted to XMLVarField-/XMLSetVarFieldImportContext scheme!


// declaration container import (<variable/user-field/sequence-decls>)


XMLVariableDeclsImportContext::XMLVariableDeclsImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp, enum VarType eVarType) :
        SvXMLImportContext(rImport),
        eVarDeclsContextType(eVarType),
        rImportHelper(rHlp)
{
}

css::uno::Reference< css::xml::sax::XFastContextHandler > XMLVariableDeclsImportContext::createFastChildContext(
        sal_Int32 nElement,
        const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
{
    if( IsTokenInNamespace(nElement, XML_NAMESPACE_TEXT) )
    {
        enum XMLTokenEnum eElementName;
        switch (eVarDeclsContextType)
        {
            case VarTypeSequence:
                eElementName = XML_SEQUENCE_DECL;
                break;
            case VarTypeSimple:
                eElementName = XML_VARIABLE_DECL;
                break;
            case VarTypeUserField:
                eElementName = XML_USER_FIELD_DECL;
                break;
            default:
                OSL_FAIL("unknown field type!");
                eElementName = XML_SEQUENCE_DECL;
                break;
        }

        if( nElement == XML_ELEMENT(TEXT, eElementName) )
        {
            return new XMLVariableDeclImportContext(
                GetImport(), rImportHelper, nElement, xAttrList,
                eVarDeclsContextType);
        }
    }

    // if no context was created, use default context
    return nullptr;
}


// declaration import (<variable/user-field/sequence-decl> elements)


XMLVariableDeclImportContext::XMLVariableDeclImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp,
    sal_Int32 nElement,
    const Reference<xml::sax::XFastAttributeList> & xAttrList,
    enum VarType eVarType) :
        SvXMLImportContext(rImport)
{
    // bug?? which properties for userfield/userfieldmaster
    XMLValueImportHelper aValueHelper(rImport, rHlp, truefalsetruefalse);
    sal_Unicode cSeparationChar('.');

    sal_Int8 nNumLevel(-1);
    OUString sName;

    if (nElement != XML_ELEMENT(TEXT, XML_SEQUENCE_DECL) &&
        nElement != XML_ELEMENT(TEXT, XML_VARIABLE_DECL) &&
        nElement != XML_ELEMENT(TEXT, XML_USER_FIELD_DECL) )
        return;

    // TODO: check validity (need name!)

    // parse attributes
    for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
    {
        switch (aIter.getToken())
        {
            case XML_ELEMENT(TEXT, XML_NAME):
                sName = aIter.toString();
                break;
            case XML_ELEMENT(TEXT, XML_DISPLAY_OUTLINE_LEVEL):
            {
                sal_Int32 nLevel;
                bool const bRet = ::sax::Converter::convertNumber(
                    nLevel, aIter.toView(), 0,
                    GetImport().GetTextImport()->GetChapterNumbering()->
                                                               getCount());
                if (bRet)
                {
                    nNumLevel = static_cast< sal_Int8 >( nLevel-1 ); // API numbers -1..9
                }
                break;
            }
            case XML_ELEMENT(TEXT, XML_SEPARATION_CHARACTER):
                cSeparationChar =
                    static_cast<char>(aIter.toString().toChar());
                break;

            default:
                // delegate to value helper
                aValueHelper.ProcessAttribute(aIter.getToken(), aIter.toView());
                break;
        }
    }

    Reference<XPropertySet> xFieldMaster;
    if (!FindFieldMaster(xFieldMaster, GetImport(), rHlp,
                        sName, eVarType))
        return;

    // now we have a field master: process attributes!
    Any aAny;

    switch (eVarType)
    {
    case VarTypeSequence:
        xFieldMaster->setPropertyValue(u"ChapterNumberingLevel"_ustr, Any(nNumLevel));

        if (nNumLevel >= 0)
        {
            OUString sStr(&cSeparationChar, 1);
            xFieldMaster->setPropertyValue(
                u"NumberingSeparator"_ustr, Any(sStr));
        }
        break;
    case VarTypeSimple:
        {
            // set string or non-string SubType (#93192#)
            // The SubType was already set in the FindFieldMaster
            // method, but it needs to be adjusted if it's a string.
            aAny <<= aValueHelper.IsStringValue()
                ? SetVariableType::STRING : SetVariableType::VAR;
            xFieldMaster->setPropertyValue(sAPI_sub_type, aAny);
        }
        break;
    case VarTypeUserField:
    {
        bool bTmp = !aValueHelper.IsStringValue();
        xFieldMaster->setPropertyValue(u"IsExpression"_ustr, Any(bTmp));
        aValueHelper.PrepareField(xFieldMaster);
        break;
    }
    default:
        OSL_FAIL("unknown varfield type");
    } // switch
}


bool XMLVariableDeclImportContext::FindFieldMaster(
    Reference<XPropertySet> & xMaster, SvXMLImport& rImport,
    XMLTextImportHelper& rImportHelper,
    const OUString& sVarName, enum VarType eVarType)
{
    static sal_Int32 nCollisionCount = 0;

    // rename field
    // currently: no family in use! Use 0.
    OUString sName = rImportHelper.GetRenameMap().Get(
        sal::static_int_cast< sal_uInt16 >(eVarType), sVarName);

    // get text fields supplier and field masters
    Reference<XTextFieldsSupplier> xTextFieldsSupp(rImport.GetModel(),
                                                   UNO_QUERY);
    Reference<container::XNameAccess> xFieldMasterNameAccess =
        xTextFieldsSupp->getTextFieldMasters();

    OUString sVarServiceName =
        OUString::Concat(sAPI_fieldmaster_prefix) +
        sAPI_set_expression +
        "." +
        sName;

    OUString sUserServiceName =
        OUString::Concat(sAPI_fieldmaster_prefix) +
        sAPI_user +
        "." +
        sName;

    if (xFieldMasterNameAccess->hasByName(sVarServiceName)) {
        // variable field master already in document

        Any aAny = xFieldMasterNameAccess->getByName(sVarServiceName);
        aAny >>= xMaster;

        aAny = xMaster->getPropertyValue(sAPI_sub_type);
        sal_Int16 nType = 0;
        aAny >>= nType;

        enum VarType eFMVarType =
            (SetVariableType::SEQUENCE == nType) ?
                VarTypeSequence : VarTypeSimple;

        if (eFMVarType != eVarType)
        {
            ++nCollisionCount;
            OUString sNew(sName + "_renamed_" + OUString::number(nCollisionCount));

            // FIXME! can't find if name is taken already!!!!

            rImportHelper.GetRenameMap().Add(
                sal::static_int_cast< sal_uInt16 >(eVarType), sName, sNew);

            // call FindFieldMaster recursively to create new master
            return FindFieldMaster(xMaster, rImport, rImportHelper,
                                   sNew, eVarType);
        }
    } else if (xFieldMasterNameAccess->hasByName(sUserServiceName)) {
        // user field: get field master
        Any aAny = xFieldMasterNameAccess->getByName(sUserServiceName);
        aAny >>= xMaster;

        if (VarTypeUserField != eVarType) {
            ++nCollisionCount;
            // find new name that is not taken
            OUString sNew(sName + "_renamed_" + OUString::number(nCollisionCount));

            // FIXME! can't find if name is taken already!!!!

            rImportHelper.GetRenameMap().Add(
                sal::static_int_cast< sal_uInt16 >(eVarType), sName, sNew);

            // call FindFieldMaster recursively to create new master
            return FindFieldMaster(xMaster, rImport, rImportHelper,
                                   sNew, eVarType);
        }
    } else {
        // field name not used: create field master

        // import -> model is MultiServiceFactory -> createInstance
        Reference<lang::XMultiServiceFactory>
            xFactory(rImport.GetModel(),UNO_QUERY);
        if( xFactory.is() ) {

            OUString sService = sAPI_fieldmaster_prefix
                + ((eVarType==VarTypeUserField) ?
                                 sAPI_user : sAPI_set_expression);
            Reference<XInterface> xIfc =
                xFactory->createInstance( sService );
            if (xIfc.is()) {
                xMaster.set(xIfc, UNO_QUERY);

                // set name
                xMaster->setPropertyValue(u"Name"_ustr, Any(sName));

                if (eVarType != VarTypeUserField) {
                    // set subtype for setexp field
                    Any aAny;
                    aAny <<= ((eVarType == VarTypeSimple) ?
                              SetVariableType::VAR :
                              SetVariableType::SEQUENCE);
                    xMaster->setPropertyValue(sAPI_sub_type, aAny);
                } // else : user field: no subtype

            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    DBG_ASSERT(xMaster.is(), "no field master found!?!");
    return true;
}


// Database Display field import


XMLDatabaseDisplayImportContext::XMLDatabaseDisplayImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp) :
        XMLDatabaseFieldImportContext(rImport, rHlp, sAPI_database, false),
        aValueHelper(rImport, rHlp, falsetruefalsefalse),
        bColumnOK(false),
        bDisplay( true ),
        bDisplayOK( false )
{
}

void XMLDatabaseDisplayImportContext::ProcessAttribute(
    sal_Int32 nAttrToken, std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
        case XML_ELEMENT(TEXT, XML_COLUMN_NAME):
            sColumnName = OUString::fromUtf8(sAttrValue);
            bColumnOK = true;
            break;
        case XML_ELEMENT(TEXT, XML_DISPLAY):
            {
                bool bNone = IsXMLToken( sAttrValue, XML_NONE );
                bool bValue = IsXMLToken( sAttrValue, XML_VALUE );
                bDisplay = bValue;
                bDisplayOK = bNone || bValue;
            }
            break;
        case XML_ELEMENT(TEXT, XML_DATABASE_NAME):
        case XML_ELEMENT(TEXT, XML_TABLE_NAME):
        case XML_ELEMENT(TEXT, XML_TABLE_TYPE):
            // handled by super class
            XMLDatabaseFieldImportContext::ProcessAttribute(nAttrToken,
                                                            sAttrValue);
            break;
        default:
            // remainder handled by value helper
            aValueHelper.ProcessAttribute(nAttrToken, sAttrValue);
            break;
    }

    bValid = m_bTableOK && m_bDatabaseOK && bColumnOK;
}

void XMLDatabaseDisplayImportContext::endFastElement(sal_Int32 )
{
    // we have an EndElement of our own, because database fields need
    // to be attached to a field master before they can be inserted into
    // the document. Database stuff (database, table, column) all goes
    // to the field master, value & style go to the field.

    if (bValid)
    {

        // so here goes: we start with the master
        Reference<XPropertySet> xMaster;

        // create and prepare field master first
        if (CreateField(xMaster,
                        u"com.sun.star.text.FieldMaster.Database"_ustr))
        {
            Any aAny;
            xMaster->setPropertyValue(u"DataColumnName"_ustr, Any(sColumnName));

            // fieldmaster takes database, table and column name
            XMLDatabaseFieldImportContext::PrepareField(xMaster);

            // create field
            Reference<XPropertySet> xField;
            if (CreateField(xField,
                            sAPI_database))
            {
                // attach field master
                Reference<XDependentTextField> xDepField(xField, UNO_QUERY);
                if (xDepField.is())
                {
                    // attach field to field master
                    xDepField->attachTextFieldMaster(xMaster);

                    // attach field to document
                    Reference<XTextContent> xTextContent(xField, UNO_QUERY);
                    if (xTextContent.is())
                    {
                        // insert, set field properties and exit!
                        try
                        {
                            GetImportHelper().InsertTextContent(xTextContent);

                            // prepare field: format from database?
                            bool bTmp = !aValueHelper.IsFormatOK();
                            xField->setPropertyValue(u"DataBaseFormat"_ustr, Any(bTmp));

                            // value, value-type and format done by value helper
                            aValueHelper.PrepareField(xField);

                            // visibility
                            if( bDisplayOK )
                            {
                                xField->setPropertyValue(sAPI_is_visible, Any(bDisplay));
                            }

                            // set presentation
                            aAny <<= GetContent();
                            xField->setPropertyValue(sAPI_current_presentation, aAny);

                            // success!
                            return;
                        }
                        catch (const lang::IllegalArgumentException&)
                        {
                            TOOLS_WARN_EXCEPTION("xmloff.text""Failed to insert text content");
                        }
                    }
                }
            }
        }
    }

    // above: exit on success; so for all error cases we end up here!
    // write element content
    GetImportHelper().InsertString(GetContent());
}


// value import helper

namespace {

enum ValueType
{
    XML_VALUE_TYPE_STRING,
    XML_VALUE_TYPE_FLOAT,
    XML_VALUE_TYPE_CURRENCY,
    XML_VALUE_TYPE_PERCENTAGE,
    XML_VALUE_TYPE_DATE,
    XML_VALUE_TYPE_TIME,
    XML_VALUE_TYPE_BOOLEAN
};

}

SvXMLEnumMapEntry<ValueType> const aValueTypeMap[] =
{
    { XML_FLOAT,        XML_VALUE_TYPE_FLOAT },
    { XML_CURRENCY,     XML_VALUE_TYPE_CURRENCY },
    { XML_PERCENTAGE,   XML_VALUE_TYPE_PERCENTAGE },
    { XML_DATE,         XML_VALUE_TYPE_DATE },
    { XML_TIME,         XML_VALUE_TYPE_TIME },
    { XML_BOOLEAN,      XML_VALUE_TYPE_BOOLEAN },
    { XML_STRING,       XML_VALUE_TYPE_STRING },
    { XML_TOKEN_INVALID, ValueType(0) }
};

XMLValueImportHelper::XMLValueImportHelper(
    SvXMLImport& rImprt,
    XMLTextImportHelper& rHlp,
    bool bType, bool bStyle, bool bValue, bool bFormula) :

        rImport(rImprt),
        rHelper(rHlp),

        fValue(0.0),
        nFormatKey(0),
        bIsDefaultLanguage(true),

        bStringType(false),
        bFormatOK(false),
        bStringValueOK(false),
        bFormulaOK(false),

        bSetType(bType),
        bSetValue(bValue),
        bSetStyle(bStyle),
        bSetFormula(bFormula)
{
}

void XMLValueImportHelper::ProcessAttribute(
    sal_Int32 nAttrToken, std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
        case XML_ELEMENT(TEXT, XML_VALUE_TYPE): // #i32362#: src680m48++ saves text:value-type
        case XML_ELEMENT(OFFICE, XML_VALUE_TYPE):
        {
            // convert enum
            ValueType eValueType = XML_VALUE_TYPE_STRING;
            bool bRet = SvXMLUnitConverter::convertEnum(
                eValueType, sAttrValue, aValueTypeMap);

            if (bRet) {
                switch (eValueType)
                {
                    case XML_VALUE_TYPE_STRING:
                        bStringType = true;
                        break;
                    case XML_VALUE_TYPE_FLOAT:
                    case XML_VALUE_TYPE_CURRENCY:
                    case XML_VALUE_TYPE_PERCENTAGE:
                    case XML_VALUE_TYPE_DATE:
                    case XML_VALUE_TYPE_TIME:
                    case XML_VALUE_TYPE_BOOLEAN:
                        bStringType = false;
                        break;

                    default:
                        OSL_FAIL("unknown value type");
                }
            }
            break;
        }

        case XML_ELEMENT(TEXT, XML_VALUE):
        case XML_ELEMENT(OFFICE, XML_VALUE):
        {
            double fTmp;
            bool const bRet = ::sax::Converter::convertDouble(fTmp,sAttrValue);
            if (bRet) {
                fValue = fTmp;
            }
            break;
        }

        case XML_ELEMENT(TEXT, XML_TIME_VALUE):
        case XML_ELEMENT(OFFICE, XML_TIME_VALUE):
        {
            double fTmp;
            bool const bRet =
                ::sax::Converter::convertDuration(fTmp, sAttrValue);
            if (bRet) {
                fValue = fTmp;
            }
            break;
        }

        case XML_ELEMENT(TEXT, XML_DATE_VALUE):
        case XML_ELEMENT(OFFICE, XML_DATE_VALUE):
        {
            double fTmp;
            bool bRet = rImport.GetMM100UnitConverter().
                convertDateTime(fTmp,sAttrValue);
            if (bRet) {
                fValue = fTmp;
            }
            break;
        }

        case XML_ELEMENT(OFFICE, XML_BOOLEAN_VALUE):
        {
            bool bTmp(false);
            bool bRet = ::sax::Converter::convertBool(bTmp, sAttrValue);
            if (bRet) {
                fValue = (bTmp ? 1.0 : 0.0);
            }
            else
            {
                double fTmp;
                bRet = ::sax::Converter::convertDouble(fTmp, sAttrValue);
                if (bRet) {
                    fValue = fTmp;
                }
            }
            break;
        }

        case XML_ELEMENT(TEXT, XML_STRING_VALUE):
        case XML_ELEMENT(OFFICE, XML_STRING_VALUE):
            sValue = OUString::fromUtf8(sAttrValue);
            bStringValueOK = true;
            break;

        case  XML_ELEMENT(TEXT, XML_FORMULA):
            {
                OUString sTmp;
                sal_uInt16 nPrefix = rImport.GetNamespaceMap().
                        GetKeyByAttrValueQName(OUString::fromUtf8(sAttrValue), &sTmp);
                if( XML_NAMESPACE_OOOW == nPrefix )
                {
                    sFormula = sTmp;
                    bFormulaOK = true;
                }
                else
                    sFormula = OUString::fromUtf8(sAttrValue);
            }
            break;

        case XML_ELEMENT(STYLE, XML_DATA_STYLE_NAME):
        {
            sal_Int32 nKey = rHelper.GetDataStyleKey(
                                          OUString::fromUtf8(sAttrValue), &bIsDefaultLanguage);
            if (-1 != nKey)
            {
                nFormatKey = nKey;
                bFormatOK = true;
            }
            break;
        }
        default:
            XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
    } // switch
}

void XMLValueImportHelper::PrepareField(
    const Reference<XPropertySet> & xPropertySet)
{
    Any aAny;

    if (bSetType)
    {
        // ??? how to set type?
    }

    if (bSetFormula)
    {
        aAny <<= !bFormulaOK ? sDefault : sFormula;
        xPropertySet->setPropertyValue(sAPI_content, aAny);
    }

    // format/style
    if (bSetStyle && bFormatOK)
    {
        xPropertySet->setPropertyValue(sAPI_number_format, Any(nFormatKey));

        if( xPropertySet->getPropertySetInfo()->
                hasPropertyByName( u"IsFixedLanguage"_ustr ) )
        {
            bool bIsFixedLanguage = ! bIsDefaultLanguage;
            xPropertySet->setPropertyValue( u"IsFixedLanguage"_ustr, Any(bIsFixedLanguage) );
        }
    }

    // value: string or float
    if (bSetValue)
    {
        if (bStringType)
        {
            aAny <<= !bStringValueOK ? sDefault : sValue;
            xPropertySet->setPropertyValue(sAPI_content, aAny);
        }
        else
        {
            xPropertySet->setPropertyValue(u"Value"_ustr, Any(fValue));
        }
    }
}

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

Messung V0.5
C=89 H=93 G=90

¤ Dauer der Verarbeitung: 0.17 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.