Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  txtfldi.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
 *
 *  Import of all text fields except those from txtvfldi.cxx
 *  (variable related text fields and database display fields)
 */


#include <sal/config.h>

#include <cassert>

#include <txtfld.hxx>
#include <txtfldi.hxx>
#include <txtvfldi.hxx>
#include <utility>
#include <xmloff/xmlimp.hxx>
#include <xmloff/txtimp.hxx>
#include <xmloff/xmlnamespace.hxx>
#include <xmloff/namespacemap.hxx>
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmluconv.hxx>
#include <xmloff/xmlement.hxx>
#include <XMLStringBufferImportContext.hxx>
#include <xmloff/XMLEventsImportContext.hxx>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/text/UserDataPart.hpp>
#include <com/sun/star/style/NumberingType.hpp>
#include <com/sun/star/text/PlaceholderType.hpp>
#include <com/sun/star/text/ReferenceFieldPart.hpp>
#include <com/sun/star/text/ReferenceFieldSource.hpp>
#include <com/sun/star/text/XTextContent.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/text/XTextFieldsSupplier.hpp>
#include <com/sun/star/text/XDependentTextField.hpp>
#include <com/sun/star/text/FilenameDisplayFormat.hpp>
#include <com/sun/star/text/ChapterFormat.hpp>
#include <com/sun/star/text/TemplateDisplayFormat.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/text/BibliographyDataType.hpp>
#include <com/sun/star/util/XUpdatable.hpp>
#include <com/sun/star/sdb/CommandType.hpp>
#include <com/sun/star/container/XIndexReplace.hpp>
#include <com/sun/star/container/XUniqueIDAccess.hpp>

#include <sax/tools/converter.hxx>

#include <rtl/ustring.hxx>
#include <rtl/ustrbuf.hxx>
#include <sal/log.hxx>
#include <rtl/math.hxx>
#include <tools/debug.hxx>
#include <osl/diagnose.h>
#include <comphelper/diagnose_ex.hxx>

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::text;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::document;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::xml::sax;
using namespace ::xmloff::token;


// SO API string constants


// service prefix and service names
constexpr OUString sAPI_textfield_prefix = u"com.sun.star.text.TextField."_ustr;
constexpr char16_t sAPI_fieldmaster_prefix[] = u"com.sun.star.text.FieldMaster.";
constexpr OUString sAPI_presentation_prefix = u"com.sun.star.presentation.TextField."_ustr;

constexpr OUString sAPI_date_time        = u"DateTime"_ustr;
constexpr OUString sAPI_page_number      = u"PageNumber"_ustr;
constexpr OUString sAPI_docinfo_change_date_time = u"DocInfo.ChangeDateTime"_ustr;
constexpr OUString sAPI_docinfo_create_date_time = u"DocInfo.CreateDateTime"_ustr;
constexpr OUString sAPI_docinfo_custom   = u"DocInfo.Custom"_ustr;
constexpr OUString sAPI_docinfo_print_date_time = u"DocInfo.PrintDateTime"_ustr;
constexpr OUString sAPI_dde              = u"DDE"_ustr;
constexpr OUString sAPI_url              = u"URL"_ustr;

// property names
constexpr OUString sAPI_is_fixed = u"IsFixed"_ustr;
constexpr OUString sAPI_content  = u"Content"_ustr;
constexpr OUString sAPI_author   = u"Author"_ustr;
constexpr OUString sAPI_hint     = u"Hint"_ustr;
constexpr OUString sAPI_name     = u"Name"_ustr;
constexpr OUStringLiteral sAPI_parent_name = u"ParentName";
constexpr OUString sAPI_sub_type = u"SubType"_ustr;
constexpr OUString sAPI_date_time_value = u"DateTimeValue"_ustr;
constexpr OUString sAPI_number_format = u"NumberFormat"_ustr;
constexpr OUString sAPI_numbering_type = u"NumberingType"_ustr;
constexpr OUString sAPI_offset   = u"Offset"_ustr;
constexpr OUString sAPI_condition = u"Condition"_ustr;
constexpr OUString sAPI_set_number = u"SetNumber"_ustr;
constexpr OUString sAPI_file_format = u"FileFormat"_ustr;
constexpr OUString sAPI_is_date  = u"IsDate"_ustr;
constexpr OUString sAPI_current_presentation = u"CurrentPresentation"_ustr;
constexpr OUString sAPI_is_hidden = u"IsHidden"_ustr;
constexpr OUString sAPI_is_fixed_language = u"IsFixedLanguage"_ustr;

constexpr OUString sAPI_true = u"TRUE"_ustr;


XMLTextFieldImportContext::XMLTextFieldImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp,
    OUString aService)
:   SvXMLImportContext( rImport )
,   sServiceName(std::move(aService))
,   rTextImportHelper(rHlp)
,   sServicePrefix(sAPI_textfield_prefix)
,   bValid(false)
{
}

void XMLTextFieldImportContext::startFastElement(
        sal_Int32 /*nElement*/,
        const Reference<XFastAttributeList> & xAttrList)
{
    // process attributes
    forauto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ) )
        ProcessAttribute(aIter.getToken(), aIter.toView() );
}

OUString const & XMLTextFieldImportContext::GetContent()
{
    if (sContent.isEmpty())
    {
        sContent = sContentBuffer.makeStringAndClear();
    }

    return sContent;
}

void XMLTextFieldImportContext::endFastElement(sal_Int32 )
{
    if (bValid)
    {

        // create field/Service
        Reference<XPropertySet> xPropSet;
        if (CreateField(xPropSet, sServicePrefix + GetServiceName()))
        {
            // set field properties
            PrepareField(xPropSet);

            // attach field to document
            Reference<XTextContent> xTextContent(xPropSet, UNO_QUERY);

            // workaround for #80606#
            try
            {
                rTextImportHelper.InsertTextContent(xTextContent);
            }
            catch (const lang::IllegalArgumentException&)
            {
                // ignore
            }
            return;
        }
    }

    // in case of error: write element content
    rTextImportHelper.InsertString(GetContent());
}

void XMLTextFieldImportContext::characters(const OUString& rContent)
{
    sContentBuffer.append(rContent);
}

bool XMLTextFieldImportContext::CreateField(
    Reference<XPropertySet> & xField,
    const OUString& rServiceName)
{
    // instantiate new XTextField:
    // ask import for model, model is factory, ask factory to create service

    Reference<XMultiServiceFactory> xFactory(GetImport().GetModel(),UNO_QUERY);
    if( xFactory.is() )
    {
        Reference<XInterface> xIfc = xFactory->createInstance(rServiceName);
        if( xIfc.is() )
        {
            xField.set(xIfc, UNO_QUERY);
        } else {
            return false;   // can't create instance
        }
    } else {
        return false;   // can't get MultiServiceFactory
    }

    return true;
}

/// create the appropriate field context from
XMLTextFieldImportContext*
XMLTextFieldImportContext::CreateTextFieldImportContext(
    SvXMLImport& rImport,
    XMLTextImportHelper& rHlp,
    sal_Int32 nToken)
{
    XMLTextFieldImportContext* pContext = nullptr;

    switch (nToken)
    {
        case XML_ELEMENT(TEXT, XML_SENDER_FIRSTNAME):
        case XML_ELEMENT(TEXT, XML_SENDER_LASTNAME):
        case XML_ELEMENT(LO_EXT, XML_SENDER_INITIALS):
        case XML_ELEMENT(TEXT, XML_SENDER_INITIALS):
        case XML_ELEMENT(TEXT, XML_SENDER_TITLE):
        case XML_ELEMENT(TEXT, XML_SENDER_POSITION):
        case XML_ELEMENT(TEXT, XML_SENDER_EMAIL):
        case XML_ELEMENT(TEXT, XML_SENDER_PHONE_PRIVATE):

        case XML_ELEMENT(TEXT, XML_SENDER_FAX):
        case XML_ELEMENT(TEXT, XML_SENDER_COMPANY):
        case XML_ELEMENT(TEXT, XML_SENDER_PHONE_WORK):
        case XML_ELEMENT(TEXT, XML_SENDER_STREET):
        case XML_ELEMENT(TEXT, XML_SENDER_CITY):
        case XML_ELEMENT(TEXT, XML_SENDER_POSTAL_CODE):
        case XML_ELEMENT(TEXT, XML_SENDER_COUNTRY):
        case XML_ELEMENT(TEXT, XML_SENDER_STATE_OR_PROVINCE):
            pContext =
                new XMLSenderFieldImportContext( rImport, rHlp );
            break;

        case XML_ELEMENT(TEXT, XML_AUTHOR_NAME):
        case XML_ELEMENT(TEXT, XML_AUTHOR_INITIALS):
            pContext =
                new XMLAuthorFieldImportContext( rImport, rHlp );
            break;

        case XML_ELEMENT(TEXT, XML_PLACEHOLDER):
            pContext =
                new XMLPlaceholderFieldImportContext( rImport, rHlp);
            break;
        case XML_ELEMENT(TEXT, XML_SEQUENCE):
            pContext =
                new XMLSequenceFieldImportContext( rImport, rHlp );
            break;
        case XML_ELEMENT(TEXT, XML_TEXT_INPUT):
            pContext =
                new XMLTextInputFieldImportContext( rImport, rHlp );
            break;
        case XML_ELEMENT(TEXT, XML_EXPRESSION):
            pContext =
                new XMLExpressionFieldImportContext( rImport, rHlp );
            break;
        case XML_ELEMENT(TEXT, XML_VARIABLE_SET):
            pContext =
                new XMLVariableSetFieldImportContext( rImport, rHlp );
            break;
        case XML_ELEMENT(TEXT, XML_VARIABLE_INPUT):
            pContext =
                new XMLVariableInputFieldImportContext( rImport, rHlp );
            break;
        case XML_ELEMENT(TEXT, XML_VARIABLE_GET):
            pContext =
                new XMLVariableGetFieldImportContext( rImport, rHlp );
            break;
        case XML_ELEMENT(TEXT, XML_USER_FIELD_GET):
            pContext = new XMLUserFieldImportContext( rImport, rHlp );
            break;
        case XML_ELEMENT(TEXT, XML_USER_FIELD_INPUT):
            pContext = new XMLUserFieldInputImportContext( rImport, rHlp );
            break;
        case XML_ELEMENT(TEXT, XML_TIME):
            pContext = new XMLTimeFieldImportContext( rImport, rHlp );
            break;
        case XML_ELEMENT(TEXT, XML_PAGE_CONTINUATION_STRING):
        case XML_ELEMENT(TEXT, XML_PAGE_CONTINUATION):
            pContext = new XMLPageContinuationImportContext( rImport, rHlp );
            break;

        case XML_ELEMENT(TEXT, XML_PAGE_NUMBER):
            pContext = new XMLPageNumberImportContext( rImport, rHlp );
            break;

        case XML_ELEMENT(TEXT, XML_DATE):
            pContext = new XMLDateFieldImportContext( rImport, rHlp );
            break;

        case XML_ELEMENT(TEXT, XML_DATABASE_NAME):
            pContext = new XMLDatabaseNameImportContext( rImport, rHlp );
            break;
        case XML_ELEMENT(TEXT, XML_DATABASE_NEXT):
            pContext = new XMLDatabaseNextImportContext( rImport, rHlp );
            break;
        case XML_ELEMENT(TEXT, XML_DATABASE_ROW_SELECT):
            pContext = new XMLDatabaseSelectImportContext( rImport, rHlp );
            break;
        case XML_ELEMENT(TEXT, XML_DATABASE_ROW_NUMBER):
            pContext = new XMLDatabaseNumberImportContext( rImport, rHlp );
            break;
        case XML_ELEMENT(TEXT, XML_DATABASE_DISPLAY):
            pContext = new XMLDatabaseDisplayImportContext( rImport, rHlp );
            break;
        case XML_ELEMENT(TEXT, XML_CONDITIONAL_TEXT):
            pContext = new XMLConditionalTextImportContext( rImport, rHlp );
            break;
        case XML_ELEMENT(TEXT, XML_HIDDEN_TEXT):
            pContext = new XMLHiddenTextImportContext( rImport, rHlp );
            break;
        case XML_ELEMENT(TEXT, XML_HIDDEN_PARAGRAPH):
            pContext = new XMLHiddenParagraphImportContext( rImport, rHlp );
            break;
        case XML_ELEMENT(TEXT, XML_DESCRIPTION):
        case XML_ELEMENT(TEXT, XML_TITLE):
        case XML_ELEMENT(TEXT, XML_SUBJECT):
        case XML_ELEMENT(TEXT, XML_KEYWORDS):
            pContext = new XMLSimpleDocInfoImportContext( rImport, rHlp,
                                                          nToken, true,
                                                          false );
            break;
        case XML_ELEMENT(TEXT, XML_INITIAL_CREATOR):
        case XML_ELEMENT(TEXT, XML_PRINTED_BY):
        case XML_ELEMENT(TEXT, XML_CREATOR):
            pContext = new XMLSimpleDocInfoImportContext( rImport, rHlp,
                                                          nToken, false,
                                                          true );
            break;

        case XML_ELEMENT(TEXT, XML_CREATION_DATE):
        case XML_ELEMENT(TEXT, XML_CREATION_TIME):
        case XML_ELEMENT(TEXT, XML_PRINT_DATE):
        case XML_ELEMENT(TEXT, XML_PRINT_TIME):
        case XML_ELEMENT(TEXT, XML_MODIFICATION_DATE):
        case XML_ELEMENT(TEXT, XML_MODIFICATION_TIME):
        case XML_ELEMENT(TEXT, XML_EDITING_DURATION):
            pContext = new XMLDateTimeDocInfoImportContext( rImport, rHlp,
                                                            nToken );
            break;

        case XML_ELEMENT(TEXT, XML_EDITING_CYCLES):
            pContext = new XMLRevisionDocInfoImportContext( rImport, rHlp,
                                                            nToken );
            break;

        case XML_ELEMENT(TEXT, XML_USER_DEFINED):
            pContext = new XMLUserDocInfoImportContext( rImport, rHlp,
                                                        nToken );
            break;

        case XML_ELEMENT(TEXT, XML_FILE_NAME):
            pContext = new XMLFileNameImportContext( rImport, rHlp );
            break;

        case XML_ELEMENT(TEXT, XML_CHAPTER):
            pContext = new XMLChapterImportContext( rImport, rHlp );
            break;

        case XML_ELEMENT(TEXT, XML_TEMPLATE_NAME):
            pContext = new XMLTemplateNameImportContext( rImport, rHlp );
            break;

        case XML_ELEMENT(TEXT, XML_WORD_COUNT):
        case XML_ELEMENT(TEXT, XML_PARAGRAPH_COUNT):
        case XML_ELEMENT(TEXT, XML_TABLE_COUNT):
        case XML_ELEMENT(TEXT, XML_CHARACTER_COUNT):
        case XML_ELEMENT(TEXT, XML_IMAGE_COUNT):
        case XML_ELEMENT(TEXT, XML_OBJECT_COUNT):
        case XML_ELEMENT(TEXT, XML_PAGE_COUNT):
        case XML_ELEMENT(LO_EXT, XML_PAGE_COUNT_RANGE):
            pContext = new XMLCountFieldImportContext( rImport, rHlp, nToken);
            break;

        case XML_ELEMENT(TEXT, XML_PAGE_VARIABLE_GET):
            pContext = new XMLPageVarGetFieldImportContext( rImport, rHlp );
            break;

        case XML_ELEMENT(TEXT, XML_PAGE_VARIABLE_SET):
            pContext = new XMLPageVarSetFieldImportContext( rImport, rHlp );
            break;

        case XML_ELEMENT(TEXT, XML_EXECUTE_MACRO):
            pContext = new XMLMacroFieldImportContext( rImport, rHlp );
            break;

        case XML_ELEMENT(TEXT, XML_DDE_CONNECTION):
            pContext = new XMLDdeFieldImportContext( rImport, rHlp );
            break;

        case XML_ELEMENT(TEXT, XML_REFERENCE_REF):
        case XML_ELEMENT(TEXT, XML_BOOKMARK_REF):
        case XML_ELEMENT(TEXT, XML_NOTE_REF):
        case XML_ELEMENT(TEXT, XML_SEQUENCE_REF):
        case XML_ELEMENT(TEXT, XML_STYLE_REF):
        case XML_ELEMENT(LO_EXT, XML_STYLE_REF):
            pContext = new XMLReferenceFieldImportContext( rImport, rHlp, nToken );
            break;

        case XML_ELEMENT(TEXT, XML_SHEET_NAME):
            pContext = new XMLSheetNameImportContext( rImport, rHlp );
            break;

        case XML_ELEMENT(TEXT, XML_PAGE_NAME):
        case XML_ELEMENT(LO_EXT, XML_PAGE_NAME):
            pContext = new XMLPageNameFieldImportContext( rImport, rHlp );
            break;

        case XML_ELEMENT(TEXT, XML_BIBLIOGRAPHY_MARK):
            pContext = new XMLBibliographyFieldImportContext( rImport, rHlp );
            break;

        case XML_ELEMENT(OFFICE, XML_ANNOTATION):
        case XML_ELEMENT(OFFICE, XML_ANNOTATION_END):
            pContext = new XMLAnnotationImportContext( rImport, rHlp, nToken);
            break;

        case XML_ELEMENT(TEXT, XML_SCRIPT):
            pContext = new XMLScriptImportContext( rImport, rHlp);
            break;

        case XML_ELEMENT(TEXT, XML_MEASURE):
            pContext = new XMLMeasureFieldImportContext( rImport, rHlp );
            break;

        case XML_ELEMENT(TEXT, XML_TABLE_FORMULA):
            pContext = new XMLTableFormulaImportContext( rImport, rHlp );
            break;
        case XML_ELEMENT(TEXT, XML_DROP_DOWN):
            pContext = new XMLDropDownFieldImportContext( rImport, rHlp );
            break;
        case XML_ELEMENT(PRESENTATION, XML_HEADER):
            pContext = new XMLHeaderFieldImportContext( rImport, rHlp );
            break;
        case XML_ELEMENT(PRESENTATION, XML_FOOTER):
            pContext = new XMLFooterFieldImportContext( rImport, rHlp );
            break;
        case XML_ELEMENT(PRESENTATION, XML_DATE_TIME):
            pContext = new XMLDateTimeFieldImportContext( rImport, rHlp );
            break;

        default:
            // ignore! May not even be a textfield.
            // (Reminder: This method is called inside default:-branch)
            pContext = nullptr;
            break;
    }

    return pContext;
}


void XMLTextFieldImportContext::ForceUpdate(
    const Reference<XPropertySet> & rPropertySet)
{
    // force update
    Reference<XUpdatable> xUpdate(rPropertySet, UNO_QUERY);
    if (xUpdate.is())
    {
        xUpdate->update();
    }
    else
    {
        OSL_FAIL("Expected XUpdatable support!");
    }
}


// XMLSenderFieldImportContext


constexpr OUStringLiteral gsPropertyFieldSubType(u"UserDataType");

XMLSenderFieldImportContext::XMLSenderFieldImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp)
    : XMLTextFieldImportContext(rImport, rHlp, u"ExtendedUser"_ustr)
    , nSubType(0)
    , sPropertyFixed(sAPI_is_fixed)
    , sPropertyContent(sAPI_content)
    , bFixed(true)
{
}

void XMLSenderFieldImportContext::startFastElement(
        sal_Int32 nElement,
        const Reference<XFastAttributeList> & xAttrList)
{
    bValid = true;
    switch (nElement) {
    case XML_ELEMENT(TEXT, XML_SENDER_FIRSTNAME):
        nSubType = UserDataPart::FIRSTNAME;
        break;
    case  XML_ELEMENT(TEXT, XML_SENDER_LASTNAME):
        nSubType = UserDataPart::NAME;
        break;
    case XML_ELEMENT(LO_EXT, XML_SENDER_INITIALS):
    case XML_ELEMENT(TEXT,   XML_SENDER_INITIALS):
        nSubType = UserDataPart::SHORTCUT;
        break;
    case XML_ELEMENT(TEXT, XML_SENDER_TITLE):
        nSubType = UserDataPart::TITLE;
        break;
    case XML_ELEMENT(TEXT, XML_SENDER_POSITION):
        nSubType = UserDataPart::POSITION;
        break;
    case XML_ELEMENT(TEXT, XML_SENDER_EMAIL):
        nSubType = UserDataPart::EMAIL;
        break;
    case XML_ELEMENT(TEXT, XML_SENDER_PHONE_PRIVATE):
        nSubType = UserDataPart::PHONE_PRIVATE;
        break;
    case XML_ELEMENT(TEXT, XML_SENDER_FAX):
        nSubType = UserDataPart::FAX;
        break;
    case XML_ELEMENT(TEXT, XML_SENDER_COMPANY):
        nSubType = UserDataPart::COMPANY;
        break;
    case  XML_ELEMENT(TEXT, XML_SENDER_PHONE_WORK):
        nSubType = UserDataPart::PHONE_COMPANY;
        break;
    case  XML_ELEMENT(TEXT, XML_SENDER_STREET):
        nSubType = UserDataPart::STREET;
        break;
    case XML_ELEMENT(TEXT, XML_SENDER_CITY):
        nSubType = UserDataPart::CITY;
        break;
    case XML_ELEMENT(TEXT, XML_SENDER_POSTAL_CODE):
        nSubType = UserDataPart::ZIP;
        break;
    case XML_ELEMENT(TEXT, XML_SENDER_COUNTRY):
        nSubType = UserDataPart::COUNTRY;
        break;
    case  XML_ELEMENT(TEXT, XML_SENDER_STATE_OR_PROVINCE):
        nSubType = UserDataPart::STATE;
        break;
    default:
        bValid = false;
        XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
        break;
    }

    // process Attributes
    XMLTextFieldImportContext::startFastElement(nElement, xAttrList);
}

void XMLSenderFieldImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue)
{
    if (XML_ELEMENT(TEXT, XML_FIXED) == nAttrToken) {

        // set bVal
        bool bVal(false);
        bool const bRet = ::sax::Converter::convertBool(bVal, sAttrValue);

        // set bFixed if successful
        if (bRet) {
            bFixed = bVal;
        }
    }
    else
        XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
}

void XMLSenderFieldImportContext::PrepareField(
    const Reference<XPropertySet> & rPropSet)
{
    // set members
    rPropSet->setPropertyValue(gsPropertyFieldSubType, Any(nSubType));

    // set fixed
    rPropSet->setPropertyValue(sPropertyFixed, Any(bFixed));

    // set content if fixed
    if (!bFixed)
        return;

    // in organizer or styles-only mode: force update
    if (GetImport().GetTextImport()->IsOrganizerMode() ||
        GetImport().GetTextImport()->IsStylesOnlyMode()   )
    {
        ForceUpdate(rPropSet);
    }
    else
    {
        rPropSet->setPropertyValue(sPropertyContent, Any(GetContent()));
    }
}


// XMLAuthorFieldImportContext

constexpr OUStringLiteral gsPropertyAuthorFullName(u"FullName");

XMLAuthorFieldImportContext::XMLAuthorFieldImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp)
:   XMLSenderFieldImportContext(rImport, rHlp)
,   bAuthorFullName(true)
,   sPropertyFixed(sAPI_is_fixed)
,   sPropertyContent(sAPI_content)
{
    // overwrite service name from XMLSenderFieldImportContext
    SetServiceName(sAPI_author);
}

void XMLAuthorFieldImportContext::startFastElement(
        sal_Int32 nElement,
        const Reference<XFastAttributeList> & xAttrList)
{
    bAuthorFullName = ( XML_ELEMENT(TEXT, XML_AUTHOR_INITIALS) != nElement);
    bValid = true;

    // process Attributes
    XMLTextFieldImportContext::startFastElement(nElement, xAttrList);
}

void XMLAuthorFieldImportContext::ProcessAttribute(sal_Int32 nAttrToken, std::string_view sAttrValue)
{
    if(nAttrToken == XML_ELEMENT(TEXT, XML_FIXED))
    {
        bool bTmp(false);
        if (::sax::Converter::convertBool(bTmp, sAttrValue))
            bFixed = bTmp;
    }
    else
        XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
}

void XMLAuthorFieldImportContext::PrepareField(
    const Reference<XPropertySet> & rPropSet)
{
    // set members
    Any aAny;
    rPropSet->setPropertyValue(gsPropertyAuthorFullName, Any(bAuthorFullName));

    rPropSet->setPropertyValue(sPropertyFixed, Any(bFixed));

    // set content if fixed
    if (!bFixed)
        return;

    // organizer or styles-only mode: force update
    if (GetImport().GetTextImport()->IsOrganizerMode() ||
        GetImport().GetTextImport()->IsStylesOnlyMode()   )
    {
        ForceUpdate(rPropSet);
    }
    else
    {
        aAny <<= GetContent();
        rPropSet->setPropertyValue(sPropertyContent, aAny);
    }
}


// page continuation string


SvXMLEnumMapEntry<PageNumberType> const lcl_aSelectPageAttrMap[] =
{
    { XML_PREVIOUS,      PageNumberType_PREV },
    { XML_CURRENT,       PageNumberType_CURRENT },
    { XML_NEXT,          PageNumberType_NEXT },
    { XML_TOKEN_INVALID, PageNumberType(0) },
};

constexpr OUStringLiteral gsPropertyUserText(u"UserText");

XMLPageContinuationImportContext::XMLPageContinuationImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp)
:   XMLTextFieldImportContext(rImport, rHlp, sAPI_page_number)
,   sPropertySubType(sAPI_sub_type)
,   sPropertyNumberingType(sAPI_numbering_type)
,   eSelectPage(PageNumberType_CURRENT)
,   sStringOK(false)
{
    bValid = true;
}

void XMLPageContinuationImportContext::ProcessAttribute(
    sal_Int32 nAttrToken, std::string_view sAttrValue )
{
    switch(nAttrToken)
    {
        case XML_ELEMENT(TEXT, XML_SELECT_PAGE):
        {
            PageNumberType nTmp;
            if (SvXMLUnitConverter::convertEnum(nTmp, sAttrValue,
                                                lcl_aSelectPageAttrMap)
                && (PageNumberType_CURRENT != nTmp) )
            {
                eSelectPage = nTmp;
            }
            break;
        }
        case XML_ELEMENT(TEXT, XML_STRING_VALUE):
        case XML_ELEMENT(OFFICE, XML_STRING_VALUE):
            sString = OUString::fromUtf8(sAttrValue);
            sStringOK = true;
            break;
        default:
            XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
    }
}

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

    xPropertySet->setPropertyValue(sPropertySubType, Any(eSelectPage));

    aAny <<= (sStringOK ? sString : GetContent());
    xPropertySet->setPropertyValue(gsPropertyUserText, aAny);

    aAny <<= style::NumberingType::CHAR_SPECIAL;
    xPropertySet->setPropertyValue(sPropertyNumberingType, aAny);
}


// page number field


XMLPageNumberImportContext::XMLPageNumberImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp)
:   XMLTextFieldImportContext(rImport, rHlp, sAPI_page_number)
,   sPropertySubType(sAPI_sub_type)
,   sPropertyNumberingType(sAPI_numbering_type)
,   sPropertyOffset(sAPI_offset)
,   sNumberSync(GetXMLToken(XML_FALSE))
,   nPageAdjust(0)
,   eSelectPage(PageNumberType_CURRENT)
,   sNumberFormatOK(false)
{
    bValid = true;
}

void XMLPageNumberImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
        case XML_ELEMENT(STYLE, XML_NUM_FORMAT):
            sNumberFormat = OUString::fromUtf8(sAttrValue);
            sNumberFormatOK = true;
            break;
        case XML_ELEMENT(STYLE, XML_NUM_LETTER_SYNC):
            sNumberSync = OUString::fromUtf8(sAttrValue);
            break;
        case XML_ELEMENT(TEXT, XML_SELECT_PAGE):
            SvXMLUnitConverter::convertEnum(eSelectPage, sAttrValue,
                                                lcl_aSelectPageAttrMap);
            break;
        case XML_ELEMENT(TEXT, XML_PAGE_ADJUST):
        {
            sal_Int32 nTmp;
            if (::sax::Converter::convertNumber(nTmp, sAttrValue))
            {
                nPageAdjust = static_cast<sal_Int16>(nTmp);
            }
            break;
        }
        default:
            XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
    }
}

void XMLPageNumberImportContext::PrepareField(
        const Reference<XPropertySet> & xPropertySet)
{
    // all properties are optional
    Reference<XPropertySetInfo> xPropertySetInfo(
        xPropertySet->getPropertySetInfo());

    if (xPropertySetInfo->hasPropertyByName(sPropertyNumberingType))
    {
        sal_Int16 nNumType;
        if( sNumberFormatOK )
        {
            nNumType= style::NumberingType::ARABIC;
            GetImport().GetMM100UnitConverter().convertNumFormat( nNumType,
                                                    sNumberFormat,
                                                    sNumberSync );
        }
        else
            nNumType = style::NumberingType::PAGE_DESCRIPTOR;

        xPropertySet->setPropertyValue(sPropertyNumberingType, Any(nNumType));
    }

    if (xPropertySetInfo->hasPropertyByName(sPropertyOffset))
    {
        // adjust offset
        switch (eSelectPage)
        {
            case PageNumberType_PREV:
                nPageAdjust--;
                break;
            case PageNumberType_CURRENT:
                break;
            case PageNumberType_NEXT:
                nPageAdjust++;
                break;
            default:
                SAL_WARN("xmloff.text""unknown page number type");
        }
        xPropertySet->setPropertyValue(sPropertyOffset, Any(nPageAdjust));
    }

    if (xPropertySetInfo->hasPropertyByName(sPropertySubType))
    {
        xPropertySet->setPropertyValue(sPropertySubType, Any(eSelectPage));
    }
}


