/* -*- 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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 & 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 xPropSet; if (CreateField(xPropSet, sServicePrefix + GetServiceName())) { // set field properties PrepareField(xPropSet); // attach field to document Reference 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 & xField, const OUString& rServiceName) { // instantiate new XTextField: // ask import for model, model is factory, ask factory to create service Reference xFactory(GetImport().GetModel(),UNO_QUERY); if( xFactory.is() ) { Reference xIfc = xFactory->createInstance(rServiceName); if( xIfc.is() ) { Reference xTmp( xIfc, UNO_QUERY ); xField = xTmp; } 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): 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 & rPropertySet) { // force update Reference 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, "ExtendedUser") , nSubType(0) , sPropertyFixed(sAPI_is_fixed) , sPropertyContent(sAPI_content) , bFixed(true) { } void XMLSenderFieldImportContext::startFastElement( sal_Int32 nElement, const Reference & 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 & 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 & xAttrList) { bAuthorFullName = ( XML_ELEMENT(TEXT, XML_AUTHOR_INITIALS) != nElement); bValid = true; // process Attributes XMLTextFieldImportContext::startFastElement(nElement, xAttrList); } void XMLAuthorFieldImportContext::ProcessAttribute(sal_Int32 nAttrToken, std::string_view sAttrValue) { if(nAttrToken == XML_ELEMENT(TEXT, XML_FIXED)) { bool bTmp(false); if (::sax::Converter::convertBool(bTmp, sAttrValue)) bFixed = bTmp; } else XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue); } void XMLAuthorFieldImportContext::PrepareField( const Reference & 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 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) { 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(nTmp); } break; } default: XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue); } } void XMLPageNumberImportContext::PrepareField( const Reference & xPropertySet) { // all properties are optional Reference 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, "JumpEdit") , 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) { 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(::rtl::math::approxFloor(fTmp * 60 * 24)); } break; } default: XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue); } } void XMLTimeFieldImportContext::PrepareField( const Reference & rPropertySet) { // all properties are optional (except IsDate) Reference 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->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, "DatabaseName", 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, "DatabaseNextSet", 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) { 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, "DatabaseNumberOfSet"), 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->setPropertyValue(sPropertySetNumber, Any(nNumber)); XMLDatabaseNextImportContext::PrepareField(xPropertySet); } // database display row number field XMLDatabaseNumberImportContext::XMLDatabaseNumberImportContext( SvXMLImport& rImport, XMLTextImportHelper& rHlp) : XMLDatabaseFieldImportContext(rImport, rHlp, "DatabaseSetNumber", true), sPropertyNumberingType( sAPI_numbering_type), sPropertySetNumber(sAPI_set_number), sNumberFormat("1"), 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) { 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 & rPropertySet) { // title field in Calc has no Fixed property Reference 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 & 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) { // 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 & xPropertySet) { if ( !aName.isEmpty() ) { xPropertySet->setPropertyValue(sPropertyName, Any(aName)); } Reference 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, "HiddenParagraph"), 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->setPropertyValue(sPropertyCondition, Any(sCondition)); xPropertySet->setPropertyValue(sPropertyIsHidden, Any(bIsHidden)); } // import 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, "ConditionalText"), 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->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, "HiddenText"), 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->setPropertyValue(sPropertyCondition, Any(sCondition)); xPropertySet->setPropertyValue(sPropertyContent, Any(sString)); xPropertySet->setPropertyValue(sPropertyIsHidden, Any(bIsHidden)); } // file name fields const SvXMLEnumMapEntry 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, "FileName"), 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) { // properties are optional Reference 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 aTemplateDisplayMap[] = { { XML_FULL, TemplateDisplayFormat::FULL }, { XML_PATH, TemplateDisplayFormat::PATH }, { XML_NAME, TemplateDisplayFormat::NAME }, { XML_NAME_AND_EXTENSION, TemplateDisplayFormat::NAME_AND_EXT }, { XML_AREA, TemplateDisplayFormat::AREA }, { XML_TITLE, TemplateDisplayFormat::TITLE }, { XML_TOKEN_INVALID, 0 } }; XMLTemplateNameImportContext::XMLTemplateNameImportContext( SvXMLImport& rImport, XMLTextImportHelper& rHlp) : XMLTextFieldImportContext(rImport, rHlp, "TemplateName"), sPropertyFileFormat(sAPI_file_format), nFormat(TemplateDisplayFormat::FULL) { bValid = true; } void XMLTemplateNameImportContext::ProcessAttribute( sal_Int32 nAttrToken, std::string_view sAttrValue ) { switch (nAttrToken) { case XML_ELEMENT(TEXT, XML_DISPLAY): { sal_uInt16 nTmp; if (SvXMLUnitConverter::convertEnum(nTmp, sAttrValue, aTemplateDisplayMap)) { nFormat = nTmp; } break; } default: // unknown attribute: ignore XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue); break; } } void XMLTemplateNameImportContext::PrepareField( const Reference & xPropertySet) { xPropertySet->setPropertyValue(sPropertyFileFormat, Any(nFormat)); } // import chapter fields const SvXMLEnumMapEntry aChapterDisplayMap[] = { { XML_NAME, ChapterFormat::NAME }, { XML_NUMBER, ChapterFormat::NUMBER }, { XML_NUMBER_AND_NAME, ChapterFormat::NAME_NUMBER }, { XML_PLAIN_NUMBER_AND_NAME, ChapterFormat::NO_PREFIX_SUFFIX }, { XML_PLAIN_NUMBER, ChapterFormat::DIGIT }, { XML_TOKEN_INVALID, 0 } }; constexpr OUStringLiteral gsPropertyChapterFormat(u"ChapterFormat"); constexpr OUStringLiteral gsPropertyLevel(u"Level"); XMLChapterImportContext::XMLChapterImportContext( SvXMLImport& rImport, XMLTextImportHelper& rHlp) : XMLTextFieldImportContext(rImport, rHlp, "Chapter"), nFormat(ChapterFormat::NAME_NUMBER), nLevel(0) { bValid = true; } void XMLChapterImportContext::ProcessAttribute( sal_Int32 nAttrToken, std::string_view sAttrValue ) { switch (nAttrToken) { case XML_ELEMENT(TEXT, XML_DISPLAY): { sal_uInt16 nTmp; if (SvXMLUnitConverter::convertEnum(nTmp, sAttrValue, aChapterDisplayMap)) { nFormat = static_cast(nTmp); } break; } case XML_ELEMENT(TEXT, XML_OUTLINE_LEVEL): { sal_Int32 nTmp; if (::sax::Converter::convertNumber( nTmp, sAttrValue, 1, GetImport().GetTextImport()->GetChapterNumbering()->getCount() )) { // API numbers 0..9, we number 1..10 nLevel = static_cast(nTmp); nLevel--; } break; } default: // unknown attribute: ignore XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue); break; } } void XMLChapterImportContext::PrepareField( const Reference & xPropertySet) { xPropertySet->setPropertyValue(gsPropertyChapterFormat, Any(nFormat)); xPropertySet->setPropertyValue(gsPropertyLevel, Any(nLevel)); } // counting fields XMLCountFieldImportContext::XMLCountFieldImportContext( SvXMLImport& rImport, XMLTextImportHelper& rHlp, sal_Int32 nElement) : XMLTextFieldImportContext(rImport, rHlp, MapTokenToServiceName(nElement)), sPropertyNumberingType( sAPI_numbering_type), bNumberFormatOK(false) { bValid = true; } void XMLCountFieldImportContext::ProcessAttribute( sal_Int32 nAttrToken, std::string_view sAttrValue ) { switch (nAttrToken) { case XML_ELEMENT(STYLE, XML_NUM_FORMAT): sNumberFormat = OUString::fromUtf8(sAttrValue); bNumberFormatOK = true; break; case XML_ELEMENT(STYLE, XML_NUM_LETTER_SYNC): sLetterSync = OUString::fromUtf8(sAttrValue); break; default: XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue); } } void XMLCountFieldImportContext::PrepareField( const Reference & xPropertySet) { // properties optional // (only page count, but do for all to save common implementation) if (!xPropertySet->getPropertySetInfo()-> hasPropertyByName(sPropertyNumberingType)) return; sal_Int16 nNumType; if( bNumberFormatOK ) { nNumType= style::NumberingType::ARABIC; GetImport().GetMM100UnitConverter().convertNumFormat( nNumType, sNumberFormat, sLetterSync ); } else nNumType = style::NumberingType::PAGE_DESCRIPTOR; xPropertySet->setPropertyValue(sPropertyNumberingType, Any(nNumType)); } OUString XMLCountFieldImportContext::MapTokenToServiceName( sal_Int32 nElement) { OUString pServiceName; switch (nElement) { case XML_ELEMENT(TEXT, XML_WORD_COUNT): pServiceName = "WordCount"; break; case XML_ELEMENT(TEXT, XML_PARAGRAPH_COUNT): pServiceName = "ParagraphCount"; break; case XML_ELEMENT(TEXT, XML_TABLE_COUNT): pServiceName = "TableCount"; break; case XML_ELEMENT(TEXT, XML_CHARACTER_COUNT): pServiceName = "CharacterCount"; break; case XML_ELEMENT(TEXT, XML_IMAGE_COUNT): pServiceName = "GraphicObjectCount"; break; case XML_ELEMENT(TEXT, XML_OBJECT_COUNT): pServiceName = "EmbeddedObjectCount"; break; case XML_ELEMENT(TEXT, XML_PAGE_COUNT): pServiceName = "PageCount"; break; default: XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement); assert(false); } return pServiceName; } // page variable import XMLPageVarGetFieldImportContext::XMLPageVarGetFieldImportContext( SvXMLImport& rImport, XMLTextImportHelper& rHlp) : XMLTextFieldImportContext(rImport, rHlp, "ReferencePageGet"), bNumberFormatOK(false) { bValid = true; } void XMLPageVarGetFieldImportContext::ProcessAttribute( sal_Int32 nAttrToken, std::string_view sAttrValue ) { switch (nAttrToken) { case XML_ELEMENT(STYLE, XML_NUM_FORMAT): sNumberFormat = OUString::fromUtf8(sAttrValue); bNumberFormatOK = true; break; case XML_ELEMENT(STYLE, XML_NUM_LETTER_SYNC): sLetterSync = OUString::fromUtf8(sAttrValue); break; default: XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue); } } void XMLPageVarGetFieldImportContext::PrepareField( const Reference & xPropertySet) { sal_Int16 nNumType; if( bNumberFormatOK ) { nNumType= style::NumberingType::ARABIC; GetImport().GetMM100UnitConverter().convertNumFormat( nNumType, sNumberFormat, sLetterSync ); } else nNumType = style::NumberingType::PAGE_DESCRIPTOR; xPropertySet->setPropertyValue(sAPI_numbering_type, Any(nNumType)); // display old content (#96657#) xPropertySet->setPropertyValue( sAPI_current_presentation, Any(GetContent()) ); } // page variable set fields XMLPageVarSetFieldImportContext::XMLPageVarSetFieldImportContext( SvXMLImport& rImport, XMLTextImportHelper& rHlp) : XMLTextFieldImportContext(rImport, rHlp, "ReferencePageSet"), nAdjust(0), bActive(true) { bValid = true; } void XMLPageVarSetFieldImportContext::ProcessAttribute( sal_Int32 nAttrToken, std::string_view sAttrValue ) { switch (nAttrToken) { case XML_ELEMENT(TEXT, XML_ACTIVE): { bool bTmp(false); if (::sax::Converter::convertBool(bTmp, sAttrValue)) { bActive = bTmp; } break; } case XML_ELEMENT(TEXT, XML_PAGE_ADJUST): { sal_Int32 nTmp(0); if (::sax::Converter::convertNumber(nTmp, sAttrValue)) { nAdjust = static_cast(nTmp); } break; } default: XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue); break; } } void XMLPageVarSetFieldImportContext::PrepareField( const Reference & xPropertySet) { xPropertySet->setPropertyValue("On", Any(bActive)); xPropertySet->setPropertyValue(sAPI_offset, Any(nAdjust)); } // macro fields XMLMacroFieldImportContext::XMLMacroFieldImportContext( SvXMLImport& rImport, XMLTextImportHelper& rHlp) : XMLTextFieldImportContext(rImport, rHlp, "Macro"), bDescriptionOK(false) { } css::uno::Reference< css::xml::sax::XFastContextHandler > XMLMacroFieldImportContext::createFastChildContext( sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& ) { if ( nElement == XML_ELEMENT(OFFICE, XML_EVENT_LISTENERS) ) { // create events context and remember it! xEventContext = new XMLEventsImportContext( GetImport() ); bValid = true; return xEventContext; } XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement); return nullptr; } void XMLMacroFieldImportContext::ProcessAttribute( sal_Int32 nAttrToken, std::string_view sAttrValue ) { switch (nAttrToken) { case XML_ELEMENT(TEXT, XML_DESCRIPTION): sDescription = OUString::fromUtf8(sAttrValue); bDescriptionOK = true; break; case XML_ELEMENT(TEXT, XML_NAME): sMacro = OUString::fromUtf8(sAttrValue); bValid = true; break; default: XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue); } } void XMLMacroFieldImportContext::PrepareField( const Reference & xPropertySet) { Any aAny; aAny <<= (bDescriptionOK ? sDescription : GetContent()); xPropertySet->setPropertyValue(sAPI_hint, aAny); // if we have an events child element, we'll look for the OnClick // event if not, it may be an old (pre-638i) document. Then, we'll // have to look at the name attribute. OUString sMacroName; OUString sLibraryName; OUString sScriptURL; if ( xEventContext.is() ) { // get event sequence XMLEventsImportContext* pEvents = xEventContext.get(); Sequence aValues; pEvents->GetEventSequence( "OnClick", aValues ); for( const auto& rValue : std::as_const(aValues) ) { if ( rValue.Name == "ScriptType" ) { // ignore ScriptType } else if ( rValue.Name == "Library" ) { rValue.Value >>= sLibraryName; } else if ( rValue.Name == "MacroName" ) { rValue.Value >>= sMacroName; } if ( rValue.Name == "Script" ) { rValue.Value >>= sScriptURL; } } } else { // disassemble old-style macro-name: Everything before the // third-last dot is the library sal_Int32 nPos = sMacro.getLength() + 1; // the loop starts with nPos-- const sal_Unicode* pBuf = sMacro.getStr(); for( sal_Int32 i = 0; (i < 3) && (nPos > 0); i++ ) { nPos--; while ( (pBuf[nPos] != '.') && (nPos > 0) ) nPos--; } if (nPos > 0) { sLibraryName = sMacro.copy(0, nPos); sMacroName = sMacro.copy(nPos+1); } else sMacroName = sMacro; } xPropertySet->setPropertyValue("ScriptURL", Any(sScriptURL)); xPropertySet->setPropertyValue("MacroName", Any(sMacroName)); xPropertySet->setPropertyValue("MacroLibrary", Any(sLibraryName)); } // reference field import XMLReferenceFieldImportContext::XMLReferenceFieldImportContext( SvXMLImport& rImport, XMLTextImportHelper& rHlp, sal_Int32 nToken) : XMLTextFieldImportContext(rImport, rHlp, "GetReference") , nElementToken(nToken) , nSource(0) , nType(ReferenceFieldPart::PAGE_DESC) , nFlags(0) , bNameOK(false) , bTypeOK(false) { } SvXMLEnumMapEntry const lcl_aReferenceTypeTokenMap[] = { { XML_PAGE, ReferenceFieldPart::PAGE}, { XML_CHAPTER, ReferenceFieldPart::CHAPTER }, { XML_TEXT, ReferenceFieldPart::TEXT }, { XML_DIRECTION, ReferenceFieldPart::UP_DOWN }, { XML_CATEGORY_AND_VALUE, ReferenceFieldPart::CATEGORY_AND_NUMBER }, { XML_CAPTION, ReferenceFieldPart::ONLY_CAPTION }, { XML_VALUE, ReferenceFieldPart::ONLY_SEQUENCE_NUMBER }, // Core implementation for direct cross-references (#i81002#) { XML_NUMBER, ReferenceFieldPart::NUMBER }, { XML_NUMBER_NO_SUPERIOR, ReferenceFieldPart::NUMBER_NO_CONTEXT }, { XML_NUMBER_ALL_SUPERIOR, ReferenceFieldPart::NUMBER_FULL_CONTEXT }, { XML_TOKEN_INVALID, 0 } }; void XMLReferenceFieldImportContext::startFastElement( sal_Int32 nElement, const Reference & xAttrList) { bTypeOK = true; switch (nElementToken) { case XML_ELEMENT(TEXT, XML_REFERENCE_REF): nSource = ReferenceFieldSource::REFERENCE_MARK; break; case XML_ELEMENT(TEXT, XML_BOOKMARK_REF): nSource = ReferenceFieldSource::BOOKMARK; break; case XML_ELEMENT(TEXT, XML_NOTE_REF): nSource = ReferenceFieldSource::FOOTNOTE; break; case XML_ELEMENT(TEXT, XML_SEQUENCE_REF): nSource = ReferenceFieldSource::SEQUENCE_FIELD; break; case XML_ELEMENT(TEXT, XML_STYLE_REF): case XML_ELEMENT(LO_EXT, XML_STYLE_REF): nSource = ReferenceFieldSource::STYLE; break; default: XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElementToken); bTypeOK = false; break; } XMLTextFieldImportContext::startFastElement(nElement, xAttrList); } void XMLReferenceFieldImportContext::ProcessAttribute( sal_Int32 nAttrToken, std::string_view sAttrValue ) { switch (nAttrToken) { case XML_ELEMENT(TEXT, XML_NOTE_CLASS): if( IsXMLToken( sAttrValue, XML_ENDNOTE ) ) nSource = ReferenceFieldSource::ENDNOTE; break; case XML_ELEMENT(TEXT, XML_REF_NAME): sName = OUString::fromUtf8(sAttrValue); bNameOK = true; break; case XML_ELEMENT(TEXT, XML_REFERENCE_FORMAT): { sal_uInt16 nToken; if (SvXMLUnitConverter::convertEnum(nToken, sAttrValue, lcl_aReferenceTypeTokenMap)) { nType = nToken; } // check for sequence-only-attributes if ( (XML_ELEMENT(TEXT, XML_SEQUENCE_REF) != nElementToken) && ( (nType == ReferenceFieldPart::CATEGORY_AND_NUMBER) || (nType == ReferenceFieldPart::ONLY_CAPTION) || (nType == ReferenceFieldPart::ONLY_SEQUENCE_NUMBER) ) ) { nType = ReferenceFieldPart::PAGE_DESC; } break; } case XML_ELEMENT(LO_EXT, XML_REFERENCE_LANGUAGE): case XML_ELEMENT(TEXT, XML_REFERENCE_LANGUAGE): sLanguage = OUString::fromUtf8(sAttrValue); break; case XML_ELEMENT(LO_EXT, XML_REFERENCE_HIDE_NON_NUMERICAL): case XML_ELEMENT(TEXT, XML_REFERENCE_HIDE_NON_NUMERICAL): if (OUString::fromUtf8(sAttrValue).toBoolean()) nFlags |= REFFLDFLAG_STYLE_HIDE_NON_NUMERICAL; break; case XML_ELEMENT(LO_EXT, XML_REFERENCE_FROM_BOTTOM): case XML_ELEMENT(TEXT, XML_REFERENCE_FROM_BOTTOM): if (OUString::fromUtf8(sAttrValue).toBoolean()) nFlags |= REFFLDFLAG_STYLE_FROM_BOTTOM; break; default: XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue); } // bValid: we need proper element type and name bValid = bTypeOK && bNameOK; } void XMLReferenceFieldImportContext::PrepareField( const Reference & xPropertySet) { xPropertySet->setPropertyValue("ReferenceFieldPart", Any(nType)); xPropertySet->setPropertyValue("ReferenceFieldSource", Any(nSource)); xPropertySet->setPropertyValue("ReferenceFieldLanguage", Any(sLanguage)); switch (nElementToken) { case XML_ELEMENT(TEXT, XML_REFERENCE_REF): case XML_ELEMENT(TEXT, XML_BOOKMARK_REF): case XML_ELEMENT(TEXT, XML_STYLE_REF): case XML_ELEMENT(LO_EXT, XML_STYLE_REF): xPropertySet->setPropertyValue("SourceName", Any(sName)); xPropertySet->setPropertyValue("ReferenceFieldFlags", Any(nFlags)); break; case XML_ELEMENT(TEXT, XML_NOTE_REF): GetImportHelper().ProcessFootnoteReference(sName, xPropertySet); break; case XML_ELEMENT(TEXT, XML_SEQUENCE_REF): GetImportHelper().ProcessSequenceReference(sName, xPropertySet); break; } xPropertySet->setPropertyValue(sAPI_current_presentation, Any(GetContent())); } // field declarations container XMLDdeFieldDeclsImportContext::XMLDdeFieldDeclsImportContext(SvXMLImport& rImport) : SvXMLImportContext(rImport) { } css::uno::Reference< css::xml::sax::XFastContextHandler > XMLDdeFieldDeclsImportContext::createFastChildContext( sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& ) { if ( nElement == XML_ELEMENT(TEXT, XML_DDE_CONNECTION_DECL) ) { return new XMLDdeFieldDeclImportContext(GetImport()); } else XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement); return nullptr; } // import dde field declaration XMLDdeFieldDeclImportContext::XMLDdeFieldDeclImportContext(SvXMLImport& rImport) : SvXMLImportContext(rImport) { } void XMLDdeFieldDeclImportContext::startFastElement( sal_Int32 /*nElement*/, const Reference & xAttrList) { OUString sName; OUString sCommandApplication; OUString sCommandTopic; OUString sCommandItem; bool bUpdate = false; bool bNameOK = false; bool bCommandApplicationOK = false; bool bCommandTopicOK = false; bool bCommandItemOK = false; // process attributes for( auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ) ) { switch (aIter.getToken()) { case XML_ELEMENT(OFFICE, XML_NAME): sName = aIter.toString(); bNameOK = true; break; case XML_ELEMENT(OFFICE, XML_DDE_APPLICATION): sCommandApplication = aIter.toString(); bCommandApplicationOK = true; break; case XML_ELEMENT(OFFICE, XML_DDE_TOPIC): sCommandTopic = aIter.toString(); bCommandTopicOK = true; break; case XML_ELEMENT(OFFICE, XML_DDE_ITEM): sCommandItem = aIter.toString(); bCommandItemOK = true; break; case XML_ELEMENT(OFFICE, XML_AUTOMATIC_UPDATE): { bool bTmp(false); if (::sax::Converter::convertBool(bTmp, aIter.toView()) ) { bUpdate = bTmp; } break; } default: XMLOFF_WARN_UNKNOWN("xmloff", aIter); } } // valid data? if (!(bNameOK && bCommandApplicationOK && bCommandTopicOK && bCommandItemOK)) return; // create DDE TextFieldMaster Reference xFactory(GetImport().GetModel(), UNO_QUERY); if( !xFactory.is() ) return; /* #i6432# There might be multiple occurrences of one DDE declaration if it is used in more than one of header/footer/body. createInstance will throw an exception if we try to create the second, third, etc. instance of such a declaration. Thus we ignore the exception. Otherwise this will lead to an unloadable document. */ try { Reference xIfc = xFactory->createInstance(OUString::Concat(sAPI_fieldmaster_prefix) + sAPI_dde); if( xIfc.is() ) { Reference xPropSet( xIfc, UNO_QUERY ); if (xPropSet.is() && xPropSet->getPropertySetInfo()->hasPropertyByName( "DDECommandType")) { xPropSet->setPropertyValue(sAPI_name, Any(sName)); xPropSet->setPropertyValue("DDECommandType", Any(sCommandApplication)); xPropSet->setPropertyValue("DDECommandFile", Any(sCommandTopic)); xPropSet->setPropertyValue("DDECommandElement", Any(sCommandItem)); xPropSet->setPropertyValue("IsAutomaticUpdate", Any(bUpdate)); } // else: ignore (can't get XPropertySet, or DDE // properties are not supported) } // else: ignore } catch (const Exception&) { //ignore } // else: ignore // else: ignore } // DDE field import XMLDdeFieldImportContext::XMLDdeFieldImportContext( SvXMLImport& rImport, XMLTextImportHelper& rHlp) : XMLTextFieldImportContext(rImport, rHlp, sAPI_dde), sPropertyContent(sAPI_content) { } void XMLDdeFieldImportContext::ProcessAttribute( sal_Int32 nAttrToken, std::string_view sAttrValue ) { if ( XML_ELEMENT(TEXT, XML_CONNECTION_NAME) == nAttrToken) { sName = OUString::fromUtf8(sAttrValue); bValid = true; } else XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue); } void XMLDdeFieldImportContext::endFastElement(sal_Int32 ) { if (!bValid) return; // find master OUString sMasterName = OUString::Concat(sAPI_fieldmaster_prefix) + sAPI_dde + "." + sName; Reference xTextFieldsSupp(GetImport().GetModel(), UNO_QUERY); Reference xFieldMasterNameAccess = xTextFieldsSupp->getTextFieldMasters(); if (!xFieldMasterNameAccess->hasByName(sMasterName)) return; Reference xMaster; Any aAny = xFieldMasterNameAccess->getByName(sMasterName); aAny >>= xMaster; //apply the content to the master xMaster->setPropertyValue( sPropertyContent, uno::Any( GetContent())); // master exists: create text field and attach Reference xField; OUString sFieldName = OUString::Concat(sAPI_textfield_prefix) + sAPI_dde; if (!CreateField(xField, sFieldName)) return; Reference xDepTextField(xField,UNO_QUERY); xDepTextField->attachTextFieldMaster(xMaster); // attach field to document Reference xTextContent(xField, UNO_QUERY); if (xTextContent.is()) { GetImportHelper().InsertTextContent(xTextContent); // we're lucky. nothing else to prepare. } // else: fail, because text content could not be created // else: fail, because field could not be created // else: fail, because no master was found (faulty document?!) // not valid: ignore } void XMLDdeFieldImportContext::PrepareField( const Reference &) { // empty, since not needed. } // sheet name fields XMLSheetNameImportContext::XMLSheetNameImportContext( SvXMLImport& rImport, XMLTextImportHelper& rHlp) : XMLTextFieldImportContext(rImport, rHlp, "SheetName") { bValid = true; // always valid! } void XMLSheetNameImportContext::ProcessAttribute( sal_Int32 nAttrToken, std::string_view sAttrValue) { // no attributes -> nothing to be done XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue); } void XMLSheetNameImportContext::PrepareField( const Reference &) { // no attributes -> nothing to be done } /** import page|slide name fields () */ XMLPageNameFieldImportContext::XMLPageNameFieldImportContext( SvXMLImport& rImport, /// XML Import XMLTextImportHelper& rHlp) /// Text import helper : XMLTextFieldImportContext(rImport, rHlp, "PageName" ) { bValid = true; } /// process attribute values void XMLPageNameFieldImportContext::ProcessAttribute( sal_Int32 nAttrToken, std::string_view sAttrValue ) { XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue); } /// prepare XTextField for insertion into document void XMLPageNameFieldImportContext::PrepareField( const css::uno::Reference &) { } // URL fields (Calc, Impress, Draw) XMLUrlFieldImportContext::XMLUrlFieldImportContext( SvXMLImport& rImport, XMLTextImportHelper& rHlp) : XMLTextFieldImportContext(rImport, rHlp, sAPI_url), bFrameOK(false) { } void XMLUrlFieldImportContext::ProcessAttribute( sal_Int32 nAttrToken, std::string_view sAttrValue ) { switch (nAttrToken) { case XML_ELEMENT(XLINK, XML_HREF): sURL = GetImport().GetAbsoluteReference( OUString::fromUtf8(sAttrValue) ); bValid = true; break; case XML_ELEMENT(OFFICE, XML_TARGET_FRAME_NAME): sFrame = OUString::fromUtf8(sAttrValue); bFrameOK = true; break; default: // ignore XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue); break; } } void XMLUrlFieldImportContext::PrepareField( const Reference & xPropertySet) { xPropertySet->setPropertyValue(sAPI_url, Any(sURL)); if (bFrameOK) { xPropertySet->setPropertyValue("TargetFrame", Any(sFrame)); } xPropertySet->setPropertyValue("Representation", Any(GetContent())); } XMLBibliographyFieldImportContext::XMLBibliographyFieldImportContext( SvXMLImport& rImport, XMLTextImportHelper& rHlp) : XMLTextFieldImportContext(rImport, rHlp, "Bibliography") { bValid = true; } // TODO: this is the same map as is used in the text field export SvXMLEnumMapEntry const aBibliographyDataTypeMap[] = { { XML_ARTICLE, BibliographyDataType::ARTICLE }, { XML_BOOK, BibliographyDataType::BOOK }, { XML_BOOKLET, BibliographyDataType::BOOKLET }, { XML_CONFERENCE, BibliographyDataType::CONFERENCE }, { XML_CUSTOM1, BibliographyDataType::CUSTOM1 }, { XML_CUSTOM2, BibliographyDataType::CUSTOM2 }, { XML_CUSTOM3, BibliographyDataType::CUSTOM3 }, { XML_CUSTOM4, BibliographyDataType::CUSTOM4 }, { XML_CUSTOM5, BibliographyDataType::CUSTOM5 }, { XML_EMAIL, BibliographyDataType::EMAIL }, { XML_INBOOK, BibliographyDataType::INBOOK }, { XML_INCOLLECTION, BibliographyDataType::INCOLLECTION }, { XML_INPROCEEDINGS, BibliographyDataType::INPROCEEDINGS }, { XML_JOURNAL, BibliographyDataType::JOURNAL }, { XML_MANUAL, BibliographyDataType::MANUAL }, { XML_MASTERSTHESIS, BibliographyDataType::MASTERSTHESIS }, { XML_MISC, BibliographyDataType::MISC }, { XML_PHDTHESIS, BibliographyDataType::PHDTHESIS }, { XML_PROCEEDINGS, BibliographyDataType::PROCEEDINGS }, { XML_TECHREPORT, BibliographyDataType::TECHREPORT }, { XML_UNPUBLISHED, BibliographyDataType::UNPUBLISHED }, { XML_WWW, BibliographyDataType::WWW }, { XML_TOKEN_INVALID, 0 } }; // we'll process attributes on our own and for fit the standard // textfield mechanism, because our attributes have zero overlap with // all the other textfields. void XMLBibliographyFieldImportContext::startFastElement( sal_Int32 /*nElement*/, const Reference & xAttrList) { // iterate over attributes for( auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ) ) { if (IsTokenInNamespace(aIter.getToken(), XML_NAMESPACE_TEXT) || IsTokenInNamespace(aIter.getToken(), XML_NAMESPACE_LO_EXT)) { auto nToken = aIter.getToken() & TOKEN_MASK; PropertyValue aValue; aValue.Name = OUString::createFromAscii( MapBibliographyFieldName(nToken)); Any aAny; // special treatment for bibliography type // biblio vs bibilio: #96658#; also read old documents if (nToken == XML_BIBILIOGRAPHIC_TYPE || nToken == XML_BIBLIOGRAPHY_TYPE ) { sal_uInt16 nTmp; if (SvXMLUnitConverter::convertEnum( nTmp, aIter.toView(), aBibliographyDataTypeMap)) { aAny <<= static_cast(nTmp); aValue.Value = aAny; aValues.push_back(aValue); } } else { OUString aStringValue = aIter.toString(); if (nToken == XML_URL || nToken == XML_LOCAL_URL || nToken == XML_TARGET_URL) { aStringValue = GetImport().GetAbsoluteReference(aStringValue); } aAny <<= aStringValue; aValue.Value = aAny; aValues.push_back(aValue); } } // else: unknown namespace -> ignore } } void XMLBibliographyFieldImportContext::ProcessAttribute( sal_Int32 , std::string_view ) { // attributes are handled in StartElement assert(false && "This should not have happened."); } void XMLBibliographyFieldImportContext::PrepareField( const Reference & xPropertySet) { // convert vector into sequence sal_Int32 nCount = aValues.size(); Sequence aValueSequence(nCount); auto aValueSequenceRange = asNonConstRange(aValueSequence); for(sal_Int32 i = 0; i < nCount; i++) { aValueSequenceRange[i] = aValues[i]; } // set sequence xPropertySet->setPropertyValue("Fields", Any(aValueSequence)); } const char* XMLBibliographyFieldImportContext::MapBibliographyFieldName( sal_Int32 nElement) { const char* pName = nullptr; switch (nElement & TOKEN_MASK) { case XML_IDENTIFIER: pName = "Identifier"; break; case XML_BIBILIOGRAPHIC_TYPE: case XML_BIBLIOGRAPHY_TYPE: // biblio... vs bibilio...: #96658#: also read old documents pName = "BibiliographicType"; break; case XML_ADDRESS: pName = "Address"; break; case XML_ANNOTE: pName = "Annote"; break; case XML_AUTHOR: pName = "Author"; break; case XML_BOOKTITLE: pName = "Booktitle"; break; case XML_CHAPTER: pName = "Chapter"; break; case XML_EDITION: pName = "Edition"; break; case XML_EDITOR: pName = "Editor"; break; case XML_HOWPUBLISHED: pName = "Howpublished"; break; case XML_INSTITUTION: pName = "Institution"; break; case XML_JOURNAL: pName = "Journal"; break; case XML_MONTH: pName = "Month"; break; case XML_NOTE: pName = "Note"; break; case XML_NUMBER: pName = "Number"; break; case XML_ORGANIZATIONS: pName = "Organizations"; break; case XML_PAGES: pName = "Pages"; break; case XML_PUBLISHER: pName = "Publisher"; break; case XML_SCHOOL: pName = "School"; break; case XML_SERIES: pName = "Series"; break; case XML_TITLE: pName = "Title"; break; case XML_REPORT_TYPE: pName = "Report_Type"; break; case XML_VOLUME: pName = "Volume"; break; case XML_YEAR: pName = "Year"; break; case XML_URL: pName = "URL"; break; case XML_CUSTOM1: pName = "Custom1"; break; case XML_CUSTOM2: pName = "Custom2"; break; case XML_CUSTOM3: pName = "Custom3"; break; case XML_CUSTOM4: pName = "Custom4"; break; case XML_CUSTOM5: pName = "Custom5"; break; case XML_ISBN: pName = "ISBN"; break; case XML_LOCAL_URL: pName = "LocalURL"; break; case XML_TARGET_TYPE: pName = "TargetType"; break; case XML_TARGET_URL: pName = "TargetURL"; break; default: assert(false && "Unknown bibliography info data"); pName = nullptr; } return pName; } // Annotation Field XMLAnnotationImportContext::XMLAnnotationImportContext( SvXMLImport& rImport, XMLTextImportHelper& rHlp, sal_Int32 nElement) : XMLTextFieldImportContext(rImport, rHlp, "Annotation"), mnElement(nElement) { bValid = true; // remember old list item and block (#91964#) and reset them // for the text frame // do this in the constructor, not in CreateChildContext (#i93392#) GetImport().GetTextImport()->PushListContext(); } void XMLAnnotationImportContext::ProcessAttribute( sal_Int32 nAttrToken, std::string_view sAttrValue ) { if (nAttrToken == XML_ELEMENT(OFFICE, XML_NAME)) aName = OUString::fromUtf8(sAttrValue); else if (nAttrToken == XML_ELEMENT(LO_EXT, XML_RESOLVED)) aResolved = OUString::fromUtf8(sAttrValue); else if (nAttrToken == XML_ELEMENT(LO_EXT, XML_PARENT_NAME)) aParentName = OUString::fromUtf8(sAttrValue); else XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue); } css::uno::Reference< css::xml::sax::XFastContextHandler > XMLAnnotationImportContext::createFastChildContext( sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList>& xAttrList ) { if( nElement == XML_ELEMENT(DC, XML_CREATOR) ) return new XMLStringBufferImportContext(GetImport(), aAuthorBuffer); else if( nElement == XML_ELEMENT(DC, XML_DATE) ) return new XMLStringBufferImportContext(GetImport(), aDateBuffer); else if (nElement == XML_ELEMENT(TEXT,XML_SENDER_INITIALS) || nElement == XML_ELEMENT(LO_EXT, XML_SENDER_INITIALS) || nElement == XML_ELEMENT(META, XML_CREATOR_INITIALS)) return new XMLStringBufferImportContext(GetImport(), aInitialsBuffer); try { bool bOK = true; if ( !mxField.is() ) bOK = CreateField( mxField, sServicePrefix + GetServiceName() ); if (bOK) { Any aAny = mxField->getPropertyValue( "TextRange" ); Reference< XText > xText; aAny >>= xText; if( xText.is() ) { rtl::Reference < XMLTextImportHelper > xTxtImport = GetImport().GetTextImport(); if( !mxCursor.is() ) { mxOldCursor = xTxtImport->GetCursor(); mxCursor = xText->createTextCursor(); } if( mxCursor.is() ) { xTxtImport->SetCursor( mxCursor ); return xTxtImport->CreateTextChildContext( GetImport(), nElement, xAttrList ); } } } } catch (const Exception&) { } return new XMLStringBufferImportContext(GetImport(), aTextBuffer); } void XMLAnnotationImportContext::endFastElement(sal_Int32 /*nElement*/) { DBG_ASSERT(!GetServiceName().isEmpty(), "no service name for element!"); if( mxCursor.is() ) { // delete addition newline mxCursor->gotoEnd( false ); mxCursor->goLeft( 1, true ); mxCursor->setString( "" ); // reset cursor GetImport().GetTextImport()->ResetCursor(); } if( mxOldCursor.is() ) GetImport().GetTextImport()->SetCursor( mxOldCursor ); // reinstall old list item #91964# GetImport().GetTextImport()->PopListContext(); if ( bValid ) { if ( mnElement == XML_ELEMENT(OFFICE, XML_ANNOTATION_END) ) { // Search for a previous annotation with the same name. uno::Reference< text::XTextContent > xPrevField; { Reference xTextFieldsSupplier(GetImport().GetModel(), UNO_QUERY); uno::Reference xFieldsAccess(xTextFieldsSupplier->getTextFields()); uno::Reference xFields(xFieldsAccess->createEnumeration()); while (xFields->hasMoreElements()) { uno::Reference xCurrField(xFields->nextElement(), uno::UNO_QUERY); uno::Reference const xInfo( xCurrField->getPropertySetInfo()); if (xInfo->hasPropertyByName(sAPI_name)) { OUString aFieldName; xCurrField->getPropertyValue(sAPI_name) >>= aFieldName; if (aFieldName == aName) { xPrevField.set( xCurrField, uno::UNO_QUERY ); break; } } } } if ( xPrevField.is() ) { // So we are ending a previous annotation, // let's create a text range covering the old and the current position. uno::Reference xText = GetImportHelper().GetText(); uno::Reference xCursor = xText->createTextCursorByRange(GetImportHelper().GetCursorAsRange()); try { xCursor->gotoRange(xPrevField->getAnchor(), true); } catch (const uno::RuntimeException&) { // Losing the start of the anchor is better than not opening the document at // all. TOOLS_WARN_EXCEPTION( "xmloff.text", "XMLAnnotationImportContext::endFastElement: gotoRange() failed: "); } xText->insertTextContent(xCursor, xPrevField, !xCursor->isCollapsed()); } } else { if ( mxField.is() || CreateField( mxField, sServicePrefix + GetServiceName() ) ) { // set field properties PrepareField( mxField ); // attach field to document Reference < XTextContent > xTextContent( mxField, UNO_QUERY ); // workaround for #80606# try { GetImportHelper().InsertTextContent( xTextContent ); } catch (const lang::IllegalArgumentException&) { // ignore } } } } else GetImportHelper().InsertString(GetContent()); } void XMLAnnotationImportContext::PrepareField( const Reference & xPropertySet ) { // import (possibly empty) author OUString sAuthor( aAuthorBuffer.makeStringAndClear() ); xPropertySet->setPropertyValue(sAPI_author, Any(sAuthor)); // import (possibly empty) initials OUString sInitials( aInitialsBuffer.makeStringAndClear() ); xPropertySet->setPropertyValue("Initials", Any(sInitials)); //import resolved flag bool bTmp(false); (void)::sax::Converter::convertBool(bTmp, aResolved); xPropertySet->setPropertyValue("Resolved", Any(bTmp)); util::DateTime aDateTime; if (::sax::Converter::parseDateTime(aDateTime, aDateBuffer)) { /* Date aDate; aDate.Year = aDateTime.Year; aDate.Month = aDateTime.Month; aDate.Day = aDateTime.Day; xPropertySet->setPropertyValue(sPropertyDate, makeAny(aDate)); */ // why is there no UNO_NAME_DATE_TIME, but only UNO_NAME_DATE_TIME_VALUE? xPropertySet->setPropertyValue(sAPI_date_time_value, Any(aDateTime)); } aDateBuffer.setLength(0); if ( aTextBuffer.getLength() ) { // delete last paragraph mark (if necessary) if (char(0x0a) == aTextBuffer[aTextBuffer.getLength()-1]) aTextBuffer.setLength(aTextBuffer.getLength()-1); xPropertySet->setPropertyValue(sAPI_content, Any(aTextBuffer.makeStringAndClear())); } if (!aName.isEmpty()) xPropertySet->setPropertyValue(sAPI_name, Any(aName)); if (!aParentName.isEmpty()) xPropertySet->setPropertyValue(sAPI_parent_name, Any(aParentName)); } // script field XMLScriptImportContext::XMLScriptImportContext( SvXMLImport& rImport, XMLTextImportHelper& rHlp) : XMLTextFieldImportContext(rImport, rHlp, "Script") , bContentOK(false) { } void XMLScriptImportContext::ProcessAttribute( sal_Int32 nAttrToken, std::string_view sAttrValue ) { switch (nAttrToken) { case XML_ELEMENT(XLINK, XML_HREF): sContent = GetImport().GetAbsoluteReference( OUString::fromUtf8(sAttrValue) ); bContentOK = true; break; case XML_ELEMENT(SCRIPT, XML_LANGUAGE): sScriptType = OUString::fromUtf8(sAttrValue); break; default: // ignore XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue); break; } // always valid (even without ScriptType; cf- #96531#) bValid = true; } void XMLScriptImportContext::PrepareField( const Reference & xPropertySet) { // if href attribute was present, we use it. Else we use element content if (! bContentOK) { sContent = GetContent(); } xPropertySet->setPropertyValue(sAPI_content, Any(sContent)); // URL or script text? We use URL if we have an href-attribute xPropertySet->setPropertyValue("URLContent", Any(bContentOK)); xPropertySet->setPropertyValue("ScriptType", Any(sScriptType)); } // measure field XMLMeasureFieldImportContext::XMLMeasureFieldImportContext( SvXMLImport& rImport, XMLTextImportHelper& rHlp) : XMLTextFieldImportContext(rImport, rHlp, "Measure"), mnKind( 0 ) { } void XMLMeasureFieldImportContext::ProcessAttribute( sal_Int32 nAttrToken, std::string_view sAttrValue ) { switch (nAttrToken) { case XML_ELEMENT(TEXT, XML_KIND): if( IsXMLToken( sAttrValue, XML_VALUE ) ) { mnKind = 0; bValid = true; } else if( IsXMLToken( sAttrValue, XML_UNIT ) ) { mnKind = 1; bValid = true; } else if( IsXMLToken( sAttrValue, XML_GAP ) ) { mnKind = 2; bValid = true; } break; default: XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue); } } void XMLMeasureFieldImportContext::PrepareField( const Reference & xPropertySet) { xPropertySet->setPropertyValue("Kind", Any(mnKind)); } // dropdown field XMLDropDownFieldImportContext::XMLDropDownFieldImportContext( SvXMLImport& rImport, XMLTextImportHelper& rHlp) : XMLTextFieldImportContext( rImport, rHlp, "DropDown" ), nSelected( -1 ), bNameOK( false ), bHelpOK(false), bHintOK(false) { bValid = true; } static bool lcl_ProcessLabel( const Reference& xAttrList, OUString& rLabel, bool& rIsSelected ) { bool bValid = false; for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) ) { switch (aIter.getToken()) { case XML_ELEMENT(TEXT, XML_VALUE): { rLabel = aIter.toString(); bValid = true; break; } case XML_ELEMENT(TEXT, XML_CURRENT_SELECTED): { bool bTmp(false); if (::sax::Converter::convertBool( bTmp, aIter.toView() )) rIsSelected = bTmp; break; } default: XMLOFF_WARN_UNKNOWN("xmloff", aIter); } } return bValid; } css::uno::Reference< css::xml::sax::XFastContextHandler > XMLDropDownFieldImportContext::createFastChildContext( sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) { if( nElement == XML_ELEMENT(TEXT, XML_LABEL) ) { OUString sLabel; bool bIsSelected = false; if( lcl_ProcessLabel( xAttrList, sLabel, bIsSelected ) ) { if( bIsSelected ) nSelected = static_cast( aLabels.size() ); aLabels.push_back( sLabel ); } } return new SvXMLImportContext( GetImport() ); } void XMLDropDownFieldImportContext::ProcessAttribute( sal_Int32 nAttrToken, std::string_view sAttrValue ) { if( nAttrToken == XML_ELEMENT(TEXT, XML_NAME)) { sName = OUString::fromUtf8(sAttrValue); bNameOK = true; } else if (nAttrToken == XML_ELEMENT(TEXT, XML_HELP)) { sHelp = OUString::fromUtf8(sAttrValue); bHelpOK = true; } else if (nAttrToken == XML_ELEMENT(TEXT, XML_HINT)) { sHint = OUString::fromUtf8(sAttrValue); bHintOK = true; } else XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue); } void XMLDropDownFieldImportContext::PrepareField( const Reference& xPropertySet) { // create sequence sal_Int32 nLength = static_cast( aLabels.size() ); Sequence aSequence( nLength ); OUString* pSequence = aSequence.getArray(); for( sal_Int32 n = 0; n < nLength; n++ ) pSequence[n] = aLabels[n]; // now set values: xPropertySet->setPropertyValue( "Items", Any(aSequence) ); if( nSelected >= 0 && nSelected < nLength ) { xPropertySet->setPropertyValue( "SelectedItem", Any(pSequence[nSelected]) ); } // set name if( bNameOK ) { xPropertySet->setPropertyValue( "Name", Any(sName) ); } // set help if( bHelpOK ) { xPropertySet->setPropertyValue( "Help", Any(sHelp) ); } // set hint if( bHintOK ) { xPropertySet->setPropertyValue( "Tooltip", Any(sHint) ); } } /** import header fields () */ XMLHeaderFieldImportContext::XMLHeaderFieldImportContext( SvXMLImport& rImport, /// XML Import XMLTextImportHelper& rHlp) /// Text import helper : XMLTextFieldImportContext(rImport, rHlp, "Header" ) { sServicePrefix = sAPI_presentation_prefix; bValid = true; } /// process attribute values void XMLHeaderFieldImportContext::ProcessAttribute( sal_Int32 nAttrToken, std::string_view sAttrValue ) { XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue); } /// prepare XTextField for insertion into document void XMLHeaderFieldImportContext::PrepareField(const Reference &) { } /** import footer fields () */ XMLFooterFieldImportContext::XMLFooterFieldImportContext( SvXMLImport& rImport, /// XML Import XMLTextImportHelper& rHlp) /// Text import helper : XMLTextFieldImportContext(rImport, rHlp, "Footer" ) { sServicePrefix = sAPI_presentation_prefix; bValid = true; } /// process attribute values void XMLFooterFieldImportContext::ProcessAttribute( sal_Int32 nAttrToken, std::string_view sAttrValue) { XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue); } /// prepare XTextField for insertion into document void XMLFooterFieldImportContext::PrepareField(const Reference &) { } /** import footer fields () */ XMLDateTimeFieldImportContext::XMLDateTimeFieldImportContext( SvXMLImport& rImport, /// XML Import XMLTextImportHelper& rHlp) /// Text import helper : XMLTextFieldImportContext(rImport, rHlp, "DateTime" ) { sServicePrefix = sAPI_presentation_prefix; bValid = true; } /// process attribute values void XMLDateTimeFieldImportContext::ProcessAttribute( sal_Int32 nAttrToken, std::string_view sAttrValue ) { XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue); } /// prepare XTextField for insertion into document void XMLDateTimeFieldImportContext::PrepareField( const css::uno::Reference< css::beans::XPropertySet> &) { } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */