/* -*- 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
for(
auto &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::strin
g_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) )
{
for( auto& 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, false, false)
{
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, false, false)
, 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, false, false)
, 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 }
};
--> --------------------
--> maximum size reached
--> --------------------