// Placeholder


constexpr OUStringLiteral gsPropertyPlaceholderType(u"PlaceHolderType");
constexpr OUStringLiteral gsPropertyPlaceholder(u"PlaceHolder");

XMLPlaceholderFieldImportContext::XMLPlaceholderFieldImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp)
:   XMLTextFieldImportContext(rImport, rHlp, u"JumpEdit"_ustr)
,   sPropertyHint(sAPI_hint)
,   nPlaceholderType(PlaceholderType::TEXT)
{
}

/// process attribute values
void XMLPlaceholderFieldImportContext::ProcessAttribute(
    sal_Int32 nAttrToken, std::string_view sAttrValue )
{
    switch (nAttrToken) {
    case XML_ELEMENT(TEXT, XML_DESCRIPTION):
        sDescription = OUString::fromUtf8(sAttrValue);
        break;

    case XML_ELEMENT(TEXT, XML_PLACEHOLDER_TYPE):
        bValid = true;
        if (IsXMLToken(sAttrValue, XML_TABLE))
        {
            nPlaceholderType = PlaceholderType::TABLE;
        }
        else if (IsXMLToken(sAttrValue, XML_TEXT))
        {
            nPlaceholderType = PlaceholderType::TEXT;
        }
        else if (IsXMLToken(sAttrValue, XML_TEXT_BOX))
        {
            nPlaceholderType = PlaceholderType::TEXTFRAME;
        }
        else if (IsXMLToken(sAttrValue, XML_IMAGE))
        {
            nPlaceholderType = PlaceholderType::GRAPHIC;
        }
        else if (IsXMLToken(sAttrValue, XML_OBJECT))
        {
            nPlaceholderType = PlaceholderType::OBJECT;
        }
        else
        {
            bValid = false;
        }
        break;

    default:
        // ignore
        XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
    }
}

void XMLPlaceholderFieldImportContext::PrepareField(
    const Reference<XPropertySet> & xPropertySet) {

    Any aAny;
    xPropertySet->setPropertyValue(sPropertyHint, Any(sDescription));

    // remove <...> around content (if present)
    OUString aContent = GetContent();
    sal_Int32 nStart = 0;
    sal_Int32 nLength = aContent.getLength();
    if (aContent.startsWith("<"))
    {
        --nLength;
        ++nStart;
    }
    if (aContent.endsWith(">"))
    {
        --nLength;
    }
    aAny <<= aContent.copy(nStart, nLength);
    xPropertySet->setPropertyValue(gsPropertyPlaceholder, aAny);

    xPropertySet->setPropertyValue(gsPropertyPlaceholderType, Any(nPlaceholderType));
}


// time field

constexpr OUString gsPropertyAdjust(u"Adjust"_ustr);

XMLTimeFieldImportContext::XMLTimeFieldImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp)
:   XMLTextFieldImportContext(rImport, rHlp, sAPI_date_time)
,   sPropertyNumberFormat(sAPI_number_format)
,   sPropertyFixed(sAPI_is_fixed)
,   sPropertyDateTimeValue(sAPI_date_time_value)
,   sPropertyDateTime(sAPI_date_time)
,   sPropertyIsDate(sAPI_is_date)
,   sPropertyIsFixedLanguage(sAPI_is_fixed_language)
,   nAdjust(0)
,   nFormatKey(0)
,   bTimeOK(false)
,   bFormatOK(false)
,   bFixed(false)
,   bIsDate(false)
,   bIsDefaultLanguage( true )
{
    bValid = true;  // always valid!
}

void XMLTimeFieldImportContext::ProcessAttribute(
    sal_Int32 nAttrToken, std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
        case XML_ELEMENT(TEXT, XML_TIME_VALUE):
        case XML_ELEMENT(OFFICE, XML_TIME_VALUE):
        {
            if (::sax::Converter::parseTimeOrDateTime(aDateTimeValue, sAttrValue))
            {
                bTimeOK = true;
            }
            break;
        }
        case XML_ELEMENT(TEXT, XML_FIXED):
        {
            bool bTmp(false);
            if (::sax::Converter::convertBool(bTmp, sAttrValue))
            {
                bFixed = bTmp;
            }
            break;
        }
        case XML_ELEMENT(STYLE, XML_DATA_STYLE_NAME):
        {
            sal_Int32 nKey = GetImportHelper().GetDataStyleKey(
                                               OUString::fromUtf8(sAttrValue), &bIsDefaultLanguage);
            if (-1 != nKey)
            {
                nFormatKey = nKey;
                bFormatOK = true;
            }
            break;
        }
        case XML_ELEMENT(TEXT, XML_TIME_ADJUST):
        {
            double fTmp;

            if (::sax::Converter::convertDuration(fTmp, sAttrValue))
            {
                // convert to minutes
                nAdjust = static_cast<sal_Int32>(::rtl::math::approxFloor(fTmp * 60 * 24));
            }
            break;
        }
        default:
            XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
    }
}

void XMLTimeFieldImportContext::PrepareField(
    const Reference<XPropertySet> & rPropertySet)
{
    // all properties are optional (except IsDate)
    Reference<XPropertySetInfo> xPropertySetInfo(
        rPropertySet->getPropertySetInfo());

    if (xPropertySetInfo->hasPropertyByName(sPropertyFixed))
    {
        rPropertySet->setPropertyValue(sPropertyFixed, Any(bFixed));
    }

    rPropertySet->setPropertyValue(sPropertyIsDate, Any(bIsDate));

    if (xPropertySetInfo->hasPropertyByName(gsPropertyAdjust))
    {
        rPropertySet->setPropertyValue(gsPropertyAdjust, Any(nAdjust));
    }

    // set value
    if (bFixed)
    {
        // organizer or styles-only mode: force update
        if (GetImport().GetTextImport()->IsOrganizerMode() ||
            GetImport().GetTextImport()->IsStylesOnlyMode()   )
        {
            ForceUpdate(rPropertySet);
        }
        else
        {
            // normal mode: set value (if present)
            if (bTimeOK)
            {
               if (xPropertySetInfo->hasPropertyByName(sPropertyDateTimeValue))
               {
                   rPropertySet->setPropertyValue(sPropertyDateTimeValue, Any(aDateTimeValue));
               }
               else if (xPropertySetInfo->hasPropertyByName(sPropertyDateTime))
               {
                   rPropertySet->setPropertyValue(sPropertyDateTime, Any(aDateTimeValue));
               }
            }
        }
    }

    if (bFormatOK &&
        xPropertySetInfo->hasPropertyByName(sPropertyNumberFormat))
    {
        rPropertySet->setPropertyValue(sPropertyNumberFormat, Any(nFormatKey));

        if( xPropertySetInfo->hasPropertyByName( sPropertyIsFixedLanguage ) )
        {
            bool bIsFixedLanguage = ! bIsDefaultLanguage;
            rPropertySet->setPropertyValue( sPropertyIsFixedLanguage, Any(bIsFixedLanguage) );
        }
    }
}


// date field


XMLDateFieldImportContext::XMLDateFieldImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp) :
        XMLTimeFieldImportContext(rImport, rHlp)
{
    bIsDate = true// always a date!
}

void XMLDateFieldImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
        case XML_ELEMENT(TEXT, XML_DATE_VALUE):
        case XML_ELEMENT(OFFICE, XML_DATE_VALUE):
        {
            if (::sax::Converter::parseDateTime(aDateTimeValue, sAttrValue))
            {
                bTimeOK = true;
            }
            break;
        }
        case XML_ELEMENT(TEXT, XML_DATE_ADJUST):
            // delegate to superclass, pretending it was a time-adjust attr.
            XMLTimeFieldImportContext::ProcessAttribute(
                XML_ELEMENT(TEXT, XML_TIME_ADJUST),
                sAttrValue);
            break;
        case XML_ELEMENT(TEXT, XML_TIME_VALUE):
        case XML_ELEMENT(OFFICE, XML_TIME_VALUE):
        case XML_ELEMENT(TEXT, XML_TIME_ADJUST):
            ; // ignore time-adjust and time-value attributes
            break;
        default:
            // all others: delegate to super-class
            return XMLTimeFieldImportContext::ProcessAttribute(nAttrToken,
                                                        sAttrValue);
            break;
    }
}


// database field superclass


constexpr OUStringLiteral gsPropertyDataBaseName(u"DataBaseName");
constexpr OUStringLiteral gsPropertyDataBaseURL(u"DataBaseURL");
constexpr OUStringLiteral gsPropertyTableName(u"DataTableName");
constexpr OUStringLiteral gsPropertyDataCommandType(u"DataCommandType");
constexpr OUStringLiteral gsPropertyIsVisible(u"IsVisible");

XMLDatabaseFieldImportContext::XMLDatabaseFieldImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp,
    const OUString& pServiceName, bool bUseDisplay)
:   XMLTextFieldImportContext(rImport, rHlp, pServiceName)
,   m_nCommandType( sdb::CommandType::TABLE )
,   m_bCommandTypeOK(false)
,   m_bDisplay( true )
,   m_bDisplayOK( false )
,   m_bUseDisplay( bUseDisplay )
,   m_bDatabaseOK(false)
,   m_bDatabaseNameOK(false)
,   m_bDatabaseURLOK(false)
,   m_bTableOK(false)
{
}

void XMLDatabaseFieldImportContext::ProcessAttribute(
    sal_Int32 nAttrToken, std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
        case XML_ELEMENT(TEXT, XML_DATABASE_NAME):
            m_sDatabaseName = OUString::fromUtf8(sAttrValue);
            m_bDatabaseOK = true;
            m_bDatabaseNameOK = true;
            break;
        case XML_ELEMENT(TEXT, XML_TABLE_NAME):
            m_sTableName = OUString::fromUtf8(sAttrValue);
            m_bTableOK = true;
            break;
        case  XML_ELEMENT(TEXT, XML_TABLE_TYPE):
            if( IsXMLToken( sAttrValue, XML_TABLE ) )
            {
                m_nCommandType = sdb::CommandType::TABLE;
                m_bCommandTypeOK = true;
            }
            else if( IsXMLToken( sAttrValue, XML_QUERY ) )
            {
                m_nCommandType = sdb::CommandType::QUERY;
                m_bCommandTypeOK = true;
            }
            else if( IsXMLToken( sAttrValue, XML_COMMAND ) )
            {
                m_nCommandType = sdb::CommandType::COMMAND;
                m_bCommandTypeOK = true;
            }
            break;
        case XML_ELEMENT(TEXT, XML_DISPLAY):
            if( IsXMLToken( sAttrValue, XML_NONE ) )
            {
                m_bDisplay = false;
                m_bDisplayOK = true;
            }
            else if( IsXMLToken( sAttrValue, XML_VALUE ) )
            {
                m_bDisplay = true;
                m_bDisplayOK = true;
            }
            break;
        default:
            XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
    }
}

css::uno::Reference< css::xml::sax::XFastContextHandler > XMLDatabaseFieldImportContext::createFastChildContext(
    sal_Int32 nElement,
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
{
    if (nElement == XML_ELEMENT(FORM, XML_CONNECTION_RESOURCE) )
    {
        forauto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
        {
            switch (aIter.getToken())
            {
                case XML_ELEMENT(XLINK, XML_HREF):
                {
                    m_sDatabaseURL = aIter.toString();
                    m_bDatabaseOK = true;
                    m_bDatabaseURLOK = true;
                }
                break;
                default:;
            }
        }

        // we call ProcessAttribute in order to set bValid appropriately
        ProcessAttribute( XML_TOKEN_INVALID, "" );
    }
    else
        XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);

    return nullptr;
}


void XMLDatabaseFieldImportContext::PrepareField(
        const Reference<XPropertySet> & xPropertySet)
{
    xPropertySet->setPropertyValue(gsPropertyTableName, Any(m_sTableName));

    if( m_bDatabaseNameOK )
    {
        xPropertySet->setPropertyValue(gsPropertyDataBaseName, Any(m_sDatabaseName));
    }
    else if( m_bDatabaseURLOK )
    {
        xPropertySet->setPropertyValue(gsPropertyDataBaseURL, Any(m_sDatabaseURL));
    }

    // #99980# load/save command type for all fields; also load
    //         old documents without command type
    if( m_bCommandTypeOK )
    {
        xPropertySet->setPropertyValue( gsPropertyDataCommandType, Any(m_nCommandType) );
    }

    if( m_bUseDisplay && m_bDisplayOK )
    {
        xPropertySet->setPropertyValue( gsPropertyIsVisible, Any(m_bDisplay) );
    }
}


// database name field


XMLDatabaseNameImportContext::XMLDatabaseNameImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp) :
        XMLDatabaseFieldImportContext(rImport, rHlp, u"DatabaseName"_ustr, true)
{
}

void XMLDatabaseNameImportContext::ProcessAttribute(
    sal_Int32 nAttrToken, std::string_view sAttrValue )
{
    // delegate to superclass and check for success
    XMLDatabaseFieldImportContext::ProcessAttribute(nAttrToken, sAttrValue);
    bValid = m_bDatabaseOK && m_bTableOK;
}


// database next field


XMLDatabaseNextImportContext::XMLDatabaseNextImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp,
    const OUString& pServiceName) :
        XMLDatabaseFieldImportContext(rImport, rHlp, pServiceName, false),
        sPropertyCondition(sAPI_condition),
        sTrue(sAPI_true),
        bConditionOK(false)
{
}

XMLDatabaseNextImportContext::XMLDatabaseNextImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp)
: XMLDatabaseFieldImportContext(rImport, rHlp, u"DatabaseNextSet"_ustr, false)
,   sPropertyCondition(sAPI_condition)
,   sTrue(sAPI_true)
,   bConditionOK(false)
{
}

void XMLDatabaseNextImportContext::ProcessAttribute(
    sal_Int32 nAttrToken, std::string_view sAttrValue )
{
    if (XML_ELEMENT(TEXT, XML_CONDITION) == nAttrToken)
    {
        OUString sTmp;
        sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrValueQName(
                                    OUString::fromUtf8(sAttrValue), &sTmp );
        if( XML_NAMESPACE_OOOW == nPrefix )
        {
            sCondition = sTmp;
            bConditionOK = true;
        }
        else
            sCondition = OUString::fromUtf8(sAttrValue);
    }
    else
    {
        XMLDatabaseFieldImportContext::ProcessAttribute(nAttrToken,
                                                        sAttrValue);
    }

    bValid = m_bDatabaseOK && m_bTableOK;
}

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

    aAny <<= bConditionOK ? sCondition : sTrue;
    xPropertySet->setPropertyValue(sPropertyCondition, aAny);

    XMLDatabaseFieldImportContext::PrepareField(xPropertySet);
}


