/* -*- 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 .
*/
namespace
{ /// Walks up the parent chain of xText and returns the topmost text.
uno::Reference<text::XText> GetToplevelText(const uno::Reference<text::XText>& xText)
{
uno::Reference<text::XText> xRet = xText; while (true)
{
uno::Reference<beans::XPropertySet> xPropertySet(xRet, uno::UNO_QUERY); if (!xPropertySet.is()) return xRet;
if (!xPropertySet->getPropertySetInfo()->hasPropertyByName(u"ParentText"_ustr)) return xRet;
/// get the field ID (as in FieldIDEnum) from XTextField enum FieldIdEnum XMLTextFieldExport::GetFieldID( const Reference<XTextField> & rTextField, const Reference<XPropertySet> & xPropSet)
{ // get service names for rTextField (via XServiceInfo service)
Reference<XServiceInfo> xService(rTextField, UNO_QUERY); const Sequence<OUString> aServices = xService->getSupportedServiceNames();
OUString sFieldName; // service name postfix of current field
// search for TextField service name const OUString* pNames = std::find_if(aServices.begin(), aServices.end(),
[](const OUString& rName) { return rName.matchIgnoreAsciiCase(gsServicePrefix); }); if (pNames != aServices.end())
{ // TextField found => postfix is field type!
sFieldName = pNames->copy(gsServicePrefix.getLength());
}
// if this is not a normal text field, check if it's a presentation text field if( sFieldName.isEmpty() )
{ // search for TextField service name
pNames = std::find_if(aServices.begin(), aServices.end(),
[](const OUString& rName) { return rName.startsWith(gsPresentationServicePrefix); }); if (pNames != aServices.end())
{ // TextField found => postfix is field type!
sFieldName = pNames->copy(gsPresentationServicePrefix.getLength());
}
// map postfix of service name to field ID
DBG_ASSERT(!sFieldName.isEmpty(), "no TextField service found!"); return MapFieldName(sFieldName, xPropSet);
}
enum FieldIdEnum XMLTextFieldExport::MapFieldName(
std::u16string_view sFieldName, // field (master) name const Reference<XPropertySet> & xPropSet) // for subtype
{ // we'll proceed in 2 steps: // a) map service name to preliminary FIELD_ID // b) map those prelim. FIELD_IDs that correspond to several field types // (in our (XML) world) to final FIELD IDs
// a) find prelim. FIELD_ID via aFieldServiceMapping
// check for non-empty service name
DBG_ASSERT(!sFieldName.empty(), "no valid service name!"); enum FieldIdEnum nToken = FIELD_ID_UNKNOWN; if (!sFieldName.empty())
{ // map name to prelim. ID bool bRet = SvXMLUnitConverter::convertEnum(
nToken, sFieldName, aFieldServiceNameMapping);
// check return
DBG_ASSERT(bRet, "Unknown field service name encountered!");
}
// b) map prelim. to final FIELD_IDs switch (nToken) { case FIELD_ID_VARIABLE_SET: if (GetBoolProperty(gsPropertyIsInput, xPropSet))
{
nToken = FIELD_ID_VARIABLE_INPUT;
} else
{ switch (GetIntProperty(gsPropertySubType, xPropSet))
{ case SetVariableType::STRING: // text field case SetVariableType::VAR: // num field
nToken = FIELD_ID_VARIABLE_SET; break; case SetVariableType::SEQUENCE:
nToken = FIELD_ID_SEQUENCE; break; case SetVariableType::FORMULA: default:
nToken = FIELD_ID_UNKNOWN; break;
}
} break;
case FIELD_ID_VARIABLE_GET: switch (GetIntProperty(gsPropertySubType, xPropSet))
{ case SetVariableType::STRING: // text field case SetVariableType::VAR: // num field
nToken = FIELD_ID_VARIABLE_GET; break; case SetVariableType::FORMULA:
nToken = FIELD_ID_EXPRESSION; break; case SetVariableType::SEQUENCE: default:
nToken = FIELD_ID_UNKNOWN; break;
} break;
case FIELD_ID_TIME: if (GetBoolProperty(gsPropertyIsDate, xPropSet))
{
nToken = FIELD_ID_DATE;
} break;
case FIELD_ID_PAGENUMBER: // NumberingType not available in non-Writer apps if (xPropSet->getPropertySetInfo()->
hasPropertyByName(gsPropertyNumberingType))
{ if (NumberingType::CHAR_SPECIAL == GetIntProperty(
gsPropertyNumberingType, xPropSet))
{
nToken = FIELD_ID_PAGESTRING;
}
} break;
case FIELD_ID_DOCINFO_CREATION_TIME: if (GetBoolProperty(gsPropertyIsDate, xPropSet))
{
nToken = FIELD_ID_DOCINFO_CREATION_DATE;
} break;
case FIELD_ID_DOCINFO_PRINT_TIME: if (GetBoolProperty(gsPropertyIsDate, xPropSet))
{
nToken = FIELD_ID_DOCINFO_PRINT_DATE;
} break;
case FIELD_ID_DOCINFO_SAVE_TIME: if (GetBoolProperty(gsPropertyIsDate, xPropSet))
{
nToken = FIELD_ID_DOCINFO_SAVE_DATE;
} break;
case FIELD_ID_REF_REFERENCE: switch (GetInt16Property(gsPropertyReferenceFieldSource, xPropSet))
{ case ReferenceFieldSource::REFERENCE_MARK:
nToken = FIELD_ID_REF_REFERENCE; break; case ReferenceFieldSource::SEQUENCE_FIELD:
nToken = FIELD_ID_REF_SEQUENCE; break; case ReferenceFieldSource::BOOKMARK:
nToken = FIELD_ID_REF_BOOKMARK; break; case ReferenceFieldSource::FOOTNOTE:
nToken = FIELD_ID_REF_FOOTNOTE; break; case ReferenceFieldSource::ENDNOTE:
nToken = FIELD_ID_REF_ENDNOTE; break; case ReferenceFieldSource::STYLE:
nToken = FIELD_ID_REF_STYLE; break; default:
nToken = FIELD_ID_UNKNOWN; break;
} break;
case FIELD_ID_COMBINED_CHARACTERS: case FIELD_ID_SCRIPT: case FIELD_ID_ANNOTATION: case FIELD_ID_BIBLIOGRAPHY: case FIELD_ID_DDE: case FIELD_ID_MACRO: case FIELD_ID_REFPAGE_SET: case FIELD_ID_REFPAGE_GET: case FIELD_ID_COUNT_PAGES: case FIELD_ID_COUNT_PAGES_RANGE: case FIELD_ID_COUNT_PARAGRAPHS: case FIELD_ID_COUNT_WORDS: case FIELD_ID_COUNT_CHARACTERS: case FIELD_ID_COUNT_TABLES: case FIELD_ID_COUNT_GRAPHICS: case FIELD_ID_COUNT_OBJECTS: case FIELD_ID_CONDITIONAL_TEXT: case FIELD_ID_HIDDEN_TEXT: case FIELD_ID_HIDDEN_PARAGRAPH: case FIELD_ID_DOCINFO_CREATION_AUTHOR: case FIELD_ID_DOCINFO_DESCRIPTION: case FIELD_ID_DOCINFO_CUSTOM: case FIELD_ID_DOCINFO_PRINT_AUTHOR: case FIELD_ID_DOCINFO_TITLE: case FIELD_ID_DOCINFO_SUBJECT: case FIELD_ID_DOCINFO_KEYWORDS: case FIELD_ID_DOCINFO_REVISION: case FIELD_ID_DOCINFO_EDIT_DURATION: case FIELD_ID_DOCINFO_SAVE_AUTHOR: case FIELD_ID_TEXT_INPUT: case FIELD_ID_USER_INPUT: case FIELD_ID_AUTHOR: case FIELD_ID_SENDER: case FIELD_ID_PLACEHOLDER: case FIELD_ID_USER_GET: case FIELD_ID_DATABASE_NEXT: case FIELD_ID_DATABASE_SELECT: case FIELD_ID_DATABASE_DISPLAY: case FIELD_ID_DATABASE_NAME: case FIELD_ID_DATABASE_NUMBER: case FIELD_ID_TEMPLATE_NAME: case FIELD_ID_CHAPTER: case FIELD_ID_FILE_NAME: case FIELD_ID_META: case FIELD_ID_SHEET_NAME: case FIELD_ID_PAGENAME: case FIELD_ID_MEASURE: case FIELD_ID_URL: case FIELD_ID_TABLE_FORMULA: case FIELD_ID_DROP_DOWN:
; // these field IDs are final break;
default:
nToken = FIELD_ID_UNKNOWN;
}
// ... and return final FIELD_ID return nToken;
}
// is string or numeric field? bool XMLTextFieldExport::IsStringField(
FieldIdEnum nFieldType, const Reference<XPropertySet> & xPropSet)
{ switch (nFieldType) {
case FIELD_ID_VARIABLE_GET: case FIELD_ID_VARIABLE_SET: case FIELD_ID_VARIABLE_INPUT:
{ // depends on field sub type return ( GetIntProperty(gsPropertySubType, xPropSet) ==
SetVariableType::STRING );
}
case FIELD_ID_USER_GET: case FIELD_ID_USER_INPUT:
{
Reference<XTextField> xTextField(xPropSet, UNO_QUERY);
DBG_ASSERT(xTextField.is(), "field is no XTextField!"); bool bRet = GetBoolProperty(gsPropertyIsExpression,
GetMasterPropertySet(xTextField)); return !bRet;
}
case FIELD_ID_META: return 0 > GetIntProperty(gsPropertyNumberFormat, xPropSet);
case FIELD_ID_DATABASE_DISPLAY: // TODO: depends on... ??? // workaround #no-bug#: no data type return 5100 == GetIntProperty(gsPropertyNumberFormat, xPropSet);
case FIELD_ID_TABLE_FORMULA: // legacy field: always a number field (because it always has // a number format) returnfalse;
case FIELD_ID_COUNT_PAGES: case FIELD_ID_COUNT_PAGES_RANGE: case FIELD_ID_COUNT_PARAGRAPHS: case FIELD_ID_COUNT_WORDS: case FIELD_ID_COUNT_CHARACTERS: case FIELD_ID_COUNT_TABLES: case FIELD_ID_COUNT_GRAPHICS: case FIELD_ID_COUNT_OBJECTS: case FIELD_ID_DOCINFO_SAVE_TIME: case FIELD_ID_DOCINFO_SAVE_DATE: case FIELD_ID_DOCINFO_CREATION_DATE: case FIELD_ID_DOCINFO_CREATION_TIME: case FIELD_ID_DOCINFO_PRINT_TIME: case FIELD_ID_DOCINFO_PRINT_DATE: case FIELD_ID_DOCINFO_EDIT_DURATION: case FIELD_ID_DOCINFO_REVISION: case FIELD_ID_DATABASE_NUMBER: case FIELD_ID_EXPRESSION: case FIELD_ID_SEQUENCE: case FIELD_ID_DATE: case FIELD_ID_TIME: case FIELD_ID_PAGENUMBER: case FIELD_ID_REFPAGE_SET: case FIELD_ID_REFPAGE_GET: case FIELD_ID_DOCINFO_CUSTOM: // always number returnfalse;
case FIELD_ID_COMBINED_CHARACTERS: case FIELD_ID_BIBLIOGRAPHY: case FIELD_ID_DDE: case FIELD_ID_REF_REFERENCE: case FIELD_ID_REF_SEQUENCE: case FIELD_ID_REF_BOOKMARK: case FIELD_ID_REF_FOOTNOTE: case FIELD_ID_REF_ENDNOTE: case FIELD_ID_REF_STYLE: case FIELD_ID_MACRO: case FIELD_ID_TEMPLATE_NAME: case FIELD_ID_CHAPTER: case FIELD_ID_FILE_NAME: case FIELD_ID_CONDITIONAL_TEXT: case FIELD_ID_HIDDEN_TEXT: case FIELD_ID_HIDDEN_PARAGRAPH: case FIELD_ID_DOCINFO_CREATION_AUTHOR: case FIELD_ID_DOCINFO_DESCRIPTION: case FIELD_ID_DOCINFO_PRINT_AUTHOR: case FIELD_ID_DOCINFO_TITLE: case FIELD_ID_DOCINFO_SUBJECT: case FIELD_ID_DOCINFO_KEYWORDS: case FIELD_ID_DOCINFO_SAVE_AUTHOR: case FIELD_ID_DATABASE_NAME: case FIELD_ID_TEXT_INPUT: case FIELD_ID_SENDER: case FIELD_ID_AUTHOR: case FIELD_ID_PAGENAME: case FIELD_ID_PAGESTRING: case FIELD_ID_SHEET_NAME: case FIELD_ID_MEASURE: case FIELD_ID_URL: case FIELD_ID_DROP_DOWN: // always string: returntrue;
case FIELD_ID_SCRIPT: case FIELD_ID_ANNOTATION: case FIELD_ID_DATABASE_NEXT: case FIELD_ID_DATABASE_SELECT: case FIELD_ID_PLACEHOLDER: case FIELD_ID_UNKNOWN: case FIELD_ID_DRAW_HEADER: case FIELD_ID_DRAW_FOOTER: case FIELD_ID_DRAW_DATE_TIME: default:
OSL_FAIL("unknown field type/field has no content"); returntrue; // invalid info; string in case of doubt
}
}
/// export the styles needed by the given field. Called on first pass /// through document void XMLTextFieldExport::ExportFieldAutoStyle( const Reference<XTextField> & rTextField, constbool bProgress )
{ // get property set
Reference<XPropertySet> xPropSet(rTextField, UNO_QUERY);
// add field master to list of used field masters (if desired) if (moUsedMasters)
{
Reference<XDependentTextField> xDepField(rTextField, UNO_QUERY); if (xDepField.is())
{ // The direct parent may be just the table cell, while we want the topmost parent, e.g. // a header text.
Reference<XText> xOurText = GetToplevelText(rTextField->getAnchor()->getText());
// insert a list for our XText (if necessary) auto aMapIter = moUsedMasters->try_emplace(xOurText).first;
assert(aMapIter != moUsedMasters->end());
// insert this text field master
OUString sFieldMasterName = GetStringProperty(
gsPropertyInstanceName, xDepField->getTextFieldMaster()); if (!sFieldMasterName.isEmpty())
aMapIter->second.insert( sFieldMasterName );
} // else: no dependent field -> no master -> ignore
}
// get Field ID
FieldIdEnum nToken = GetFieldID(rTextField, xPropSet);
// export the character style for all fields // with one exception: combined character fields export their own // text style below
Reference <XPropertySet> xRangePropSet(rTextField->getAnchor(), UNO_QUERY); if (FIELD_ID_COMBINED_CHARACTERS != nToken)
{
GetExport().GetTextParagraphExport()->Add(
XmlStyleFamily::TEXT_TEXT, xRangePropSet);
}
// process special styles for each field (e.g. data styles) switch (nToken) {
case FIELD_ID_DATABASE_DISPLAY:
{
sal_Int32 nFormat = GetIntProperty(gsPropertyNumberFormat, xPropSet); // workaround: #no-bug#; see IsStringField(...) if ( (5100 != nFormat) &&
!GetBoolProperty(gsPropertyIsDataBaseFormat, xPropSet) )
{
GetExport().addDataStyle(nFormat);
} break;
}
case FIELD_ID_DATE: case FIELD_ID_TIME:
{ // date and time fields are always number fields, but the // NumberFormat property is optional (e.g. Calc doesn't // support it)
Reference<XPropertySetInfo> xPropSetInfo(
xPropSet->getPropertySetInfo() ); if ( xPropSetInfo->hasPropertyByName( gsPropertyNumberFormat ) )
{
sal_Int32 nFormat =
GetIntProperty(gsPropertyNumberFormat, xPropSet);
// nFormat may be -1 for numeric fields that display their // variable name. (Maybe this should be a field type, then?) if (nFormat != -1)
{ if( ! GetOptionalBoolProperty(
gsPropertyIsFixedLanguage,
xPropSet, xPropSetInfo, false ) )
{
nFormat =
GetExport().dataStyleForceSystemLanguage(nFormat);
}
case FIELD_ID_META: // recurse into content (does not export element, so can be done first)
{ bool dummy_for_autostyles(true);
ExportMetaField(xPropSet, true, bProgress, dummy_for_autostyles);
}
[[fallthrough]]; case FIELD_ID_DOCINFO_PRINT_TIME: case FIELD_ID_DOCINFO_PRINT_DATE: case FIELD_ID_DOCINFO_CREATION_DATE: case FIELD_ID_DOCINFO_CREATION_TIME: case FIELD_ID_DOCINFO_SAVE_TIME: case FIELD_ID_DOCINFO_SAVE_DATE: case FIELD_ID_DOCINFO_EDIT_DURATION: case FIELD_ID_VARIABLE_SET: case FIELD_ID_VARIABLE_GET: case FIELD_ID_VARIABLE_INPUT: case FIELD_ID_USER_GET: case FIELD_ID_EXPRESSION: case FIELD_ID_TABLE_FORMULA: case FIELD_ID_DOCINFO_CUSTOM: // register number format, if this is a numeric field if (! IsStringField(nToken, xPropSet)) {
// nFormat may be -1 for numeric fields that display their // variable name. (Maybe this should be a field type, then?) if (nFormat != -1)
{ // handle formats for fixed language fields // for all these fields (except table formula) if( ( nToken != FIELD_ID_TABLE_FORMULA ) &&
! GetOptionalBoolProperty(
gsPropertyIsFixedLanguage,
xPropSet, xPropSet->getPropertySetInfo(), false ) )
{
nFormat =
GetExport().dataStyleForceSystemLanguage(nFormat);
}
GetExport().addDataStyle(nFormat);
}
} break;
case FIELD_ID_COMBINED_CHARACTERS:
{ // export text style with the addition of the combined characters
DBG_ASSERT(nullptr != pCombinedCharactersPropertyState, "need proper PropertyState for combined characters");
std::span<XMLPropertyState> aStates( pCombinedCharactersPropertyState.get(), 1 );
GetExport().GetTextParagraphExport()->Add(
XmlStyleFamily::TEXT_TEXT, xRangePropSet,
aStates); break;
}
case FIELD_ID_ANNOTATION: if (auto xText = XTextFromTextRangeProp(xPropSet))
GetExport().GetTextParagraphExport()->collectTextAutoStyles(xText, bProgress); break;
case FIELD_ID_SCRIPT: case FIELD_ID_BIBLIOGRAPHY: case FIELD_ID_DDE: case FIELD_ID_REF_REFERENCE: case FIELD_ID_REF_SEQUENCE: case FIELD_ID_REF_BOOKMARK: case FIELD_ID_REF_FOOTNOTE: case FIELD_ID_REF_ENDNOTE: case FIELD_ID_REF_STYLE: case FIELD_ID_MACRO: case FIELD_ID_REFPAGE_SET: case FIELD_ID_REFPAGE_GET: case FIELD_ID_COUNT_PAGES: case FIELD_ID_COUNT_PAGES_RANGE: case FIELD_ID_COUNT_PARAGRAPHS: case FIELD_ID_COUNT_WORDS: case FIELD_ID_COUNT_CHARACTERS: case FIELD_ID_COUNT_TABLES: case FIELD_ID_COUNT_GRAPHICS: case FIELD_ID_COUNT_OBJECTS: case FIELD_ID_CONDITIONAL_TEXT: case FIELD_ID_HIDDEN_TEXT: case FIELD_ID_HIDDEN_PARAGRAPH: case FIELD_ID_DOCINFO_CREATION_AUTHOR: case FIELD_ID_DOCINFO_DESCRIPTION: case FIELD_ID_DOCINFO_PRINT_AUTHOR: case FIELD_ID_DOCINFO_TITLE: case FIELD_ID_DOCINFO_SUBJECT: case FIELD_ID_DOCINFO_KEYWORDS: case FIELD_ID_DOCINFO_REVISION: case FIELD_ID_DOCINFO_SAVE_AUTHOR: case FIELD_ID_SEQUENCE: case FIELD_ID_PAGENAME: case FIELD_ID_PAGENUMBER: case FIELD_ID_PAGESTRING: case FIELD_ID_AUTHOR: case FIELD_ID_SENDER: case FIELD_ID_PLACEHOLDER: case FIELD_ID_USER_INPUT: case FIELD_ID_TEXT_INPUT: case FIELD_ID_DATABASE_NEXT: case FIELD_ID_DATABASE_SELECT: case FIELD_ID_DATABASE_NAME: case FIELD_ID_DATABASE_NUMBER: case FIELD_ID_TEMPLATE_NAME: case FIELD_ID_CHAPTER: case FIELD_ID_FILE_NAME: case FIELD_ID_SHEET_NAME: case FIELD_ID_MEASURE: case FIELD_ID_URL: case FIELD_ID_DROP_DOWN: case FIELD_ID_DRAW_DATE_TIME: case FIELD_ID_DRAW_FOOTER: case FIELD_ID_DRAW_HEADER:
; // no formats for these fields! break;
case FIELD_ID_UNKNOWN: default:
OSL_FAIL("unknown field type!"); // ignore -> no format for unknown break;
}
}
/// export the given field to XML. Called on second pass through document void XMLTextFieldExport::ExportField( const Reference<XTextField> & rTextField, bool bProgress, bool & rPrevCharIsSpace)
{ // get property set
Reference<XPropertySet> xPropSet(rTextField, UNO_QUERY);
// get property set of range (for the attributes)
Reference <XPropertySet> xRangePropSet(rTextField->getAnchor(), UNO_QUERY);
// get Field ID enum FieldIdEnum nToken = GetFieldID(rTextField, xPropSet);
// special treatment for combined characters field, because it is // exported as a style const XMLPropertyState* aStates[] = { pCombinedCharactersPropertyState.get(), nullptr }; const XMLPropertyState **pStates =
FIELD_ID_COMBINED_CHARACTERS == nToken
? aStates
: nullptr;
// find out whether we need to set the style bool bIsUICharStyle; bool bHasAutoStyle;
OUString sStyle = GetExport().GetTextParagraphExport()->
FindTextStyle( xRangePropSet, bIsUICharStyle, bHasAutoStyle, pStates ); bool bHasStyle = !sStyle.isEmpty();
// finally, export the field itself
ExportFieldHelper( rTextField, xPropSet, xRangePropSet, nToken,
bProgress, rPrevCharIsSpace);
}
}
/// export the given field to XML. Called on second pass through document void XMLTextFieldExport::ExportFieldHelper( const Reference<XTextField> & rTextField, const Reference<XPropertySet> & rPropSet, const Reference<XPropertySet> &, enum FieldIdEnum nToken, bool bProgress, bool & rPrevCharIsSpace)
{ // get property set info (because some attributes are not support // in all implementations)
Reference<XPropertySetInfo> xPropSetInfo(rPropSet->getPropertySetInfo());
// process each field type switch (nToken) { case FIELD_ID_AUTHOR: // author field: fixed, field (sub-)type if (xPropSetInfo->hasPropertyByName(gsPropertyIsFixed))
{
GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_FIXED,
(GetBoolProperty(gsPropertyIsFixed, rPropSet) ? XML_TRUE : XML_FALSE) );
}
ExportElement(MapAuthorFieldName(rPropSet), sPresentation); break;
case FIELD_ID_SENDER: // sender field: fixed, field (sub-)type
ProcessBoolean(XML_FIXED,
GetBoolProperty(gsPropertyIsFixed, rPropSet), true);
ExportElement(MapSenderFieldName(rPropSet), sPresentation); break;
case FIELD_ID_TEXT_INPUT: // text input field: description and string-value
ProcessString(XML_DESCRIPTION,
GetStringProperty(gsPropertyHint, rPropSet));
ProcessString(XML_HELP,
GetStringProperty(gsPropertyHelp, rPropSet), true);
ProcessString(XML_HINT,
GetStringProperty(gsPropertyTooltip, rPropSet), true);
ExportElement(XML_TEXT_INPUT, sPresentation); break;
case FIELD_ID_TIME: // all properties (except IsDate) are optional! if (xPropSetInfo->hasPropertyByName(gsPropertyNumberFormat))
{
ProcessValueAndType(false,
GetIntProperty(gsPropertyNumberFormat,rPropSet),
u""_ustr, u"", 0.0, // not used false, false, true,
! GetOptionalBoolProperty(
gsPropertyIsFixedLanguage,
rPropSet, xPropSetInfo, false ), true);
} if (xPropSetInfo->hasPropertyByName(gsPropertyDateTimeValue))
{ // no value -> current time
ProcessTimeOrDateTime(XML_TIME_VALUE,
GetDateTimeProperty(gsPropertyDateTimeValue,
rPropSet));
} if (xPropSetInfo->hasPropertyByName(gsPropertyDateTime))
{ // no value -> current time
ProcessTimeOrDateTime(XML_TIME_VALUE,
GetDateTimeProperty(gsPropertyDateTime,rPropSet));
} if (xPropSetInfo->hasPropertyByName(gsPropertyIsFixed))
{
ProcessBoolean(XML_FIXED,
GetBoolProperty(gsPropertyIsFixed, rPropSet), false);
} if (xPropSetInfo->hasPropertyByName(gsPropertyAdjust))
{ // adjust value given as integer in minutes
ProcessDateTime(XML_TIME_ADJUST,
GetIntProperty(gsPropertyAdjust, rPropSet), false, true);
}
ExportElement(XML_TIME, sPresentation); break;
case FIELD_ID_DATE: // all properties (except IsDate) are optional! if (xPropSetInfo->hasPropertyByName(gsPropertyNumberFormat))
{
ProcessValueAndType(false,
GetIntProperty(gsPropertyNumberFormat,rPropSet),
u""_ustr, u"", 0.0, // not used false, false, true,
! GetOptionalBoolProperty(
gsPropertyIsFixedLanguage,
rPropSet, xPropSetInfo, false ) );
} if (xPropSetInfo->hasPropertyByName(gsPropertyDateTimeValue))
{ // no value -> current date
ProcessDateTime(XML_DATE_VALUE,
GetDateTimeProperty(gsPropertyDateTimeValue,
rPropSet));
} // TODO: remove double-handling after SRC614 elseif (xPropSetInfo->hasPropertyByName(gsPropertyDateTime))
{
ProcessDateTime(XML_DATE_VALUE,
GetDateTimeProperty(gsPropertyDateTime,rPropSet));
} if (xPropSetInfo->hasPropertyByName(gsPropertyIsFixed))
{
ProcessBoolean(XML_FIXED,
GetBoolProperty(gsPropertyIsFixed, rPropSet), false);
} if (xPropSetInfo->hasPropertyByName(gsPropertyAdjust))
{ // adjust value given as number of days
ProcessDateTime(XML_DATE_ADJUST,
GetIntProperty(gsPropertyAdjust, rPropSet), true, true);
}
ExportElement(XML_DATE, sPresentation); break;
case FIELD_ID_PAGENUMBER: // all properties are optional if (xPropSetInfo->hasPropertyByName(gsPropertyNumberingType))
{
ProcessNumberingType(GetInt16Property(gsPropertyNumberingType,
rPropSet));
} if (xPropSetInfo->hasPropertyByName(gsPropertyOffset))
{
sal_Int32 nAdjust = GetIntProperty(gsPropertyOffset, rPropSet);
if (xPropSetInfo->hasPropertyByName(gsPropertySubType))
{ // property SubType used in MapPageNumberName
ProcessString(XML_SELECT_PAGE,
MapPageNumberName(rPropSet, nAdjust));
}
ProcessIntegerDef(XML_PAGE_ADJUST, nAdjust, 0);
}
ExportElement(XML_PAGE_NUMBER, sPresentation); break;
case FIELD_ID_PAGESTRING:
{
ProcessString(XML_STRING_VALUE,
GetStringProperty(gsPropertyUserText, rPropSet),
sPresentation);
sal_Int32 nDummy = 0; // MapPageNumberName need int
ProcessString(XML_SELECT_PAGE, MapPageNumberName(rPropSet, nDummy));
ExportElement(XML_PAGE_CONTINUATION, sPresentation); break;
}
case FIELD_ID_DATABASE_DISPLAY:
{ // get database, table and column name from field master const Reference<XPropertySet> xMaster = GetMasterPropertySet(rTextField);
ProcessString(XML_TABLE_NAME,
GetStringProperty(gsPropertyDataTableName, xMaster));
ProcessCommandType(GetIntProperty(gsPropertyDataCommandType, xMaster));
ProcessString(XML_COLUMN_NAME,
GetStringProperty(gsPropertyDataColumnName, xMaster)); // export number format if available (happens only for numbers!) if (!GetBoolProperty(gsPropertyIsDataBaseFormat, rPropSet))
{
ProcessValueAndType(false, // doesn't happen for text
GetIntProperty(gsPropertyNumberFormat,rPropSet),
u""_ustr, u"", 0.0, // not used false, false, true, false);
}
ProcessDisplay(GetBoolProperty(gsPropertyIsVisible, rPropSet), false);
ExportDataBaseElement(XML_DATABASE_DISPLAY, sPresentation,
xMaster, xMaster->getPropertySetInfo()); break;
}
case FIELD_ID_DOCINFO_REVISION:
ProcessBoolean(XML_FIXED,
GetBoolProperty(gsPropertyIsFixed, rPropSet), false);
ExportElement(MapDocInfoFieldName(nToken), sPresentation); break;
case FIELD_ID_DOCINFO_EDIT_DURATION: case FIELD_ID_DOCINFO_SAVE_TIME: case FIELD_ID_DOCINFO_CREATION_TIME: case FIELD_ID_DOCINFO_PRINT_TIME: case FIELD_ID_DOCINFO_SAVE_DATE: case FIELD_ID_DOCINFO_CREATION_DATE: case FIELD_ID_DOCINFO_PRINT_DATE:
ProcessValueAndType(false,
GetIntProperty(gsPropertyNumberFormat, rPropSet),
u""_ustr, u"", 0.0, false, false, true,
! GetOptionalBoolProperty(
gsPropertyIsFixedLanguage,
rPropSet, xPropSetInfo, false ) );
// todo: export date/time value, but values not available -> core bug
ProcessBoolean(XML_FIXED,
GetBoolProperty(gsPropertyIsFixed, rPropSet), false);
ExportElement(MapDocInfoFieldName(nToken), sPresentation); break;
case FIELD_ID_DOCINFO_CREATION_AUTHOR: case FIELD_ID_DOCINFO_DESCRIPTION: case FIELD_ID_DOCINFO_PRINT_AUTHOR: case FIELD_ID_DOCINFO_TITLE: case FIELD_ID_DOCINFO_SUBJECT: case FIELD_ID_DOCINFO_KEYWORDS: case FIELD_ID_DOCINFO_SAVE_AUTHOR: if (xPropSetInfo->hasPropertyByName(gsPropertyIsFixed))
{
ProcessBoolean(XML_FIXED,
GetBoolProperty(gsPropertyIsFixed, rPropSet), false);
}
ExportElement(MapDocInfoFieldName(nToken), sPresentation); break;
case FIELD_ID_DOCINFO_CUSTOM:
{
ProcessValueAndType(false, // doesn't happen for text
GetIntProperty(gsPropertyNumberFormat,rPropSet),
u""_ustr, u"", 0.0, // not used false, false, true,
! GetOptionalBoolProperty(
gsPropertyIsFixedLanguage,
rPropSet, xPropSetInfo, false ));
uno::Any aAny = rPropSet->getPropertyValue( gsPropertyName );
OUString sName;
aAny >>= sName;
ProcessString(XML_NAME, sName);
ProcessBoolean(XML_FIXED, GetBoolProperty(gsPropertyIsFixed, rPropSet), false);
ExportElement(XML_USER_DEFINED, sPresentation); break;
}
case FIELD_ID_COUNT_PAGES: case FIELD_ID_COUNT_PARAGRAPHS: case FIELD_ID_COUNT_WORDS: case FIELD_ID_COUNT_CHARACTERS: case FIELD_ID_COUNT_TABLES: case FIELD_ID_COUNT_GRAPHICS: case FIELD_ID_COUNT_OBJECTS: // all properties optional (applies to pages only, but I'll do // it for all for sake of common implementation) if (xPropSetInfo->hasPropertyByName(gsPropertyNumberingType))
{
ProcessNumberingType(GetInt16Property(gsPropertyNumberingType,
rPropSet));
}
ExportElement(MapCountFieldName(nToken), sPresentation, XML_NAMESPACE_TEXT); break;
case FIELD_ID_REFPAGE_GET:
ProcessNumberingType(
GetInt16Property(gsPropertyNumberingType, rPropSet));
ExportElement(XML_PAGE_VARIABLE_GET, sPresentation); break;
case FIELD_ID_MACRO:
ExportMacro( rPropSet, sPresentation ); break;
case FIELD_ID_REF_SEQUENCE: // reference to sequence: format, name, find value (and element) // was: if (nSeqNumber != -1) ...
ProcessString(XML_REFERENCE_FORMAT,
MapReferenceType(GetInt16Property(
gsPropertyReferenceFieldPart, rPropSet)),
XML_TEMPLATE);
ProcessString(XML_REF_NAME,
MakeSequenceRefName(
GetInt16Property(gsPropertySequenceNumber, rPropSet),
GetStringProperty(gsPropertySourceName, rPropSet) ) ); if (xPropSetInfo->hasPropertyByName(gsPropertyReferenceFieldLanguage) &&
GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED)
{ // export text:reference-language attribute, if not empty
ProcessString(XML_REFERENCE_LANGUAGE,
GetStringProperty(gsPropertyReferenceFieldLanguage, rPropSet), true, XML_NAMESPACE_LO_EXT);
}
ExportElement(
MapReferenceSource(
GetInt16Property(gsPropertyReferenceFieldSource, rPropSet)),
sPresentation); break;
case FIELD_ID_REF_REFERENCE: case FIELD_ID_REF_BOOKMARK: // reference to bookmarks, references: format, name (and element)
ProcessString(XML_REFERENCE_FORMAT,
MapReferenceType(GetInt16Property(
gsPropertyReferenceFieldPart, rPropSet)),
XML_TEMPLATE);
ProcessString(XML_REF_NAME,
GetStringProperty(gsPropertySourceName, rPropSet)); if (xPropSetInfo->hasPropertyByName(gsPropertyReferenceFieldLanguage) &&
GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED)
{ // export text:reference-language attribute, if not empty
ProcessString(XML_REFERENCE_LANGUAGE,
GetStringProperty(gsPropertyReferenceFieldLanguage, rPropSet), true, XML_NAMESPACE_LO_EXT);
}
ExportElement(
MapReferenceSource(GetInt16Property(
gsPropertyReferenceFieldSource, rPropSet)),
sPresentation); break;
case FIELD_ID_REF_FOOTNOTE: case FIELD_ID_REF_ENDNOTE: // reference to end-/footnote: format, generate name, (and element)
GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_NOTE_CLASS,
FIELD_ID_REF_ENDNOTE==nToken ? XML_ENDNOTE : XML_FOOTNOTE );
ProcessString(XML_REFERENCE_FORMAT,
MapReferenceType(GetInt16Property(
gsPropertyReferenceFieldPart, rPropSet)),
XML_TEMPLATE);
ProcessString(XML_REF_NAME,
MakeFootnoteRefName(GetInt16Property(
gsPropertySequenceNumber, rPropSet))); if (xPropSetInfo->hasPropertyByName(gsPropertyReferenceFieldLanguage) &&
GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED)
{ // export text:reference-language attribute, if not empty
ProcessString(XML_REFERENCE_LANGUAGE,
GetStringProperty(gsPropertyReferenceFieldLanguage, rPropSet), true, XML_NAMESPACE_LO_EXT);
}
ExportElement(
MapReferenceSource(GetInt16Property(
gsPropertyReferenceFieldSource, rPropSet)),
sPresentation); break;
case FIELD_ID_REF_STYLE:
{
ProcessString(XML_REFERENCE_FORMAT,
MapReferenceType(GetInt16Property(gsPropertyReferenceFieldPart, rPropSet)),
XML_TEMPLATE);
ProcessString(XML_REF_NAME, GetStringProperty(gsPropertySourceName, rPropSet));
sal_uInt16 referenceFieldFlags = GetIntProperty(gsPropertyReferenceFieldFlags, rPropSet); // In reality gsPropertyReferenceFieldFlags is a uInt16... but there is no GetUInt16Property
case FIELD_ID_URL:
{ // this field is a special case because it gets mapped onto a // hyperlink, rather than one of the regular text field.
ProcessString(XML_HREF, GetExport().GetRelativeReference(GetStringProperty(gsPropertyURL, rPropSet)), false, XML_NAMESPACE_XLINK);
ProcessString(XML_TARGET_FRAME_NAME,
GetStringProperty(gsPropertyTargetFrame,rPropSet), true, XML_NAMESPACE_OFFICE);
GetExport().AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
SvXMLElementExport aUrlField(rExport, XML_NAMESPACE_TEXT, XML_A, false, false);
GetExport().Characters(sPresentation); break;
}
case FIELD_ID_BIBLIOGRAPHY:
{
ProcessBibliographyData(rPropSet);
ExportElement(XML_BIBLIOGRAPHY_MARK, sPresentation); break;
}
case FIELD_ID_ANNOTATION:
{ // check for empty presentation (just in case)
DBG_ASSERT(sPresentation.isEmpty(), "Unexpected presentation for annotation field");
case FIELD_ID_COMBINED_CHARACTERS:
{ // The style with the combined characters attribute has // already been handled in the ExportField method. So all that // is left to do now is to export the characters.
GetExport().Characters(sPresentation); break;
}
case FIELD_ID_META:
{
ExportMetaField(rPropSet, false, bProgress, rPrevCharIsSpace); break;
}
case FIELD_ID_UNKNOWN: default:
OSL_FAIL("unknown field type encountered!"); // always export content
GetExport().Characters(sPresentation);
}
}
/// export field declarations / field masters void XMLTextFieldExport::ExportFieldDeclarations()
{
Reference<XText> xEmptyText;
ExportFieldDeclarations(xEmptyText);
}
/// export field declarations / field masters void XMLTextFieldExport::ExportFieldDeclarations( const Reference<XText> & rText )
{ // store lists for decl elements
std::vector<OUString> aVarName;
std::vector<OUString> aUserName;
std::vector<OUString> aSeqName;
std::vector<OUString> aDdeName;
// get text fields supplier and field master name access
Reference<XTextFieldsSupplier> xTextFieldsSupp(GetExport().GetModel(),
UNO_QUERY); if( !xTextFieldsSupp.is() ) return;
// where to get the text field masters from? // a) we get a specific XText: then use pUsedMasters // b) the XText is empty: then export all text fields
Sequence<OUString> aFieldMasters; if (rText.is())
{ // export only used masters
DBG_ASSERT(moUsedMasters.has_value(), "field masters must be recorded in order to be " "written out separately" ); if (moUsedMasters)
{
std::map<Reference<XText>, std::set<OUString> > ::iterator aMapIter =
moUsedMasters->find(rText); if (aMapIter != moUsedMasters->end())
{ // found the set of used field masters
aFieldMasters = comphelper::containerToSequence(aMapIter->second);
moUsedMasters->erase(rText);
} // else: XText not found -> ignore
} // else: no field masters have been recorded -> ignore
} else
{ // no XText: export all!
aFieldMasters = xFieldMasterNameAccess->getElementNames();
}
// get XPropertySet of this field master
Reference<XPropertySet> xPropSet;
Any aAny = xFieldMasterNameAccess->getByName(sFieldMaster);
aAny >>= xPropSet;
// save interesting field masters if (sFieldMasterType == FIELD_SERVICE_SETEXP)
{
sal_Int32 nType = GetIntProperty(gsPropertySubType, xPropSet);
// variable field masters: if ( !aVarName.empty() )
{
SvXMLElementExport aElem( GetExport(),
XML_NAMESPACE_TEXT,
XML_VARIABLE_DECLS, true, true );
for (constauto& sName : aVarName)
{ // get field master property set
Reference<XPropertySet> xPropSet;
Any aAny = xFieldMasterNameAccess->getByName(sName);
aAny >>= xPropSet;
// field name and type
OUString sFieldMasterType;
OUString sVarName;
ExplodeFieldMasterName(sName, sFieldMasterType, sVarName);
// get dependent field property set
Reference<XPropertySet> xFieldPropSet; if (GetDependentFieldPropertySet(xPropSet, xFieldPropSet))
{ // process value and type.
ProcessValueAndType(
bIsString,
GetIntProperty(gsPropertyNumberFormat, xFieldPropSet),
u""_ustr, u"", 0.0, false, true, false, false);
} else
{ // If no dependent field is found, only string and // float types can be supported
// number format: 0 is default number format for 1st // language. should be: getDefaultNumberFormat(Locale) // from NumberFormats
ProcessValueAndType(
bIsString,
0, u""_ustr, u"", 0.0, false, true, false, false);
}
ProcessString(XML_NAME, sVarName);
ExportElement(XML_VARIABLE_DECL, true);
}
} // else: no declarations element
// sequence field masters: if ( !aSeqName.empty() )
{
SvXMLElementExport aElem( GetExport(),
XML_NAMESPACE_TEXT,
XML_SEQUENCE_DECLS, true, true );
for (constauto& sName : aSeqName)
{ // get field master property set
Reference<XPropertySet> xPropSet;
Any aAny = xFieldMasterNameAccess->getByName(sName);
aAny >>= xPropSet;
// field name and type
OUString sFieldMasterType;
OUString sVarName;
ExplodeFieldMasterName(sName, sFieldMasterType, sVarName);
// separation character if (nLevel > 0) {
ProcessString(XML_SEPARATION_CHARACTER, GetStringProperty(
gsPropertyNumberingSeparator, xPropSet));
}
ProcessString(XML_NAME, sVarName);
ExportElement(XML_SEQUENCE_DECL, true);
}
} // else: no declarations element
// user field masters: if ( !aUserName.empty() )
{
SvXMLElementExport aElem( GetExport(),
XML_NAMESPACE_TEXT,
XML_USER_FIELD_DECLS, true, true );
for (constauto& sName : aUserName)
{ // get field master property set
Reference<XPropertySet> xPropSet;
Any aAny = xFieldMasterNameAccess->getByName(sName);
aAny >>= xPropSet;
// field name and type
OUString sFieldMasterType;
OUString sVarName;
ExplodeFieldMasterName(sName, sFieldMasterType, sVarName);
for (constauto& sName : aDdeName)
{ // get field master property set
Reference<XPropertySet> xPropSet;
Any aAny = xFieldMasterNameAccess->getByName(sName);
aAny >>= xPropSet;
// check if this connection is being used by a field
Reference<XPropertySet> xDummy; if (GetDependentFieldPropertySet(xPropSet, xDummy))
{
// create used masters set (if none is used) if (bExportOnlyUsed) #ifdefined __GNUC__ && !defined __clang__ && __GNUC__ == 14 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif
moUsedMasters.emplace(); #ifdefined __GNUC__ && !defined __clang__ && __GNUC__ == 14 #pragma GCC diagnostic pop #endif
}
void XMLTextFieldExport::ExportElement(enum XMLTokenEnum eElementName, bool bAddSpace)
{ // can't call ExportElement(eElementName, const OUString&) with empty // string because xmlprinter only uses empty tags if no content // (not even empty content) was written.
DBG_ASSERT(XML_TOKEN_INVALID != eElementName, "invalid element name!"); if (XML_TOKEN_INVALID != eElementName)
{ // Element
SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_TEXT,
eElementName, bAddSpace, bAddSpace );
} // else: ignore
}
// if the ScriptURL property is not empty then this is a Scripting // Framework URL, otherwise treat it as a Basic Macro if (!sName.isEmpty())
{
OUString sScript( u"Script"_ustr );
aSeq = Sequence<PropertyValue>
{
comphelper::makePropertyValue(sEventType, sScript),
comphelper::makePropertyValue(sScript, sName)
};
} else
{
aSeq = Sequence<PropertyValue>
{
comphelper::makePropertyValue(sEventType, u"StarBasic"_ustr),
comphelper::makePropertyValue(u"Library"_ustr, rPropSet->getPropertyValue( u"MacroLibrary"_ustr )),
comphelper::makePropertyValue(u"MacroName"_ustr, rPropSet->getPropertyValue( u"MacroName"_ustr ))
};
}
// 2) export the sequence
GetExport().GetEventExport().ExportSingleEvent( aSeq, u"OnClick"_ustr, false );
// and finally, the field presentation
GetExport().Characters(rContent);
}
void XMLTextFieldExport::ExportMetaField( const Reference<XPropertySet> & i_xMeta, bool i_bAutoStyles, bool i_bProgress, bool & rPrevCharIsSpace)
{ bool doExport(!i_bAutoStyles); // do not export element if autostyles // check version >= 1.2 switch (GetExport().getSaneDefaultVersion()) { case SvtSaveOptions::ODFSVER_011: // fall through case SvtSaveOptions::ODFSVER_010: doExport = false; break; default: break;
}
DBG_ASSERT(bExportValueType || !bExportValue, "value w/o value type not supported!");
// take care of illegal formats // (shouldn't happen, but does if document is corrupted) if (-1 != nFormatKey)
{ if (bExportValue || bExportValueType)
{
XMLNumberFormatAttributesExportHelper::
SetNumberFormatAttributes(
GetExport(), nFormatKey, fValue, bExportValue);
}
if (bExportStyle)
{ // don't export language (if desired) if( bForceSystemLanguage )
nFormatKey =
GetExport().dataStyleForceSystemLanguage( nFormatKey );
OUString sDataStyleName =
GetExport().getDataStyleName(nFormatKey, bTimeStyle); if( !sDataStyleName.isEmpty() )
{
GetExport().AddAttribute( XML_NAMESPACE_STYLE,
XML_DATA_STYLE_NAME,
sDataStyleName );
} // else: ignore (no valid number format)
} // else: ignore (no number format)
}
}
}
/// process display related properties void XMLTextFieldExport::ProcessDisplay(bool bIsVisible, bool bIsCommand)
{ enum XMLTokenEnum eValue;
/// export a string as a sequence of paragraphs void XMLTextFieldExport::ProcessParagraphSequence(
std::u16string_view sParagraphSequence)
{ // iterate over all string-pieces separated by return (0x0a) and // put each inside a paragraph element.
SvXMLTokenEnumerator aEnumerator(sParagraphSequence, char(0x0a));
std::u16string_view aSubString; while (aEnumerator.getNextToken(aSubString))
{
SvXMLElementExport aParagraph(
GetExport(), XML_NAMESPACE_TEXT, XML_P, true, false);
GetExport().Characters(OUString(aSubString));
}
}
// export an integer attribute void XMLTextFieldExport::ProcessInteger(enum XMLTokenEnum eName,
sal_Int32 nNum)
{
SAL_WARN_IF( eName == XML_TOKEN_INVALID, "xmloff.text", "invalid element token"); if ( XML_TOKEN_INVALID == eName ) return;
/// export an integer attribute, omit if default void XMLTextFieldExport::ProcessIntegerDef(enum XMLTokenEnum eName,
sal_Int32 nNum, sal_Int32 nDefault)
{ if (nNum != nDefault)
ProcessInteger(eName, nNum);
}
/// export a numbering type void XMLTextFieldExport::ProcessNumberingType(sal_Int16 nNumberingType)
{ // process only if real format (not: like page descriptor) if (NumberingType::PAGE_DESCRIPTOR == nNumberingType) return;
OUStringBuffer sTmp( 10 ); // number type: num format
GetExport().GetMM100UnitConverter().convertNumFormat( sTmp,
nNumberingType );
GetExport().AddAttribute(XML_NAMESPACE_STYLE, XML_NUM_FORMAT,
sTmp.makeStringAndClear() ); // and letter sync, if applicable
SvXMLUnitConverter::convertNumLetterSync( sTmp, nNumberingType );
if (!sTmp.isEmpty())
{
GetExport().AddAttribute(XML_NAMESPACE_STYLE, XML_NUM_LETTER_SYNC,
sTmp.makeStringAndClear() );
} // else: like page descriptor => ignore
}
/// export a date, time, or duration void XMLTextFieldExport::ProcessDateTime(enum XMLTokenEnum eName, double dValue, bool bIsDate, bool bIsDuration, bool bOmitDurationIfZero,
sal_uInt16 nPrefix)
{ // truncate for date granularity if (bIsDate)
{
dValue = ::rtl::math::approxFloor(dValue);
}
OUStringBuffer aBuffer; if (bIsDuration)
{ // date/time duration handle bOmitDurationIfZero if (!bOmitDurationIfZero || dValue != 0.0)
{
::sax::Converter::convertDuration(aBuffer, dValue);
}
} else
{ // date/time value
rExport.GetMM100UnitConverter().convertDateTime(aBuffer, dValue);
}
// explode a field master name into field type and field name void XMLTextFieldExport::ExplodeFieldMasterName(
std::u16string_view sMasterName, OUString& sFieldType, OUString& sVarName)
{
sal_Int32 nLength = gsFieldMasterPrefix.getLength();
size_t nSeparator = sMasterName.find('.', nLength);
// '.' found? if (nSeparator == o3tl::make_unsigned(nLength) || nSeparator == std::u16string_view::npos) {
SAL_WARN("xmloff.text", "no field var name!");
} else
{
sFieldType = sMasterName.substr(nLength, nSeparator-nLength);
sVarName = sMasterName.substr(nSeparator+1);
}
}
// for XDependentTextFields, get PropertySet of FieldMaster
Reference<XPropertySet> XMLTextFieldExport::GetMasterPropertySet( const Reference<XTextField> & rTextField)
{ // name, value => get Property set of TextFieldMaster
Reference<XDependentTextField> xDep(rTextField, UNO_QUERY); return xDep->getTextFieldMaster();
}
// get PropertySet of (any; the first) dependent field bool XMLTextFieldExport::GetDependentFieldPropertySet( const Reference<XPropertySet> & xMaster,
Reference<XPropertySet> & xField)
{
Any aAny;
Sequence<Reference<XDependentTextField> > aFields;
aAny = xMaster->getPropertyValue(gsPropertyDependentTextFields);
aAny >>= aFields;
// any fields? if (aFields.hasElements())
{ // get first one and return const Reference<XDependentTextField>& xTField = aFields[0];
xField.set(xTField, UNO_QUERY);
DBG_ASSERT(xField.is(), "Surprisingly, this TextField refuses to be a PropertySet!"); returntrue;
} else
{ returnfalse;
}
}
switch (ePage)
{ case PageNumberType_PREV:
eName = XML_PREVIOUS;
nOffset += 1; break; case PageNumberType_CURRENT:
eName = XML_CURRENT; break; case PageNumberType_NEXT:
eName = XML_NEXT;
nOffset -= 1; break; default:
OSL_FAIL("unknown page number type");
eName = XML_TOKEN_INVALID; break;
}
return eName;
}
/// map TemplateDisplayFormat to XML enum XMLTokenEnum XMLTextFieldExport::MapTemplateDisplayFormat(sal_Int16 nFormat)
{ enum XMLTokenEnum eName = XML_TOKEN_INVALID;
switch (nFormat)
{ case TemplateDisplayFormat::FULL:
eName = XML_FULL; break; case TemplateDisplayFormat::PATH:
eName = XML_PATH; break; case TemplateDisplayFormat::NAME:
eName = XML_NAME; break; case TemplateDisplayFormat::NAME_AND_EXT:
eName = XML_NAME_AND_EXTENSION; break; case TemplateDisplayFormat::AREA:
eName = XML_AREA; break; case TemplateDisplayFormat::TITLE:
eName = XML_TITLE; break; default:
OSL_FAIL("unknown template display format");
eName = XML_TOKEN_INVALID; break;
}
return eName;
}
/// map count/statistics field token to XML name enum XMLTokenEnum XMLTextFieldExport::MapCountFieldName(FieldIdEnum nToken)
{ enum XMLTokenEnum eElement = XML_TOKEN_INVALID;
switch (nToken)
{ case FIELD_ID_COUNT_PAGES:
eElement = XML_PAGE_COUNT; break; case FIELD_ID_COUNT_PAGES_RANGE:
eElement = XML_PAGE_COUNT_RANGE; break; case FIELD_ID_COUNT_PARAGRAPHS:
eElement = XML_PARAGRAPH_COUNT; break; case FIELD_ID_COUNT_WORDS:
eElement = XML_WORD_COUNT; break; case FIELD_ID_COUNT_CHARACTERS:
eElement = XML_CHARACTER_COUNT; break; case FIELD_ID_COUNT_TABLES:
eElement = XML_TABLE_COUNT; break; case FIELD_ID_COUNT_GRAPHICS:
eElement = XML_IMAGE_COUNT; break; case FIELD_ID_COUNT_OBJECTS:
eElement = XML_OBJECT_COUNT; break; default:
OSL_FAIL("no count field token");
eElement = XML_TOKEN_INVALID; break;
}
return eElement;
}
/// map ChapterDisplayFormat to XML string enum XMLTokenEnum XMLTextFieldExport::MapChapterDisplayFormat(sal_Int16 nFormat)
{ enum XMLTokenEnum eName = XML_TOKEN_INVALID;
switch (nFormat)
{ case ChapterFormat::NAME:
eName = XML_NAME; break; case ChapterFormat::NUMBER:
eName = XML_NUMBER; break; case ChapterFormat::NAME_NUMBER:
eName = XML_NUMBER_AND_NAME; break; case ChapterFormat::NO_PREFIX_SUFFIX:
eName = XML_PLAIN_NUMBER_AND_NAME; break; case ChapterFormat::DIGIT:
eName = XML_PLAIN_NUMBER; break; default:
OSL_FAIL("unknown chapter display format");
eName = XML_TOKEN_INVALID; break;
}
return eName;
}
/// map FilenameDisplayFormat to XML attribute names enum XMLTokenEnum XMLTextFieldExport::MapFilenameDisplayFormat(sal_Int16 nFormat)
{ enum XMLTokenEnum eName = XML_TOKEN_INVALID;
switch (nFormat)
{ case FilenameDisplayFormat::FULL:
eName = XML_FULL; break; case FilenameDisplayFormat::PATH:
eName = XML_PATH; break; case FilenameDisplayFormat::NAME:
eName = XML_NAME; break; case FilenameDisplayFormat::NAME_AND_EXT:
eName = XML_NAME_AND_EXTENSION; break; default:
OSL_FAIL("unknown filename display format");
}
return eName;
}
/// map ReferenceFieldPart to XML string enum XMLTokenEnum XMLTextFieldExport::MapReferenceType(sal_Int16 nType)
{ enum XMLTokenEnum eElement = XML_TOKEN_INVALID;
switch (nType)
{ case ReferenceFieldPart::PAGE:
eElement = XML_PAGE; break; case ReferenceFieldPart::CHAPTER:
eElement = XML_CHAPTER; break; case ReferenceFieldPart::TEXT:
eElement = XML_TEXT; break; case ReferenceFieldPart::UP_DOWN:
eElement = XML_DIRECTION; break; case ReferenceFieldPart::CATEGORY_AND_NUMBER:
eElement = XML_CATEGORY_AND_VALUE; break; case ReferenceFieldPart::ONLY_CAPTION:
eElement = XML_CAPTION; break; case ReferenceFieldPart::ONLY_SEQUENCE_NUMBER:
eElement = XML_VALUE; break; case ReferenceFieldPart::PAGE_DESC: // small hack: this value never gets written, because // XML_TEMPLATE is default
eElement = XML_TEMPLATE; break; // Core implementation for direct cross-references (#i81002#) case ReferenceFieldPart::NUMBER:
eElement = XML_NUMBER; break; case ReferenceFieldPart::NUMBER_NO_CONTEXT:
eElement = XML_NUMBER_NO_SUPERIOR; break; case ReferenceFieldPart::NUMBER_FULL_CONTEXT:
eElement = XML_NUMBER_ALL_SUPERIOR; break; default:
OSL_FAIL("unknown reference type");
eElement = XML_TEMPLATE; break;
}
return eElement;
}
/// map ReferenceFieldPart to XML string enum XMLTokenEnum XMLTextFieldExport::MapReferenceSource(sal_Int16 nType)
{ enum XMLTokenEnum eElement = XML_TOKEN_INVALID;
switch (nType)
{ case ReferenceFieldSource::REFERENCE_MARK:
eElement = XML_REFERENCE_REF; break; case ReferenceFieldSource::SEQUENCE_FIELD:
eElement = XML_SEQUENCE_REF; break; case ReferenceFieldSource::BOOKMARK:
eElement = XML_BOOKMARK_REF; break; case ReferenceFieldSource::FOOTNOTE: case ReferenceFieldSource::ENDNOTE:
eElement = XML_NOTE_REF; break; case ReferenceFieldSource::STYLE:
eElement = XML_STYLE_REF; break; default:
OSL_FAIL("unknown reference source"); break;
}
return eElement;
}
/// element name for sender fields enum XMLTokenEnum XMLTextFieldExport::MapSenderFieldName( const Reference<XPropertySet> & xPropSet)
{ enum XMLTokenEnum eName = XML_TOKEN_INVALID;
// sub-field type switch (GetInt16Property(gsPropertyFieldSubType, xPropSet))
{ case UserDataPart::COMPANY :
eName = XML_SENDER_COMPANY; break; case UserDataPart::FIRSTNAME :
eName = XML_SENDER_FIRSTNAME; break; case UserDataPart::NAME :
eName = XML_SENDER_LASTNAME; break; case UserDataPart::SHORTCUT :
eName = XML_SENDER_INITIALS; break; case UserDataPart::STREET :
eName = XML_SENDER_STREET; break; case UserDataPart::COUNTRY :
eName = XML_SENDER_COUNTRY; break; case UserDataPart::ZIP :
eName = XML_SENDER_POSTAL_CODE; break; case UserDataPart::CITY :
eName = XML_SENDER_CITY; break; case UserDataPart::TITLE :
eName = XML_SENDER_TITLE; break; case UserDataPart::POSITION :
eName = XML_SENDER_POSITION; break; case UserDataPart::PHONE_PRIVATE :
eName = XML_SENDER_PHONE_PRIVATE; break; case UserDataPart::PHONE_COMPANY :
eName = XML_SENDER_PHONE_WORK; break; case UserDataPart::FAX :
eName = XML_SENDER_FAX; break; case UserDataPart::EMAIL :
eName = XML_SENDER_EMAIL; break; case UserDataPart::STATE :
eName = XML_SENDER_STATE_OR_PROVINCE; break; default:
SAL_WARN("xmloff.text", "unknown sender type");
eName = XML_TOKEN_INVALID; break;
}
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.