// database select field


XMLDatabaseSelectImportContext::XMLDatabaseSelectImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp) :
        XMLDatabaseNextImportContext(rImport, rHlp, u"DatabaseNumberOfSet"_ustr),
        sPropertySetNumber(sAPI_set_number),
        nNumber(0),
        bNumberOK(false)
{
}

void XMLDatabaseSelectImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    if (XML_ELEMENT(TEXT, XML_ROW_NUMBER) == nAttrToken)
    {
        sal_Int32 nTmp;
        if (::sax::Converter::convertNumber( nTmp, sAttrValue
                                               /* , nMin, nMax ??? */ ))
        {
            nNumber = nTmp;
            bNumberOK = true;
        }
    }
    else
    {
        XMLDatabaseNextImportContext::ProcessAttribute(nAttrToken, sAttrValue);
    }

    bValid = m_bTableOK && m_bDatabaseOK && bNumberOK;
}

void XMLDatabaseSelectImportContext::PrepareField(
    const Reference<XPropertySet> & xPropertySet)
{
    xPropertySet->setPropertyValue(sPropertySetNumber, Any(nNumber));

    XMLDatabaseNextImportContext::PrepareField(xPropertySet);
}


// database display row number field


XMLDatabaseNumberImportContext::XMLDatabaseNumberImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp) :
        XMLDatabaseFieldImportContext(rImport, rHlp, u"DatabaseSetNumber"_ustr, true),
        sPropertyNumberingType(
            sAPI_numbering_type),
        sPropertySetNumber(sAPI_set_number),
        sNumberFormat(u"1"_ustr),
        sNumberSync(GetXMLToken(XML_FALSE)),
        nValue(0),
        bValueOK(false)
{
}

void XMLDatabaseNumberImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
        case XML_ELEMENT(STYLE, XML_NUM_FORMAT):
            sNumberFormat = OUString::fromUtf8(sAttrValue);
            break;
        case XML_ELEMENT(STYLE, XML_NUM_LETTER_SYNC):
            sNumberSync = OUString::fromUtf8(sAttrValue);
            break;
        case XML_ELEMENT(TEXT, XML_VALUE_TYPE):
        case XML_ELEMENT(OFFICE, XML_VALUE_TYPE):
        {
            sal_Int32 nTmp;
            if (::sax::Converter::convertNumber( nTmp, sAttrValue ))
            {
                nValue = nTmp;
                bValueOK = true;
            }
            break;
        }
        default:
            XMLDatabaseFieldImportContext::ProcessAttribute(nAttrToken,
                                                            sAttrValue);
            break;
    }

    bValid = m_bTableOK && m_bDatabaseOK;
}

void XMLDatabaseNumberImportContext::PrepareField(
    const Reference<XPropertySet> & xPropertySet)
{
    sal_Int16 nNumType = style::NumberingType::ARABIC;
    GetImport().GetMM100UnitConverter().convertNumFormat( nNumType,
                                                    sNumberFormat,
                                                    sNumberSync );
    xPropertySet->setPropertyValue(sPropertyNumberingType, Any(nNumType));

    if (bValueOK)
    {
        xPropertySet->setPropertyValue(sPropertySetNumber, Any(nValue));
    }

    XMLDatabaseFieldImportContext::PrepareField(xPropertySet);
}


// Simple doc info fields


XMLSimpleDocInfoImportContext::XMLSimpleDocInfoImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp,
    sal_Int32 nElementToken,
    bool bContent, bool bAuthor)
:   XMLTextFieldImportContext(rImport, rHlp, MapTokenToServiceName(nElementToken) )
,   sPropertyFixed(sAPI_is_fixed)
,   sPropertyContent(sAPI_content)
,   sPropertyAuthor(sAPI_author)
,   sPropertyCurrentPresentation(sAPI_current_presentation)
,   bFixed(false)
,   bHasAuthor(bAuthor)
,   bHasContent(bContent)
{
    bValid = true;
}

void XMLSimpleDocInfoImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    if (XML_ELEMENT(TEXT, XML_FIXED) == nAttrToken)
    {
        bool bTmp(false);
        if (::sax::Converter::convertBool(bTmp, sAttrValue))
        {
            bFixed = bTmp;
        }
    }
    else
        XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
}

void XMLSimpleDocInfoImportContext::PrepareField(
    const Reference<XPropertySet> & rPropertySet)
{
    //  title field in Calc has no Fixed property
    Reference<XPropertySetInfo> xPropertySetInfo(rPropertySet->getPropertySetInfo());
    if (!xPropertySetInfo->hasPropertyByName(sPropertyFixed))
        return;

    Any aAny;
    rPropertySet->setPropertyValue(sPropertyFixed, Any(bFixed));

    // set Content and CurrentPresentation (if fixed)
    if (!bFixed)
        return;

    // in organizer-mode or styles-only-mode, only force update
    if (GetImport().GetTextImport()->IsOrganizerMode() ||
        GetImport().GetTextImport()->IsStylesOnlyMode()   )
    {
        ForceUpdate(rPropertySet);
    }
    else
    {
        // set content (author, if that's the name) and current
        // presentation
        aAny <<= GetContent();

        if (bFixed && bHasAuthor)
        {
            rPropertySet->setPropertyValue(sPropertyAuthor, aAny);
        }

        if (bFixed && bHasContent)
        {
            rPropertySet->setPropertyValue(sPropertyContent, aAny);
        }

        rPropertySet->setPropertyValue(sPropertyCurrentPresentation, aAny);
    }
}

OUString XMLSimpleDocInfoImportContext::MapTokenToServiceName(
    sal_Int32 nElementToken)
{
    OUString pServiceName;

    switch(nElementToken)
    {
        case XML_ELEMENT(TEXT, XML_INITIAL_CREATOR):
            pServiceName = "DocInfo.CreateAuthor";
            break;
        case XML_ELEMENT(TEXT, XML_CREATION_DATE):
            pServiceName = sAPI_docinfo_create_date_time;
            break;
        case XML_ELEMENT(TEXT, XML_CREATION_TIME):
            pServiceName = sAPI_docinfo_create_date_time;
            break;
        case XML_ELEMENT(TEXT, XML_DESCRIPTION):
            pServiceName = "DocInfo.Description";
            break;
        case XML_ELEMENT(TEXT, XML_EDITING_DURATION):
            pServiceName = "DocInfo.EditTime";
            break;
        case XML_ELEMENT(TEXT, XML_USER_DEFINED):
            pServiceName = sAPI_docinfo_custom;
            break;
        case XML_ELEMENT(TEXT, XML_PRINTED_BY):
            pServiceName = "DocInfo.PrintAuthor";
            break;
        case XML_ELEMENT(TEXT, XML_PRINT_DATE):
            pServiceName = sAPI_docinfo_print_date_time;
            break;
        case XML_ELEMENT(TEXT, XML_PRINT_TIME):
            pServiceName = sAPI_docinfo_print_date_time;
            break;
        case XML_ELEMENT(TEXT, XML_KEYWORDS):
            pServiceName = "DocInfo.KeyWords";
            break;
        case XML_ELEMENT(TEXT, XML_SUBJECT):
            pServiceName = "DocInfo.Subject";
            break;
        case XML_ELEMENT(TEXT, XML_EDITING_CYCLES):
            pServiceName = "DocInfo.Revision";
            break;
        case XML_ELEMENT(TEXT, XML_CREATOR):
            pServiceName = "DocInfo.ChangeAuthor";
            break;
        case XML_ELEMENT(TEXT, XML_MODIFICATION_DATE):
            pServiceName = sAPI_docinfo_change_date_time;
            break;
        case XML_ELEMENT(TEXT, XML_MODIFICATION_TIME):
            pServiceName = sAPI_docinfo_change_date_time;
            break;
        case XML_ELEMENT(TEXT, XML_TITLE):
            pServiceName = "DocInfo.Title";
            break;
        default:
            XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElementToken);
            assert(false);
    }

    return pServiceName;
}


// revision field

constexpr OUStringLiteral sPropertyRevision(u"Revision");

XMLRevisionDocInfoImportContext::XMLRevisionDocInfoImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp, sal_Int32 nElement) :
        XMLSimpleDocInfoImportContext(rImport, rHlp, nElement, falsefalse)
{
    bValid = true;
}

void XMLRevisionDocInfoImportContext::PrepareField(
    const Reference<XPropertySet> & rPropertySet)
{
    XMLSimpleDocInfoImportContext::PrepareField(rPropertySet);

    // set revision number
    // if fixed, if not in organizer-mode, if not in styles-only-mode
    if (!bFixed)
        return;

    if ( GetImport().GetTextImport()->IsOrganizerMode() ||
         GetImport().GetTextImport()->IsStylesOnlyMode()   )
    {
        ForceUpdate(rPropertySet);
    }
    else
    {
        sal_Int32 nTmp;
        if (::sax::Converter::convertNumber(nTmp, GetContent()))
        {
            rPropertySet->setPropertyValue(sPropertyRevision, Any(nTmp));
        }
    }
}


// DocInfo fields with date/time attributes


XMLDateTimeDocInfoImportContext::XMLDateTimeDocInfoImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp, sal_Int32 nElement)
    : XMLSimpleDocInfoImportContext(rImport, rHlp, nElement, falsefalse)
    , sPropertyNumberFormat(sAPI_number_format)
    , sPropertyIsDate(sAPI_is_date)
    , sPropertyIsFixedLanguage(sAPI_is_fixed_language)
    , nFormat(0)
    , bFormatOK(false)
    , bIsDate(false)
    , bHasDateTime(false)
    , bIsDefaultLanguage(true)
{
    // we allow processing of EDIT_DURATION here, because import of actual
    // is not supported anyway. If it was, we'd need an extra import class
    // because times and time durations are presented differently!

    bValid = true;
    switch (nElement)
    {
        case XML_ELEMENT(TEXT, XML_CREATION_DATE):
        case XML_ELEMENT(TEXT, XML_PRINT_DATE):
        case XML_ELEMENT(TEXT, XML_MODIFICATION_DATE):
            bIsDate = true;
            bHasDateTime = true;
            break;
        case XML_ELEMENT(TEXT, XML_CREATION_TIME):
        case XML_ELEMENT(TEXT, XML_PRINT_TIME):
        case XML_ELEMENT(TEXT, XML_MODIFICATION_TIME):
            bIsDate = false;
            bHasDateTime = true;
            break;
        case XML_ELEMENT(TEXT, XML_EDITING_DURATION):
            bIsDate = false;
            bHasDateTime = false;
            break;
        default:
            XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
            OSL_FAIL("XMLDateTimeDocInfoImportContext needs date/time doc. fields");
            bValid = false;
            break;
    }
}

void XMLDateTimeDocInfoImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
        case XML_ELEMENT(STYLE, XML_DATA_STYLE_NAME):
        {
            sal_Int32 nKey = GetImportHelper().GetDataStyleKey(
                                               OUString::fromUtf8(sAttrValue), &bIsDefaultLanguage);
            if (-1 != nKey)
            {
                nFormat = nKey;
                bFormatOK = true;
            }
            break;
        }
        case XML_ELEMENT(TEXT, XML_FIXED):
            XMLSimpleDocInfoImportContext::ProcessAttribute(nAttrToken,
                                                            sAttrValue);
            break;
        default:
            // ignore -> we can't set date/time value anyway!
            break;
    }
}

void XMLDateTimeDocInfoImportContext::PrepareField(
    const Reference<XPropertySet> & xPropertySet)
{
    // process fixed and presentation
    XMLSimpleDocInfoImportContext::PrepareField(xPropertySet);

    if (bHasDateTime)
    {
        xPropertySet->setPropertyValue(sPropertyIsDate, Any(bIsDate));
    }

    if (bFormatOK)
    {
        xPropertySet->setPropertyValue(sPropertyNumberFormat, Any(nFormat));

        if( xPropertySet->getPropertySetInfo()->
                hasPropertyByName( sPropertyIsFixedLanguage ) )
        {
            bool bIsFixedLanguage = ! bIsDefaultLanguage;
            xPropertySet->setPropertyValue( sPropertyIsFixedLanguage, Any(bIsFixedLanguage) );
        }
    }

    // can't set date/time/duration value! Sorry.
}


// user defined docinfo fields


XMLUserDocInfoImportContext::XMLUserDocInfoImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp,
    sal_Int32 nElement) :
        XMLSimpleDocInfoImportContext(rImport, rHlp, nElement, falsefalse)
    , sPropertyName(sAPI_name)
    , sPropertyNumberFormat(sAPI_number_format)
    , sPropertyIsFixedLanguage(sAPI_is_fixed_language)
    , nFormat(0)
    , bFormatOK(false)
    , bIsDefaultLanguage( true )
{
    bValid = false;
}

void XMLUserDocInfoImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
        case XML_ELEMENT(STYLE, XML_DATA_STYLE_NAME):
        {
            sal_Int32 nKey = GetImportHelper().GetDataStyleKey(
                                               OUString::fromUtf8(sAttrValue), &bIsDefaultLanguage);
            if (-1 != nKey)
            {
                nFormat = nKey;
                bFormatOK = true;
            }
            break;
        }
        case XML_ELEMENT(TEXT, XML_NAME):
        {
            if (!bValid)
            {
                SetServiceName(sAPI_docinfo_custom );
                aName = OUString::fromUtf8(sAttrValue);
                bValid = true;
            }
            break;
        }

        default:
            XMLSimpleDocInfoImportContext::ProcessAttribute(nAttrToken,
                                                            sAttrValue);
            break;
    }
}

void XMLUserDocInfoImportContext::PrepareField(
        const css::uno::Reference<css::beans::XPropertySet> & xPropertySet)
{
    if ( !aName.isEmpty() )
    {
        xPropertySet->setPropertyValue(sPropertyName, Any(aName));
    }
    Reference<XPropertySetInfo> xPropertySetInfo(
        xPropertySet->getPropertySetInfo());
    if (bFormatOK &&
        xPropertySetInfo->hasPropertyByName(sPropertyNumberFormat))
    {
        xPropertySet->setPropertyValue(sPropertyNumberFormat, Any(nFormat));

        if( xPropertySetInfo->hasPropertyByName( sPropertyIsFixedLanguage ) )
        {
            bool bIsFixedLanguage = ! bIsDefaultLanguage;
            xPropertySet->setPropertyValue( sPropertyIsFixedLanguage, Any(bIsFixedLanguage) );
        }
    }

    // call superclass to handle "fixed"
    XMLSimpleDocInfoImportContext::PrepareField(xPropertySet);
}


// import hidden paragraph fields


XMLHiddenParagraphImportContext::XMLHiddenParagraphImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp) :
        XMLTextFieldImportContext(rImport, rHlp, u"HiddenParagraph"_ustr),
        sPropertyCondition(sAPI_condition),
        sPropertyIsHidden(sAPI_is_hidden),
        bIsHidden(false)
{
}

void XMLHiddenParagraphImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    if ( XML_ELEMENT(TEXT, XML_CONDITION) == nAttrToken)
    {
        OUString sTmp;
        sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrValueQName(
                                    OUString::fromUtf8(sAttrValue), &sTmp );
        if( XML_NAMESPACE_OOOW == nPrefix )
        {
            sCondition = sTmp;
            bValid = true;
        }
        else
            sCondition = OUString::fromUtf8(sAttrValue);
    }
    else if ( XML_ELEMENT(TEXT, XML_IS_HIDDEN) == nAttrToken)
    {
        bool bTmp(false);
        if (::sax::Converter::convertBool(bTmp, sAttrValue))
        {
            bIsHidden = bTmp;
        }
    }
    else
        XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
}

void XMLHiddenParagraphImportContext::PrepareField(
    const Reference<XPropertySet> & xPropertySet)
{
    xPropertySet->setPropertyValue(sPropertyCondition, Any(sCondition));
    xPropertySet->setPropertyValue(sPropertyIsHidden, Any(bIsHidden));
}


// import conditional text (<text:conditional-text>)

constexpr OUStringLiteral gsPropertyTrueContent(u"TrueContent");
constexpr OUStringLiteral gsPropertyFalseContent(u"FalseContent");
constexpr OUStringLiteral gsPropertyIsConditionTrue(u"IsConditionTrue");

XMLConditionalTextImportContext::XMLConditionalTextImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp) :
        XMLTextFieldImportContext(rImport, rHlp, u"ConditionalText"_ustr),
        sPropertyCondition(sAPI_condition),
        sPropertyCurrentPresentation(sAPI_current_presentation),
        bConditionOK(false),
        bTrueOK(false),
        bFalseOK(false),
        bCurrentValue(false)
{
}

void XMLConditionalTextImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
        case XML_ELEMENT(TEXT, XML_CONDITION):
            {
                OUString sTmp;
                sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
                        GetKeyByAttrValueQName(OUString::fromUtf8(sAttrValue), &sTmp);
                if( XML_NAMESPACE_OOOW == nPrefix )
                {
                    sCondition = sTmp;
                    bConditionOK = true;
                }
                else
                    sCondition = OUString::fromUtf8(sAttrValue);
            }
            break;
        case XML_ELEMENT(TEXT, XML_STRING_VALUE_IF_FALSE):
            sFalseContent = OUString::fromUtf8(sAttrValue);
            bFalseOK = true;
            break;
        case XML_ELEMENT(TEXT, XML_STRING_VALUE_IF_TRUE):
            sTrueContent = OUString::fromUtf8(sAttrValue);
            bTrueOK = true;
            break;
        case XML_ELEMENT(TEXT, XML_CURRENT_VALUE):
        {
            bool bTmp(false);
            if (::sax::Converter::convertBool(bTmp, sAttrValue))
            {
                bCurrentValue = bTmp;
            }
            break;
        }
        default:
            XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
    }

    bValid = bConditionOK && bFalseOK && bTrueOK;
}

void XMLConditionalTextImportContext::PrepareField(
    const Reference<XPropertySet> & xPropertySet)
{
    xPropertySet->setPropertyValue(sPropertyCondition, Any(sCondition));
    xPropertySet->setPropertyValue(gsPropertyFalseContent, Any(sFalseContent));
    xPropertySet->setPropertyValue(gsPropertyTrueContent, Any(sTrueContent));
    xPropertySet->setPropertyValue(gsPropertyIsConditionTrue, Any(bCurrentValue));
    xPropertySet->setPropertyValue(sPropertyCurrentPresentation, Any(GetContent()));
}


// hidden text


XMLHiddenTextImportContext::XMLHiddenTextImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp) :
        XMLTextFieldImportContext(rImport, rHlp, u"HiddenText"_ustr),
        sPropertyCondition(sAPI_condition),
        sPropertyContent(sAPI_content),
        sPropertyIsHidden(sAPI_is_hidden),
        bConditionOK(false),
        bStringOK(false),
        bIsHidden(false)
{
}

void XMLHiddenTextImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
        case XML_ELEMENT(TEXT, XML_CONDITION):
            {
                OUString sTmp;
                sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
                            GetKeyByAttrValueQName(OUString::fromUtf8(sAttrValue), &sTmp);
                if( XML_NAMESPACE_OOOW == nPrefix )
                {
                    sCondition = sTmp;
                    bConditionOK = true;
                }
                else
                    sCondition = OUString::fromUtf8(sAttrValue);
            }
            break;
        case XML_ELEMENT(TEXT, XML_STRING_VALUE):
        case XML_ELEMENT(OFFICE, XML_STRING_VALUE):
            sString = OUString::fromUtf8(sAttrValue);
            bStringOK = true;
            break;
        case XML_ELEMENT(TEXT, XML_IS_HIDDEN):
        {
            bool bTmp(false);
            if (::sax::Converter::convertBool(bTmp, sAttrValue))
            {
                bIsHidden = bTmp;
            }
            break;
        }
        default:
            XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
    }

    bValid = bConditionOK && bStringOK;
}

void XMLHiddenTextImportContext::PrepareField(
        const Reference<XPropertySet> & xPropertySet)
{
    xPropertySet->setPropertyValue(sPropertyCondition, Any(sCondition));
    xPropertySet->setPropertyValue(sPropertyContent, Any(sString));
    xPropertySet->setPropertyValue(sPropertyIsHidden, Any(bIsHidden));
}


// file name fields


const SvXMLEnumMapEntry<sal_uInt16> aFilenameDisplayMap[] =
{
    { XML_PATH,                 FilenameDisplayFormat::PATH },
    { XML_NAME,                 FilenameDisplayFormat::NAME },
    { XML_NAME_AND_EXTENSION,   FilenameDisplayFormat::NAME_AND_EXT },
    { XML_FULL,                 FilenameDisplayFormat::FULL },
    { XML_TOKEN_INVALID, 0 }
};

XMLFileNameImportContext::XMLFileNameImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp) :
        XMLTextFieldImportContext(rImport, rHlp, u"FileName"_ustr),
        sPropertyFixed(sAPI_is_fixed),
        sPropertyFileFormat(sAPI_file_format),
        sPropertyCurrentPresentation(
            sAPI_current_presentation),
        nFormat(FilenameDisplayFormat::FULL),
        bFixed(false)
{
    bValid = true;
}

void XMLFileNameImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
        case XML_ELEMENT(TEXT, XML_FIXED):
        {
            bool bTmp(false);
            if (::sax::Converter::convertBool(bTmp, sAttrValue))
            {
                bFixed = bTmp;
            }
            break;
        }
        case XML_ELEMENT(TEXT, XML_DISPLAY):
        {
            sal_uInt16 nTmp;
            if (SvXMLUnitConverter::convertEnum(nTmp, sAttrValue,
                                                aFilenameDisplayMap))
            {
                nFormat = nTmp;
            }
            break;
        }
        default:
            // unknown attribute: ignore
            XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
            break;
    }
}

void XMLFileNameImportContext::PrepareField(
    const Reference<XPropertySet> & xPropertySet)
{
    // properties are optional
    Reference<XPropertySetInfo> xPropertySetInfo(
        xPropertySet->getPropertySetInfo());

    if (xPropertySetInfo->hasPropertyByName(sPropertyFixed))
    {
         xPropertySet->setPropertyValue(sPropertyFixed, Any(bFixed));
    }

    if (xPropertySetInfo->hasPropertyByName(sPropertyFileFormat))
    {
        xPropertySet->setPropertyValue(sPropertyFileFormat, Any(nFormat));
    }

    if (xPropertySetInfo->hasPropertyByName(sPropertyCurrentPresentation))
    {
        xPropertySet->setPropertyValue(sPropertyCurrentPresentation, Any(GetContent()));
    }
}


// template name field


const SvXMLEnumMapEntry<sal_uInt16> aTemplateDisplayMap[] =
{
    { XML_FULL,                 TemplateDisplayFormat::FULL },
    { XML_PATH,                 TemplateDisplayFormat::PATH },
    { XML_NAME,                 TemplateDisplayFormat::NAME },
    { XML_NAME_AND_EXTENSION,   TemplateDisplayFormat::NAME_AND_EXT },
    { XML_AREA,                 TemplateDisplayFormat::AREA },
    { XML_TITLE,                TemplateDisplayFormat::TITLE },
    { XML_TOKEN_INVALID, 0 }
};


XMLTemplateNameImportContext::XMLTemplateNameImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp) :
        XMLTextFieldImportContext(rImport, rHlp, u"TemplateName"_ustr),
        sPropertyFileFormat(sAPI_file_format),
        nFormat(TemplateDisplayFormat::FULL)
{
    bValid = true;
}

void XMLTemplateNameImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
        case XML_ELEMENT(TEXT, XML_DISPLAY):
        {
            sal_uInt16 nTmp;
            if (SvXMLUnitConverter::convertEnum(nTmp, sAttrValue,
                                                aTemplateDisplayMap))
            {
                nFormat = nTmp;
            }
            break;
        }
        default:
            // unknown attribute: ignore
            XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
            break;
    }
}

void XMLTemplateNameImportContext::PrepareField(
    const Reference<XPropertySet> & xPropertySet)
{
    xPropertySet->setPropertyValue(sPropertyFileFormat, Any(nFormat));
}


// import chapter fields


const SvXMLEnumMapEntry<sal_uInt16> aChapterDisplayMap[] =
{
    { XML_NAME,                     ChapterFormat::NAME },
    { XML_NUMBER,                   ChapterFormat::NUMBER },
    { XML_NUMBER_AND_NAME,          ChapterFormat::NAME_NUMBER },
    { XML_PLAIN_NUMBER_AND_NAME,    ChapterFormat::NO_PREFIX_SUFFIX },
    { XML_PLAIN_NUMBER,             ChapterFormat::DIGIT },
    { XML_TOKEN_INVALID, 0 }
};

constexpr OUStringLiteral gsPropertyChapterFormat(u"ChapterFormat");
constexpr OUStringLiteral gsPropertyLevel(u"Level");

XMLChapterImportContext::XMLChapterImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp) :
        XMLTextFieldImportContext(rImport, rHlp, u"Chapter"_ustr),
        nFormat(ChapterFormat::NAME_NUMBER),
        nLevel(0)
{
    bValid = true;
}

void XMLChapterImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
        case XML_ELEMENT(TEXT, XML_DISPLAY):
        {
            sal_uInt16 nTmp;
            if (SvXMLUnitConverter::convertEnum(nTmp, sAttrValue,
                                                aChapterDisplayMap))
            {
                nFormat = static_cast<sal_Int16>(nTmp);
            }
            break;
        }
        case XML_ELEMENT(TEXT, XML_OUTLINE_LEVEL):
        {
            sal_Int32 nTmp;
            if (::sax::Converter::convertNumber(
                nTmp, sAttrValue, 1,
                GetImport().GetTextImport()->GetChapterNumbering()->getCount()
                ))
            {
                // API numbers 0..9, we number 1..10
                nLevel = static_cast<sal_Int8>(nTmp);
                nLevel--;
            }
            break;
        }
        default:
            // unknown attribute: ignore
            XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
            break;
    }
}

void XMLChapterImportContext::PrepareField(
        const Reference<XPropertySet> & xPropertySet)
{
    xPropertySet->setPropertyValue(gsPropertyChapterFormat, Any(nFormat));
    xPropertySet->setPropertyValue(gsPropertyLevel, Any(nLevel));
}


// counting fields


XMLCountFieldImportContext::XMLCountFieldImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp,
    sal_Int32 nElement) :
        XMLTextFieldImportContext(rImport, rHlp, MapTokenToServiceName(nElement)),
        sPropertyNumberingType(
            sAPI_numbering_type),
        bNumberFormatOK(false)
{
    bValid = true;
}

void XMLCountFieldImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
        case XML_ELEMENT(STYLE, XML_NUM_FORMAT):
            sNumberFormat = OUString::fromUtf8(sAttrValue);
            bNumberFormatOK = true;
            break;
        case XML_ELEMENT(STYLE, XML_NUM_LETTER_SYNC):
            sLetterSync = OUString::fromUtf8(sAttrValue);
            break;
        default:
            XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
    }
}

void XMLCountFieldImportContext::PrepareField(
    const Reference<XPropertySet> & xPropertySet)
{
    // properties optional
    // (only page count, but do for all to save common implementation)

    if (!xPropertySet->getPropertySetInfo()->
        hasPropertyByName(sPropertyNumberingType))
        return;

    sal_Int16 nNumType;
    if( bNumberFormatOK )
    {
        nNumType= style::NumberingType::ARABIC;
        GetImport().GetMM100UnitConverter().convertNumFormat( nNumType,
                                                sNumberFormat,
                                                sLetterSync );
    }
    else
        nNumType = style::NumberingType::PAGE_DESCRIPTOR;
    xPropertySet->setPropertyValue(sPropertyNumberingType, Any(nNumType));
}

OUString XMLCountFieldImportContext::MapTokenToServiceName(
    sal_Int32 nElement)
{
    OUString pServiceName;

    switch (nElement)
    {
        case XML_ELEMENT(TEXT, XML_WORD_COUNT):
            pServiceName = "WordCount";
            break;
        case XML_ELEMENT(TEXT, XML_PARAGRAPH_COUNT):
            pServiceName = "ParagraphCount";
            break;
        case XML_ELEMENT(TEXT, XML_TABLE_COUNT):
            pServiceName = "TableCount";
            break;
        case XML_ELEMENT(TEXT, XML_CHARACTER_COUNT):
            pServiceName = "CharacterCount";
            break;
        case XML_ELEMENT(TEXT, XML_IMAGE_COUNT):
            pServiceName = "GraphicObjectCount";
            break;
        case XML_ELEMENT(TEXT, XML_OBJECT_COUNT):
            pServiceName = "EmbeddedObjectCount";
            break;
        case XML_ELEMENT(TEXT, XML_PAGE_COUNT):
            pServiceName = "PageCount";
            break;
        case XML_ELEMENT(LO_EXT, XML_PAGE_COUNT_RANGE):
            pServiceName = "PageCountRange";
            break;
        default:
            XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
            assert(false);
    }

    return pServiceName;
}


// page variable import


XMLPageVarGetFieldImportContext::XMLPageVarGetFieldImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp) :
        XMLTextFieldImportContext(rImport, rHlp, u"ReferencePageGet"_ustr),
        bNumberFormatOK(false)
{
    bValid = true;
}

void XMLPageVarGetFieldImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
        case XML_ELEMENT(STYLE, XML_NUM_FORMAT):
            sNumberFormat = OUString::fromUtf8(sAttrValue);
            bNumberFormatOK = true;
            break;
        case XML_ELEMENT(STYLE, XML_NUM_LETTER_SYNC):
            sLetterSync = OUString::fromUtf8(sAttrValue);
            break;
        default:
            XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
    }
}

void XMLPageVarGetFieldImportContext::PrepareField(
    const Reference<XPropertySet> & xPropertySet)
{
    sal_Int16 nNumType;
    if( bNumberFormatOK )
    {
        nNumType= style::NumberingType::ARABIC;
        GetImport().GetMM100UnitConverter().convertNumFormat( nNumType,
                                                    sNumberFormat,
                                                    sLetterSync );
    }
    else
        nNumType = style::NumberingType::PAGE_DESCRIPTOR;
    xPropertySet->setPropertyValue(sAPI_numbering_type, Any(nNumType));

    // display old content (#96657#)
    xPropertySet->setPropertyValue( sAPI_current_presentation, Any(GetContent()) );
}


// page variable set fields


XMLPageVarSetFieldImportContext::XMLPageVarSetFieldImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp) :
        XMLTextFieldImportContext(rImport, rHlp, u"ReferencePageSet"_ustr),
        nAdjust(0),
        bActive(true)
{
    bValid = true;
}

void XMLPageVarSetFieldImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
    case XML_ELEMENT(TEXT, XML_ACTIVE):
    {
        bool bTmp(false);
        if (::sax::Converter::convertBool(bTmp, sAttrValue))
        {
            bActive = bTmp;
        }
        break;
    }
    case XML_ELEMENT(TEXT, XML_PAGE_ADJUST):
    {
        sal_Int32 nTmp(0);
        if (::sax::Converter::convertNumber(nTmp, sAttrValue))
        {
            nAdjust = static_cast<sal_Int16>(nTmp);
        }
        break;
    }
    default:
        XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
        break;
    }
}

void XMLPageVarSetFieldImportContext::PrepareField(
    const Reference<XPropertySet> & xPropertySet)
{
    xPropertySet->setPropertyValue(u"On"_ustr, Any(bActive));
    xPropertySet->setPropertyValue(sAPI_offset, Any(nAdjust));
}


// macro fields


XMLMacroFieldImportContext::XMLMacroFieldImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp) :
        XMLTextFieldImportContext(rImport, rHlp, u"Macro"_ustr),
        bDescriptionOK(false)
{
}

css::uno::Reference< css::xml::sax::XFastContextHandler > XMLMacroFieldImportContext::createFastChildContext(
    sal_Int32 nElement,
    const css::uno::Reference< css::xml::sax::XFastAttributeList >&  )
{
    if ( nElement == XML_ELEMENT(OFFICE, XML_EVENT_LISTENERS) )
    {
        // create events context and remember it!
        xEventContext = new XMLEventsImportContext( GetImport() );
        bValid = true;
        return xEventContext;
    }
    XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);

    return nullptr;
}

void XMLMacroFieldImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
        case XML_ELEMENT(TEXT, XML_DESCRIPTION):
            sDescription = OUString::fromUtf8(sAttrValue);
            bDescriptionOK = true;
            break;
        case XML_ELEMENT(TEXT, XML_NAME):
            sMacro = OUString::fromUtf8(sAttrValue);
            bValid = true;
            break;
        default:
            XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
    }
}

void XMLMacroFieldImportContext::PrepareField(
    const Reference<XPropertySet> & xPropertySet)
{
    Any aAny;
    aAny <<= (bDescriptionOK ? sDescription : GetContent());
    xPropertySet->setPropertyValue(sAPI_hint, aAny);

    // if we have an events child element, we'll look for the OnClick
    // event if not, it may be an old (pre-638i) document. Then, we'll
    // have to look at the name attribute.
    OUString sMacroName;
    OUString sLibraryName;
    OUString sScriptURL;

    if ( xEventContext.is() )
    {
        // get event sequence
        XMLEventsImportContext* pEvents = xEventContext.get();
        Sequence<PropertyValue> aValues;
        pEvents->GetEventSequence( u"OnClick"_ustr, aValues );

        for (const auto& rValue : aValues)
        {
            if ( rValue.Name == "ScriptType" )
            {
                // ignore ScriptType
            }
            else if ( rValue.Name == "Library" )
            {
                rValue.Value >>= sLibraryName;
            }
            else if ( rValue.Name == "MacroName" )
            {
                rValue.Value >>= sMacroName;
            }
            if ( rValue.Name == "Script" )
            {
                rValue.Value >>= sScriptURL;
            }
        }
    }
    else
    {
        // disassemble old-style macro-name: Everything before the
        // third-last dot is the library
        sal_Int32 nPos = sMacro.getLength() + 1;    // the loop starts with nPos--
        const sal_Unicode* pBuf = sMacro.getStr();
        for( sal_Int32 i = 0; (i < 3) && (nPos > 0); i++ )
        {
            nPos--;
            while ( (pBuf[nPos] != '.') && (nPos > 0) )
                nPos--;
        }

        if (nPos > 0)
        {
            sLibraryName = sMacro.copy(0, nPos);
            sMacroName = sMacro.copy(nPos+1);
        }
        else
            sMacroName = sMacro;
    }

    xPropertySet->setPropertyValue(u"ScriptURL"_ustr, Any(sScriptURL));
    xPropertySet->setPropertyValue(u"MacroName"_ustr, Any(sMacroName));
    xPropertySet->setPropertyValue(u"MacroLibrary"_ustr, Any(sLibraryName));
}


// reference field import


XMLReferenceFieldImportContext::XMLReferenceFieldImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp,
    sal_Int32 nToken)
:   XMLTextFieldImportContext(rImport, rHlp, u"GetReference"_ustr)
,   nElementToken(nToken)
,   nSource(0)
,   nType(ReferenceFieldPart::PAGE_DESC)
,   nFlags(0)
,   bNameOK(false)
,   bTypeOK(false)
{
}

SvXMLEnumMapEntry<sal_uInt16> const lcl_aReferenceTypeTokenMap[] =
{
    { XML_PAGE,         ReferenceFieldPart::PAGE},
    { XML_CHAPTER,      ReferenceFieldPart::CHAPTER },
    { XML_TEXT,         ReferenceFieldPart::TEXT },
    { XML_DIRECTION,    ReferenceFieldPart::UP_DOWN },
    { XML_CATEGORY_AND_VALUE, ReferenceFieldPart::CATEGORY_AND_NUMBER },
    { XML_CAPTION,      ReferenceFieldPart::ONLY_CAPTION },
    { XML_VALUE,        ReferenceFieldPart::ONLY_SEQUENCE_NUMBER },
    // Core implementation for direct cross-references (#i81002#)
    { XML_NUMBER,               ReferenceFieldPart::NUMBER },
    { XML_NUMBER_NO_SUPERIOR,   ReferenceFieldPart::NUMBER_NO_CONTEXT },
    { XML_NUMBER_ALL_SUPERIOR,  ReferenceFieldPart::NUMBER_FULL_CONTEXT },
    { XML_TOKEN_INVALID, 0 }
};

void XMLReferenceFieldImportContext::startFastElement(
        sal_Int32 nElement,
        const Reference<XFastAttributeList> & xAttrList)
{
    bTypeOK = true;
    switch (nElementToken)
    {
        case XML_ELEMENT(TEXT, XML_REFERENCE_REF):
            nSource = ReferenceFieldSource::REFERENCE_MARK;
            break;
        case  XML_ELEMENT(TEXT, XML_BOOKMARK_REF):
            nSource = ReferenceFieldSource::BOOKMARK;
            break;
        case XML_ELEMENT(TEXT, XML_NOTE_REF):
            nSource = ReferenceFieldSource::FOOTNOTE;
            break;
        case XML_ELEMENT(TEXT, XML_SEQUENCE_REF):
            nSource = ReferenceFieldSource::SEQUENCE_FIELD;
            break;
        case XML_ELEMENT(TEXT, XML_STYLE_REF):
        case XML_ELEMENT(LO_EXT, XML_STYLE_REF):
            nSource = ReferenceFieldSource::STYLE;
            break;
        default:
            XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElementToken);
            bTypeOK = false;
            break;
    }

    XMLTextFieldImportContext::startFastElement(nElement, xAttrList);
}


void XMLReferenceFieldImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
        case XML_ELEMENT(TEXT, XML_NOTE_CLASS):
            if( IsXMLToken( sAttrValue, XML_ENDNOTE ) )
                nSource = ReferenceFieldSource::ENDNOTE;
            break;
        case XML_ELEMENT(TEXT, XML_REF_NAME):
            sName = OUString::fromUtf8(sAttrValue);
            bNameOK = true;
            break;
        case  XML_ELEMENT(TEXT, XML_REFERENCE_FORMAT):
        {
            sal_uInt16 nToken;
            if (SvXMLUnitConverter::convertEnum(nToken, sAttrValue,
                                                lcl_aReferenceTypeTokenMap))
            {
                nType = nToken;
            }

            // check for sequence-only-attributes
            if ( (XML_ELEMENT(TEXT, XML_SEQUENCE_REF) != nElementToken) &&
                 ( (nType == ReferenceFieldPart::CATEGORY_AND_NUMBER) ||
                   (nType == ReferenceFieldPart::ONLY_CAPTION) ||
                   (nType == ReferenceFieldPart::ONLY_SEQUENCE_NUMBER) ) )
            {
                nType = ReferenceFieldPart::PAGE_DESC;
            }

            break;
        }
        case XML_ELEMENT(LO_EXT, XML_REFERENCE_LANGUAGE):
        case XML_ELEMENT(TEXT, XML_REFERENCE_LANGUAGE):
            sLanguage = OUString::fromUtf8(sAttrValue);
            break;
        case XML_ELEMENT(LO_EXT, XML_REFERENCE_HIDE_NON_NUMERICAL):
        case XML_ELEMENT(TEXT, XML_REFERENCE_HIDE_NON_NUMERICAL):
            if (OUString::fromUtf8(sAttrValue).toBoolean())
                nFlags |= REFFLDFLAG_STYLE_HIDE_NON_NUMERICAL;
            break;
        case XML_ELEMENT(LO_EXT, XML_REFERENCE_FROM_BOTTOM):
        case XML_ELEMENT(TEXT, XML_REFERENCE_FROM_BOTTOM):
            if (OUString::fromUtf8(sAttrValue).toBoolean())
                nFlags |= REFFLDFLAG_STYLE_FROM_BOTTOM;
            break;
        default:
            XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
    }

    // bValid: we need proper element type and name
    bValid = bTypeOK && bNameOK;
}

void XMLReferenceFieldImportContext::PrepareField(
    const Reference<XPropertySet> & xPropertySet)
{
    xPropertySet->setPropertyValue(u"ReferenceFieldPart"_ustr, Any(nType));

    xPropertySet->setPropertyValue(u"ReferenceFieldSource"_ustr, Any(nSource));

    xPropertySet->setPropertyValue(u"ReferenceFieldLanguage"_ustr, Any(sLanguage));
    switch (nElementToken)
    {
        case XML_ELEMENT(TEXT, XML_REFERENCE_REF):
        case XML_ELEMENT(TEXT, XML_BOOKMARK_REF):
        case XML_ELEMENT(TEXT, XML_STYLE_REF):
        case XML_ELEMENT(LO_EXT, XML_STYLE_REF):
            xPropertySet->setPropertyValue(u"SourceName"_ustr, Any(sName));
            xPropertySet->setPropertyValue(u"ReferenceFieldFlags"_ustr, Any(nFlags));
            break;

        case XML_ELEMENT(TEXT, XML_NOTE_REF):
            GetImportHelper().ProcessFootnoteReference(sName, xPropertySet);
            break;

        case XML_ELEMENT(TEXT, XML_SEQUENCE_REF):
            GetImportHelper().ProcessSequenceReference(sName, xPropertySet);
            break;
    }

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


// field declarations container

XMLDdeFieldDeclsImportContext::XMLDdeFieldDeclsImportContext(SvXMLImport& rImport) :
        SvXMLImportContext(rImport)
{
}

css::uno::Reference< css::xml::sax::XFastContextHandler > XMLDdeFieldDeclsImportContext::createFastChildContext(
    sal_Int32 nElement,
    const css::uno::Reference< css::xml::sax::XFastAttributeList >&  )
{
    if ( nElement == XML_ELEMENT(TEXT, XML_DDE_CONNECTION_DECL) )
    {
        return new XMLDdeFieldDeclImportContext(GetImport());
    }
    else
        XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
    return nullptr;
}


// import dde field declaration


XMLDdeFieldDeclImportContext::XMLDdeFieldDeclImportContext(SvXMLImport& rImport)
:   SvXMLImportContext(rImport)
{
}

void XMLDdeFieldDeclImportContext::startFastElement(
        sal_Int32 /*nElement*/,
        const Reference<XFastAttributeList> & xAttrList)
{
    OUString sName;
    OUString sCommandApplication;
    OUString sCommandTopic;
    OUString sCommandItem;

    bool bUpdate = false;
    bool bNameOK = false;
    bool bCommandApplicationOK = false;
    bool bCommandTopicOK = false;
    bool bCommandItemOK = false;

    // process attributes
    forauto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ) )
    {
        switch (aIter.getToken())
        {
            case XML_ELEMENT(OFFICE, XML_NAME):
                sName = aIter.toString();
                bNameOK = true;
                break;
            case XML_ELEMENT(OFFICE, XML_DDE_APPLICATION):
                sCommandApplication = aIter.toString();
                bCommandApplicationOK = true;
                break;
            case XML_ELEMENT(OFFICE, XML_DDE_TOPIC):
                sCommandTopic = aIter.toString();
                bCommandTopicOK = true;
                break;
            case XML_ELEMENT(OFFICE, XML_DDE_ITEM):
                sCommandItem = aIter.toString();
                bCommandItemOK = true;
                break;
            case XML_ELEMENT(OFFICE, XML_AUTOMATIC_UPDATE):
            {
                bool bTmp(false);
                if (::sax::Converter::convertBool(bTmp, aIter.toView()) )
                {
                    bUpdate = bTmp;
                }
                break;
            }
            default:
                XMLOFF_WARN_UNKNOWN("xmloff", aIter);
        }
    }

    // valid data?
    if (!(bNameOK && bCommandApplicationOK && bCommandTopicOK && bCommandItemOK))
        return;

    // create DDE TextFieldMaster
    Reference<XMultiServiceFactory> xFactory(GetImport().GetModel(),
                                             UNO_QUERY);
    if( !xFactory.is() )
        return;

    /* #i6432# There might be multiple occurrences of one DDE
       declaration if it is used in more than one of
       header/footer/body. createInstance will throw an exception if we
       try to create the second, third, etc. instance of such a
       declaration. Thus we ignore the exception. Otherwise this will
       lead to an unloadable document. */

    try
    {
        Reference<XInterface> xIfc =
            xFactory->createInstance(OUString::Concat(sAPI_fieldmaster_prefix) + sAPI_dde);
        if( xIfc.is() )
        {
            Reference<XPropertySet> xPropSet( xIfc, UNO_QUERY );
            if (xPropSet.is() &&
                xPropSet->getPropertySetInfo()->hasPropertyByName(
                                                                  u"DDECommandType"_ustr))
            {
                xPropSet->setPropertyValue(sAPI_name, Any(sName));

                xPropSet->setPropertyValue(u"DDECommandType"_ustr, Any(sCommandApplication));

                xPropSet->setPropertyValue(u"DDECommandFile"_ustr, Any(sCommandTopic));

                xPropSet->setPropertyValue(u"DDECommandElement"_ustr,
                                           Any(sCommandItem));

                xPropSet->setPropertyValue(u"IsAutomaticUpdate"_ustr,
                                           Any(bUpdate));
            }
            // else: ignore (can't get XPropertySet, or DDE
            //               properties are not supported)
        }
        // else: ignore
    }
    catch (const Exception&)
    {
        //ignore
    }
    // else: ignore
    // else: ignore
}


// DDE field import


XMLDdeFieldImportContext::XMLDdeFieldImportContext(
    SvXMLImport& rImport, XMLTextImportHelper& rHlp) :
        XMLTextFieldImportContext(rImport, rHlp, sAPI_dde),
        sPropertyContent(sAPI_content)
{
}

void XMLDdeFieldImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    if ( XML_ELEMENT(TEXT, XML_CONNECTION_NAME) == nAttrToken)
    {
        sName = OUString::fromUtf8(sAttrValue);
        bValid = true;
    }
    else
        XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
}


void XMLDdeFieldImportContext::endFastElement(sal_Int32 )
{
    if (!bValid)
        return;

    // find master
    OUString sMasterName = OUString::Concat(sAPI_fieldmaster_prefix) + sAPI_dde + "." + sName;

    Reference<XTextFieldsSupplier> xTextFieldsSupp(GetImport().GetModel(),
                                                   UNO_QUERY);
    Reference<container::XNameAccess> xFieldMasterNameAccess =
        xTextFieldsSupp->getTextFieldMasters();

    if (!xFieldMasterNameAccess->hasByName(sMasterName))
        return;

    Reference<XPropertySet> xMaster;
    Any aAny = xFieldMasterNameAccess->getByName(sMasterName);
    aAny >>= xMaster;
    //apply the content to the master
    xMaster->setPropertyValue( sPropertyContent, uno::Any( GetContent()));
    // master exists: create text field and attach
    Reference<XPropertySet> xField;
    OUString sFieldName = OUString::Concat(sAPI_textfield_prefix) + sAPI_dde;
    if (!CreateField(xField, sFieldName))
        return;

    Reference<XDependentTextField> xDepTextField(xField,UNO_QUERY);
    xDepTextField->attachTextFieldMaster(xMaster);

    // attach field to document
    Reference<XTextContent> xTextContent(xField, UNO_QUERY);
    if (xTextContent.is())
    {
        GetImportHelper().InsertTextContent(xTextContent);

        // we're lucky. nothing else to prepare.
    }
    // else: fail, because text content could not be created
    // else: fail, because field could not be created
    // else: fail, because no master was found (faulty document?!)
    // not valid: ignore
}

void XMLDdeFieldImportContext::PrepareField(
    const Reference<XPropertySet> &)
{
    // empty, since not needed.
}


// sheet name fields


XMLSheetNameImportContext::XMLSheetNameImportContext(
    SvXMLImport& rImport,
    XMLTextImportHelper& rHlp) :
        XMLTextFieldImportContext(rImport, rHlp, u"SheetName"_ustr)
{
    bValid = true;  // always valid!
}

void XMLSheetNameImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue)
{
    // no attributes -> nothing to be done
    XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
}

void XMLSheetNameImportContext::PrepareField(
    const Reference<XPropertySet> &)
{
    // no attributes -> nothing to be done
}

/** import page|slide name fields (<text:page-name>) */

XMLPageNameFieldImportContext::XMLPageNameFieldImportContext(
        SvXMLImport& rImport,                   /// XML Import
        XMLTextImportHelper& rHlp)              /// Text import helper
: XMLTextFieldImportContext(rImport, rHlp, u"PageName"_ustr )
{
    bValid = true;
}

/// process attribute values
void XMLPageNameFieldImportContext::ProcessAttribute( sal_Int32 nAttrToken,
                                   std::string_view sAttrValue )
{
    XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
}

/// prepare XTextField for insertion into document
void XMLPageNameFieldImportContext::PrepareField(
        const css::uno::Reference<css::beans::XPropertySet> &)
{
}


// URL fields (Calc, Impress, Draw)


XMLUrlFieldImportContext::XMLUrlFieldImportContext(
    SvXMLImport& rImport,
    XMLTextImportHelper& rHlp) :
        XMLTextFieldImportContext(rImport, rHlp, sAPI_url),
        bFrameOK(false)
{
}

void XMLUrlFieldImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
        case XML_ELEMENT(XLINK, XML_HREF):
            sURL = GetImport().GetAbsoluteReference( OUString::fromUtf8(sAttrValue) );
            bValid = true;
            break;
        case XML_ELEMENT(OFFICE, XML_TARGET_FRAME_NAME):
            sFrame = OUString::fromUtf8(sAttrValue);
            bFrameOK = true;
            break;
        default:
            // ignore
            XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
            break;
    }
}

void XMLUrlFieldImportContext::PrepareField(
    const Reference<XPropertySet> & xPropertySet)
{
    xPropertySet->setPropertyValue(sAPI_url, Any(sURL));

    if (bFrameOK)
    {
        xPropertySet->setPropertyValue(u"TargetFrame"_ustr, Any(sFrame));
    }

    xPropertySet->setPropertyValue(u"Representation"_ustr, Any(GetContent()));
}


XMLBibliographyFieldImportContext::XMLBibliographyFieldImportContext(
    SvXMLImport& rImport,
    XMLTextImportHelper& rHlp) :
        XMLTextFieldImportContext(rImport, rHlp, u"Bibliography"_ustr)
{
    bValid = true;
}

// TODO: this is the same map as is used in the text field export
SvXMLEnumMapEntry<sal_uInt16> const aBibliographyDataTypeMap[] =
{
    { XML_ARTICLE,          BibliographyDataType::ARTICLE },
    { XML_BOOK,             BibliographyDataType::BOOK },
    { XML_BOOKLET,          BibliographyDataType::BOOKLET },
    { XML_CONFERENCE,       BibliographyDataType::CONFERENCE },
    { XML_CUSTOM1,          BibliographyDataType::CUSTOM1 },
    { XML_CUSTOM2,          BibliographyDataType::CUSTOM2 },
    { XML_CUSTOM3,          BibliographyDataType::CUSTOM3 },
    { XML_CUSTOM4,          BibliographyDataType::CUSTOM4 },
    { XML_CUSTOM5,          BibliographyDataType::CUSTOM5 },
    { XML_EMAIL,            BibliographyDataType::EMAIL },
    { XML_INBOOK,           BibliographyDataType::INBOOK },
    { XML_INCOLLECTION,     BibliographyDataType::INCOLLECTION },
    { XML_INPROCEEDINGS,    BibliographyDataType::INPROCEEDINGS },
    { XML_JOURNAL,          BibliographyDataType::JOURNAL },
    { XML_MANUAL,           BibliographyDataType::MANUAL },
    { XML_MASTERSTHESIS,    BibliographyDataType::MASTERSTHESIS },
    { XML_MISC,             BibliographyDataType::MISC },
    { XML_PHDTHESIS,        BibliographyDataType::PHDTHESIS },
    { XML_PROCEEDINGS,      BibliographyDataType::PROCEEDINGS },
    { XML_TECHREPORT,       BibliographyDataType::TECHREPORT },
    { XML_UNPUBLISHED,      BibliographyDataType::UNPUBLISHED },
    { XML_WWW,              BibliographyDataType::WWW },
    { XML_TOKEN_INVALID, 0 }
};


// we'll process attributes on our own and for fit the standard
// textfield mechanism, because our attributes have zero overlap with
// all the other textfields.
void XMLBibliographyFieldImportContext::startFastElement(
        sal_Int32 /*nElement*/,
        const Reference<XFastAttributeList> & xAttrList)
{
    // iterate over attributes
    forauto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ) )
    {
        if (IsTokenInNamespace(aIter.getToken(), XML_NAMESPACE_TEXT)
            || IsTokenInNamespace(aIter.getToken(), XML_NAMESPACE_LO_EXT))
        {
            auto nToken = aIter.getToken() & TOKEN_MASK;
            PropertyValue aValue;
            aValue.Name = MapBibliographyFieldName(nToken);

            // special treatment for bibliography type
            // biblio vs bibilio: #96658#; also read old documents
            if (nToken == XML_BIBILIOGRAPHIC_TYPE ||
                nToken == XML_BIBLIOGRAPHY_TYPE    )
            {
                sal_uInt16 nTmp;
                if (SvXMLUnitConverter::convertEnum(
                    nTmp, aIter.toView(),
                    aBibliographyDataTypeMap))
                {
                    aValue.Value <<= static_cast<sal_Int16>(nTmp);

                    aValues.push_back(aValue);
                }
            }
            else
            {
                OUString aStringValue = aIter.toString();
                if (nToken == XML_URL || nToken == XML_LOCAL_URL || nToken == XML_TARGET_URL)
                {
                    aStringValue = GetImport().GetAbsoluteReference(aStringValue);
                }
                aValue.Value <<= aStringValue;

                aValues.push_back(aValue);
            }
        }
        // else: unknown namespace -> ignore
    }
}

void XMLBibliographyFieldImportContext::ProcessAttribute(
    sal_Int32 ,
    std::string_view )
{
    // attributes are handled in StartElement
    assert(false && "This should not have happened.");
}


void XMLBibliographyFieldImportContext::PrepareField(
    const Reference<XPropertySet> & xPropertySet)
{
    // convert vector into sequence
    sal_Int32 nCount = aValues.size();
    Sequence<PropertyValue> aValueSequence(nCount);
    auto aValueSequenceRange = asNonConstRange(aValueSequence);
    for(sal_Int32 i = 0; i < nCount; i++)
    {
        aValueSequenceRange[i] = aValues[i];
    }

    // set sequence
    xPropertySet->setPropertyValue(u"Fields"_ustr, Any(aValueSequence));
}

OUString XMLBibliographyFieldImportContext::MapBibliographyFieldName(
    sal_Int32 nElement)
{
    OUString pName;

    switch (nElement & TOKEN_MASK)
    {
        case XML_IDENTIFIER:
            pName = u"Identifier"_ustr;
            break;
        case XML_BIBILIOGRAPHIC_TYPE:
        case XML_BIBLIOGRAPHY_TYPE:
            // biblio... vs bibilio...: #96658#: also read old documents
            pName = u"BibiliographicType"_ustr;
            break;
        case XML_ADDRESS:
            pName = u"Address"_ustr;
            break;
        case XML_ANNOTE:
            pName = u"Annote"_ustr;
            break;
        case XML_AUTHOR:
            pName = u"Author"_ustr;
            break;
        case XML_BOOKTITLE:
            pName = u"Booktitle"_ustr;
            break;
        case XML_CHAPTER:
            pName = u"Chapter"_ustr;
            break;
        case XML_EDITION:
            pName = u"Edition"_ustr;
            break;
        case XML_EDITOR:
            pName = u"Editor"_ustr;
            break;
        case XML_HOWPUBLISHED:
            pName = u"Howpublished"_ustr;
            break;
        case XML_INSTITUTION:
            pName = u"Institution"_ustr;
            break;
        case XML_JOURNAL:
            pName = u"Journal"_ustr;
            break;
        case XML_MONTH:
            pName = u"Month"_ustr;
            break;
        case XML_NOTE:
            pName = u"Note"_ustr;
            break;
        case XML_NUMBER:
            pName = u"Number"_ustr;
            break;
        case XML_ORGANIZATIONS:
            pName = u"Organizations"_ustr;
            break;
        case XML_PAGES:
            pName = u"Pages"_ustr;
            break;
        case XML_PUBLISHER:
            pName = u"Publisher"_ustr;
            break;
        case XML_SCHOOL:
            pName = u"School"_ustr;
            break;
        case XML_SERIES:
            pName = u"Series"_ustr;
            break;
        case XML_TITLE:
            pName = u"Title"_ustr;
            break;
        case XML_REPORT_TYPE:
            pName = u"Report_Type"_ustr;
            break;
        case XML_VOLUME:
            pName = u"Volume"_ustr;
            break;
        case XML_YEAR:
            pName = u"Year"_ustr;
            break;
        case XML_URL:
            pName = u"URL"_ustr;
            break;
        case XML_CUSTOM1:
            pName = u"Custom1"_ustr;
            break;
        case XML_CUSTOM2:
            pName = u"Custom2"_ustr;
            break;
        case XML_CUSTOM3:
            pName = u"Custom3"_ustr;
            break;
        case XML_CUSTOM4:
            pName = u"Custom4"_ustr;
            break;
        case XML_CUSTOM5:
            pName = u"Custom5"_ustr;
            break;
        case XML_ISBN:
            pName = u"ISBN"_ustr;
            break;
        case XML_LOCAL_URL:
            pName = u"LocalURL"_ustr;
            break;
        case XML_TARGET_TYPE:
            pName = u"TargetType"_ustr;
            break;
        case XML_TARGET_URL:
            pName = u"TargetURL"_ustr;
            break;
        default:
            assert(false && "Unknown bibliography info data");
    }
    return pName;
}

// Annotation Field


XMLAnnotationImportContext::XMLAnnotationImportContext(
    SvXMLImport& rImport,
    XMLTextImportHelper& rHlp,
    sal_Int32 nElement) :
        XMLTextFieldImportContext(rImport, rHlp, u"Annotation"_ustr),
        mnElement(nElement)
{
    bValid = true;

    // remember old list item and block (#91964#) and reset them
    // for the text frame
    // do this in the constructor, not in CreateChildContext (#i93392#)
    GetImport().GetTextImport()->PushListContext();
}

void XMLAnnotationImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    if (nAttrToken == XML_ELEMENT(OFFICE, XML_NAME))
        aName = OUString::fromUtf8(sAttrValue);
    else if (nAttrToken == XML_ELEMENT(LO_EXT, XML_RESOLVED))
        aResolved = OUString::fromUtf8(sAttrValue);
    else if (nAttrToken == XML_ELEMENT(LO_EXT, XML_PARENT_NAME))
        aParentName = OUString::fromUtf8(sAttrValue);
    else
        XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
}

css::uno::Reference< css::xml::sax::XFastContextHandler > XMLAnnotationImportContext::createFastChildContext(
    sal_Int32 nElement,
    const uno::Reference< xml::sax::XFastAttributeList>& xAttrList )
{
    if( nElement == XML_ELEMENT(DC, XML_CREATOR) )
        return new XMLStringBufferImportContext(GetImport(), aAuthorBuffer);
    else if( nElement == XML_ELEMENT(DC, XML_DATE) )
        return new XMLStringBufferImportContext(GetImport(), aDateBuffer);
    else if (nElement == XML_ELEMENT(TEXT,XML_SENDER_INITIALS) ||
             nElement == XML_ELEMENT(LO_EXT, XML_SENDER_INITIALS) ||
             nElement == XML_ELEMENT(META, XML_CREATOR_INITIALS))
        return new XMLStringBufferImportContext(GetImport(), aInitialsBuffer);

    try
    {
        bool bOK = true;
        if ( !mxField.is() )
            bOK = CreateField( mxField, sServicePrefix + GetServiceName() );
        if (bOK)
        {
            Any aAny = mxField->getPropertyValue( u"TextRange"_ustr );
            Reference< XText > xText;
            aAny >>= xText;
            if( xText.is() )
            {
                rtl::Reference < XMLTextImportHelper > xTxtImport = GetImport().GetTextImport();
                if( !mxCursor.is() )
                {
                    mxOldCursor = xTxtImport->GetCursor();
                    mxCursor = xText->createTextCursor();
                }

                if( mxCursor.is() )
                {
                    xTxtImport->SetCursor( mxCursor );
                    return xTxtImport->CreateTextChildContext( GetImport(), nElement, xAttrList );
                }
            }
        }
    }
    catch (const Exception&)
    {
    }

    return new XMLStringBufferImportContext(GetImport(), aTextBuffer);
}

void XMLAnnotationImportContext::endFastElement(sal_Int32 /*nElement*/)
{
    DBG_ASSERT(!GetServiceName().isEmpty(), "no service name for element!");
    if( mxCursor.is() )
    {
        // delete addition newline
        mxCursor->gotoEnd( false );
        mxCursor->goLeft( 1, true );
        mxCursor->setString( u""_ustr );

        // reset cursor
        GetImport().GetTextImport()->ResetCursor();
    }

    if( mxOldCursor.is() )
        GetImport().GetTextImport()->SetCursor( mxOldCursor );

    // reinstall old list item #91964#
    GetImport().GetTextImport()->PopListContext();

    if (!bValid)
    {
        GetImportHelper().InsertString(GetContent());
        return;
    }

    if ( mnElement == XML_ELEMENT(OFFICE, XML_ANNOTATION_END) )
    {
        // Search for a previous annotation with the same name.
        uno::Reference< text::XTextContent > xPrevField;
        {
            Reference<XTextFieldsSupplier> xTextFieldsSupplier(GetImport().GetModel(), UNO_QUERY);
            if (!xTextFieldsSupplier)
                return;
            uno::Reference<container::XUniqueIDAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields(), UNO_QUERY_THROW);
            uno::Any aAny = xFieldsAccess->getByUniqueID(aName);
            aAny >>= xPrevField;
        }
        if ( xPrevField.is() )
        {
            // So we are ending a previous annotation,
            // let's create a text range covering the old and the current position.
            uno::Reference<text::XText> xText = GetImportHelper().GetText();
            uno::Reference<text::XTextCursor> xCursor =
                xText->createTextCursorByRange(GetImportHelper().GetCursorAsRange());
            try
            {
                xCursor->gotoRange(xPrevField->getAnchor(), true);
            }
            catch (const uno::RuntimeException&)
            {
                // Losing the start of the anchor is better than not opening the document at
                // all.
                TOOLS_WARN_EXCEPTION(
                    "xmloff.text",
                    "XMLAnnotationImportContext::endFastElement: gotoRange() failed: ");
            }

            xText->insertTextContent(xCursor, xPrevField, !xCursor->isCollapsed());
        }
        return;
    }

    if ( mxField.is() || CreateField( mxField, sServicePrefix + GetServiceName() ) )
    {
        // set field properties
        PrepareField( mxField );

        // attach field to document
        Reference < XTextContent > xTextContent( mxField, UNO_QUERY );

        // workaround for #80606#
        try
        {
            GetImportHelper().InsertTextContent( xTextContent );
        }
        catch (const lang::IllegalArgumentException&)
        {
            // ignore
        }
    }
}

void XMLAnnotationImportContext::PrepareField(
    const Reference<XPropertySet> & xPropertySet )
{
    // import (possibly empty) author
    OUString sAuthor( aAuthorBuffer.makeStringAndClear() );
    xPropertySet->setPropertyValue(sAPI_author, Any(sAuthor));

    // import (possibly empty) initials
    OUString sInitials( aInitialsBuffer.makeStringAndClear() );
    xPropertySet->setPropertyValue(u"Initials"_ustr, Any(sInitials));

    //import resolved flag
    bool bTmp(false);
    (void)::sax::Converter::convertBool(bTmp, aResolved);
    xPropertySet->setPropertyValue(u"Resolved"_ustr, Any(bTmp));

    util::DateTime aDateTime;
    if (::sax::Converter::parseDateTime(aDateTime, aDateBuffer))
    {
        /*
        Date aDate;
        aDate.Year = aDateTime.Year;
        aDate.Month = aDateTime.Month;
        aDate.Day = aDateTime.Day;
        xPropertySet->setPropertyValue(sPropertyDate, makeAny(aDate));
        */

        // why is there no UNO_NAME_DATE_TIME, but only UNO_NAME_DATE_TIME_VALUE?
        xPropertySet->setPropertyValue(sAPI_date_time_value, Any(aDateTime));
    }
    aDateBuffer.setLength(0);

    if ( aTextBuffer.getLength() )
    {
        // delete last paragraph mark (if necessary)
        if (char(0x0a) == aTextBuffer[aTextBuffer.getLength()-1])
            aTextBuffer.setLength(aTextBuffer.getLength()-1);
        xPropertySet->setPropertyValue(sAPI_content, Any(aTextBuffer.makeStringAndClear()));
    }

    if (!aName.isEmpty())
        xPropertySet->setPropertyValue(sAPI_name, Any(aName));

    if (!aParentName.isEmpty())
        xPropertySet->setPropertyValue(sAPI_parent_name, Any(aParentName));
}


// script field


XMLScriptImportContext::XMLScriptImportContext(
    SvXMLImport& rImport,
    XMLTextImportHelper& rHlp)
:   XMLTextFieldImportContext(rImport, rHlp, u"Script"_ustr)
,   bContentOK(false)
{
}

void XMLScriptImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
        case XML_ELEMENT(XLINK, XML_HREF):
            sContent = GetImport().GetAbsoluteReference( OUString::fromUtf8(sAttrValue) );
            bContentOK = true;
            break;

        case XML_ELEMENT(SCRIPT, XML_LANGUAGE):
            sScriptType = OUString::fromUtf8(sAttrValue);
            break;

        default:
            // ignore
            XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
            break;
    }

    // always valid (even without ScriptType; cf- #96531#)
    bValid = true;
}

void XMLScriptImportContext::PrepareField(
    const Reference<XPropertySet> & xPropertySet)
{
    // if href attribute was present, we use it. Else we use element content
    if (! bContentOK)
    {
        sContent = GetContent();
    }
    xPropertySet->setPropertyValue(sAPI_content, Any(sContent));

    // URL or script text? We use URL if we have an href-attribute
    xPropertySet->setPropertyValue(u"URLContent"_ustr, Any(bContentOK));

    xPropertySet->setPropertyValue(u"ScriptType"_ustr, Any(sScriptType));
}


// measure field


XMLMeasureFieldImportContext::XMLMeasureFieldImportContext(
    SvXMLImport& rImport,
    XMLTextImportHelper& rHlp) :
        XMLTextFieldImportContext(rImport, rHlp, u"Measure"_ustr),
        mnKind( 0 )
{
}

void XMLMeasureFieldImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    switch (nAttrToken)
    {
        case XML_ELEMENT(TEXT, XML_KIND):
            if( IsXMLToken( sAttrValue, XML_VALUE ) )
            {
                mnKind = 0; bValid = true;
            }
            else if( IsXMLToken( sAttrValue, XML_UNIT ) )
            {
                mnKind = 1; bValid = true;
            }
            else if( IsXMLToken( sAttrValue, XML_GAP ) )
            {
                mnKind = 2; bValid = true;
            }
            break;
        default:
            XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
    }
}

void XMLMeasureFieldImportContext::PrepareField(
    const Reference<XPropertySet> & xPropertySet)
{
    xPropertySet->setPropertyValue(u"Kind"_ustr, Any(mnKind));
}


// dropdown field


XMLDropDownFieldImportContext::XMLDropDownFieldImportContext(
        SvXMLImport& rImport,
        XMLTextImportHelper& rHlp) :
    XMLTextFieldImportContext( rImport, rHlp, u"DropDown"_ustr ),
    nSelected( -1 ),
    bNameOK( false ),
    bHelpOK(false),
    bHintOK(false)
{
    bValid = true;
}

static bool lcl_ProcessLabel(
                       const Reference<XFastAttributeList>& xAttrList,
                       OUString& rLabel,
                       bool& rIsSelected )
{
    bool bValid = false;
    forauto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
    {
        switch (aIter.getToken())
        {
            case XML_ELEMENT(TEXT, XML_VALUE):
            {
                rLabel = aIter.toString();
                bValid = true;
                break;
            }
            case XML_ELEMENT(TEXT, XML_CURRENT_SELECTED):
            {
                bool bTmp(false);
                if (::sax::Converter::convertBool( bTmp, aIter.toView() ))
                    rIsSelected = bTmp;
                break;
            }
            default:
                XMLOFF_WARN_UNKNOWN("xmloff", aIter);
        }
    }
    return bValid;
}

css::uno::Reference< css::xml::sax::XFastContextHandler > XMLDropDownFieldImportContext::createFastChildContext(
    sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
{
    if( nElement == XML_ELEMENT(TEXT, XML_LABEL) )
    {
        OUString sLabel;
        bool bIsSelected = false;
        if( lcl_ProcessLabel( xAttrList, sLabel, bIsSelected ) )
        {
            if( bIsSelected )
                nSelected = static_cast<sal_Int32>( aLabels.size() );
            aLabels.push_back( sLabel );
        }
    }
    return new SvXMLImportContext( GetImport() );
}

void XMLDropDownFieldImportContext::ProcessAttribute(
    sal_Int32 nAttrToken,
    std::string_view sAttrValue )
{
    if( nAttrToken == XML_ELEMENT(TEXT, XML_NAME))
    {
        sName = OUString::fromUtf8(sAttrValue);
        bNameOK = true;
    }
    else if (nAttrToken ==  XML_ELEMENT(TEXT, XML_HELP))
    {
        sHelp = OUString::fromUtf8(sAttrValue);
        bHelpOK = true;
    }
    else if (nAttrToken ==  XML_ELEMENT(TEXT, XML_HINT))
    {
        sHint = OUString::fromUtf8(sAttrValue);
        bHintOK = true;
    }
    else
        XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
}

void XMLDropDownFieldImportContext::PrepareField(
    const Reference<XPropertySet>& xPropertySet)
{
    // create sequence
    sal_Int32 nLength = static_cast<sal_Int32>( aLabels.size() );
    Sequence<OUString> aSequence( nLength );
    OUString* pSequence = aSequence.getArray();
    for( sal_Int32 n = 0; n < nLength; n++ )
        pSequence[n] = aLabels[n];

    // now set values:

    xPropertySet->setPropertyValue( u"Items"_ustr, Any(aSequence) );

    if( nSelected >= 0  &&  nSelected < nLength )
    {
        xPropertySet->setPropertyValue( u"SelectedItem"_ustr, Any(pSequence[nSelected]) );
    }

    // set name
    if( bNameOK )
    {
        xPropertySet->setPropertyValue( u"Name"_ustr, Any(sName) );
    }
    // set help
    if( bHelpOK )
    {
        xPropertySet->setPropertyValue( u"Help"_ustr, Any(sHelp) );
    }
    // set hint
    if( bHintOK )
    {
        xPropertySet->setPropertyValue( u"Tooltip"_ustr, Any(sHint) );
    }

}

/** import header fields (<draw:header>) */

XMLHeaderFieldImportContext::XMLHeaderFieldImportContext(
        SvXMLImport& rImport,                   /// XML Import
        XMLTextImportHelper& rHlp)              /// Text import helper
: XMLTextFieldImportContext(rImport, rHlp, u"Header"_ustr )
{
    sServicePrefix = sAPI_presentation_prefix;
    bValid = true;
}

/// process attribute values
void XMLHeaderFieldImportContext::ProcessAttribute( sal_Int32 nAttrToken, std::string_view sAttrValue )
{
    XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
}

/// prepare XTextField for insertion into document
void XMLHeaderFieldImportContext::PrepareField(const Reference<XPropertySet> &)
{
}

/** import footer fields (<draw:footer>) */

XMLFooterFieldImportContext::XMLFooterFieldImportContext(
        SvXMLImport& rImport,                   /// XML Import
        XMLTextImportHelper& rHlp)              /// Text import helper
: XMLTextFieldImportContext(rImport, rHlp, u"Footer"_ustr )
{
    sServicePrefix = sAPI_presentation_prefix;
    bValid = true;
}

/// process attribute values
void XMLFooterFieldImportContext::ProcessAttribute( sal_Int32 nAttrToken, std::string_view sAttrValue)
{
    XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
}

/// prepare XTextField for insertion into document
void XMLFooterFieldImportContext::PrepareField(const Reference<XPropertySet> &)
{
}


/** import footer fields (<draw:date-and-time>) */

XMLDateTimeFieldImportContext::XMLDateTimeFieldImportContext(
        SvXMLImport& rImport,                   /// XML Import
        XMLTextImportHelper& rHlp)              /// Text import helper
: XMLTextFieldImportContext(rImport, rHlp, u"DateTime"_ustr )
{
    sServicePrefix = sAPI_presentation_prefix;
    bValid = true;
}

/// process attribute values
void XMLDateTimeFieldImportContext::ProcessAttribute( sal_Int32 nAttrToken,
                                   std::string_view sAttrValue )
{
    XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
}

/// prepare XTextField for insertion into document
void XMLDateTimeFieldImportContext::PrepareField(
        const css::uno::Reference<
        css::beans::XPropertySet> &)
{
}

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

Messung V0.5 in Prozent
C=95 H=99 G=96

¤ Dauer der Verarbeitung: 0.56 Sekunden  (vorverarbeitet am  2026-04-28) ¤

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






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge