23#include <rtl/ustring.hxx>
25#include <osl/diagnose.h>
34#include <com/sun/star/frame/XModel.hpp>
35#include <com/sun/star/xml/sax/XAttributeList.hpp>
36#include <com/sun/star/text/ControlCharacter.hpp>
37#include <com/sun/star/text/XTextContent.hpp>
38#include <com/sun/star/text/XTextRangeCompare.hpp>
39#include <com/sun/star/beans/XPropertySet.hpp>
40#include <com/sun/star/lang/XMultiServiceFactory.hpp>
41#include <com/sun/star/container/XNamed.hpp>
42#include <com/sun/star/rdf/XMetadatable.hpp>
44#include <com/sun/star/text/XFormField.hpp>
76 switch (aIter.getToken())
79 sName = aIter.toString();
82 sValue = aIter.toString();
97 uno::Reference<uno::XInterface> & io_rxCrossRefHeadingBookmark )
100 , m_rxCrossRefHeadingBookmark(io_rxCrossRefHeadingBookmark)
102 , m_bHaveAbout(false)
108enum lcl_MarkType { TypeReference, TypeReferenceStart, TypeReferenceEnd,
110 TypeFieldmark, TypeFieldmarkStart, TypeFieldmarkSeparator, TypeFieldmarkEnd
134 name ==
u"msoffice.field.FORMCHECKBOX" ||
135 name ==
u"ecma.office-open-xml.field.FORMCHECKBOX")
138 name ==
u"ecma.office-open-xml.field.FORMDROPDOWN")
146 if (
name ==
"msoffice.field.FORMTEXT" ||
147 name ==
"ecma.office-open-xml.field.FORMTEXT")
155 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
181 assert(rHelper.hasCurrentFieldCtx());
184 auto const [
name,
type ] = rHelper.getCurrentFieldType();
189 SAL_INFO(
"xmloff.text",
"invalid fieldmark-start/fieldmark-end ignored");
193 uno::Reference<text::XTextRange>
const xStartRange(rHelper.getCurrentFieldStart());
194 uno::Reference<text::XTextCursor>
const xCursor(
195 rHelper.GetText()->createTextCursorByRange(xStartRange));
196 uno::Reference<text::XTextRangeCompare>
const xCompare(rHelper.GetText(), uno::UNO_QUERY);
197 if (xCompare->compareRegionStarts(xStartRange, rHelper.GetCursorAsRange()) < 0)
199 SAL_WARN(
"xmloff.text",
"invalid field mark positions");
202 xCursor->gotoRange(rHelper.GetCursorAsRange(),
true);
205 rImport,
"com.sun.star.text.Fieldmark",
name, xCursor,
206 OUString(), isFieldmarkSeparatorMissing);
212 Reference<text::XFormField>
const xFormField(xContent, UNO_QUERY);
213 assert(xFormField.is());
215 xFormField->setFieldType(fieldmarkTypeName);
216 }
catch (uno::RuntimeException
const&) {
219 SAL_INFO(
"xmloff.text",
"invalid fieldmark type, converting to param");
224 rHelper.setCurrentFieldParamsTo(xFormField);
226 rHelper.GetCursor()->gotoRange(xContent->getAnchor()->getEnd(),
false);
227 rHelper.GetCursor()->goLeft(1,
false);
231 rHelper.GetText()->insertControlCharacter(rHelper.GetCursor(),
232 text::ControlCharacter::PARAGRAPH_BREAK,
false);
233 rHelper.GetCursor()->goLeft(1,
false);
239 uno::Reference<text::XTextContent>
const xField(rHelper.popFieldCtx(),
244 if (rHelper.GetText() == xField->getAnchor()->getText())
248 rHelper.GetCursor()->goRight(1,
true);
249 rHelper.GetCursor()->setString(OUString());
250 rHelper.GetCursor()->gotoRange(xField->getAnchor()->getEnd(),
false);
252 catch (uno::Exception
const&)
259 SAL_INFO(
"xmloff.text",
"fieldmark has invalid positions");
267 static constexpr OUStringLiteral sAPI_bookmark =
u"com.sun.star.text.Bookmark";
273 if (
m_sBookmarkName.isEmpty() && TypeFieldmarkEnd != nTmp && TypeFieldmarkSeparator != nTmp)
281 "com.sun.star.text.ReferenceMark",
293 uno::Reference<container::XNamed>
const xNamed(
305 bool bImportAsField = (nTmp==TypeFieldmark && !formFieldmarkName.isEmpty());
307 const Reference<XInterface> xContent(
309 (bImportAsField ? OUString(
"com.sun.star.text.FormFieldmark") : OUString(sAPI_bookmark)),
313 if (nTmp==TypeFieldmark) {
314 if (xContent.is() && bImportAsField) {
316 Reference< css::text::XFormField> xFormField(xContent, UNO_QUERY);
317 xFormField->setFieldType(formFieldmarkName);
327 assert(xContent.is());
333 case TypeBookmarkStart:
336 std::shared_ptr< ::xmloff::ParsedRDFaAttributes >
341 GetImport().GetRDFaImportHelper().ParseRDFa(
352 case TypeBookmarkEnd:
359 uno::Reference<container::XNamed>
const xNamed(
368 Reference<XTextRange> xStartRange;
369 std::shared_ptr< ::xmloff::ParsedRDFaAttributes >
375 Reference<XTextRange> xEndRange(
379 if (xStartRange.is() && xEndRange.is() && xStartRange->getText() == xEndRange->getText())
382 Reference<XTextCursor> xInsertionCursor =
386 xInsertionCursor->gotoRange(xStartRange,
true);
387 }
catch (uno::Exception&) {
389 "cannot go to end position of bookmark");
398 Reference<XInterface> xContent;
407 const Reference<rdf::XMetadatable>
408 xMeta(xContent, UNO_QUERY);
409 GetImport().GetRDFaImportHelper().AddRDFa(
410 xMeta, xRDFaAttributes);
412 const Reference<XPropertySet> xPropertySet(xContent, UNO_QUERY);
413 if (xPropertySet.is())
420 assert(xContent.is());
429 case TypeFieldmarkStart:
433 case TypeFieldmarkSeparator:
438 case TypeFieldmarkEnd:
447 case TypeReferenceStart:
448 case TypeReferenceEnd:
449 OSL_FAIL(
"reference start/end are handled in txtparai !");
453 OSL_FAIL(
"unknown mark type");
460 const css::uno::Reference< css::xml::sax::XFastAttributeList >& )
467 SvXMLImport& rImport,
468 const OUString& sServiceName,
469 const OUString& sMarkName,
470 const Reference<XTextRange> & rRange,
471 const OUString& i_rXmlId,
472 bool const isFieldmarkSeparatorMissing)
475 const Reference<XMultiServiceFactory>
xFactory(rImport.GetModel(),
477 Reference<XInterface> xIfc;
485 OSL_FAIL(
"CreateAndInsertMark: cannot create service?");
490 const Reference<XNamed> xNamed(xIfc, UNO_QUERY);
493 xNamed->setName(sMarkName);
497 if (!sMarkName.isEmpty())
499 OSL_FAIL(
"name given, but XNamed not supported?");
504 if (isFieldmarkSeparatorMissing)
506 uno::Reference<beans::XPropertySet>
const xProps(xIfc, uno::UNO_QUERY_THROW);
507 xProps->setPropertyValue(
"PrivateSeparatorAtStart",
uno::Any(
true));
511 const Reference<XTextContent> xTextContent(xIfc, UNO_QUERY);
512 if (xTextContent.is())
518 rImport.GetTextImport()->GetText()->insertTextContent(rRange,
522 rImport.SetXmlId(xIfc, i_rXmlId);
526 catch (css::lang::IllegalArgumentException &)
528 OSL_FAIL(
"CreateAndInsertMark: cannot insert?");
537 const Reference<XFastAttributeList> & xAttrList)
539 bool bNameOK =
false;
544 OUString sValue = aIter.toString();
545 switch(aIter.getToken())
SvXMLEnumMapEntry< lcl_MarkType > const lcl_aMarkTypeMap[]
static auto InsertFieldmark(SvXMLImport &rImport, XMLTextImportHelper &rHelper, bool const isFieldmarkSeparatorMissing) -> void
static OUString lcl_getFieldmarkName(OUString const &name)
static auto PopFieldmark(XMLTextImportHelper &rHelper) -> void
static OUString lcl_getFormFieldmarkName(std::u16string_view name)
constexpr OUStringLiteral sServiceName
This class deliberately does not support XWeak, to improve performance when loading large documents.
SvXMLImport & GetImport()
static bool convertEnum(EnumT &rEnum, std::u16string_view rValue, const SvXMLEnumMapEntry< EnumT > *pMap)
convert string to enum using given enum map, if the enum is not found in the map, this method will re...
XMLFieldParamImportContext(SvXMLImport &rImport, XMLTextImportHelper &rHlp)
XMLTextImportHelper & rHelper
virtual void SAL_CALL startFastElement(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
void pushFieldCtx(const OUString &name, const OUString &type)
bool getBookmarkHidden(OUString const &bookmark) const
bool FindAndRemoveBookmarkStartRange(const OUString &sName, css::uno::Reference< css::text::XTextRange > &o_rRange, OUString &o_rXmlId, std::shared_ptr< ::xmloff::ParsedRDFaAttributes > &o_rpRDFaAttributes)
process the start of a range reference
css::uno::Reference< css::text::XText > & GetText()
void setCurrentFieldParamsTo(css::uno::Reference< css::text::XFormField > const &xFormField)
css::uno::Reference< css::text::XFormField > popFieldCtx()
void InsertBookmarkStartRange(const OUString &sName, const css::uno::Reference< css::text::XTextRange > &rRange, OUString const &i_rXmlId, std::shared_ptr< ::xmloff::ParsedRDFaAttributes > &i_rpRDFaAttributes)
save the start of a range reference
void addFieldParam(const OUString &name, const OUString &value)
bool hasCurrentFieldCtx() const
bool hasCurrentFieldSeparator() const
void setBookmarkAttributes(OUString const &bookmark, bool hidden, OUString const &condition)
const OUString & getBookmarkCondition(OUString const &bookmark) const
void AddCrossRefHeadingMapping(OUString const &rFrom, OUString const &rTo)
css::uno::Reference< css::text::XTextRange > & GetCursorAsRange()
virtual void SAL_CALL startFastElement(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
css::uno::Reference< css::uno::XInterface > & m_rxCrossRefHeadingBookmark
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
XMLTextImportHelper & m_rHelper
XMLTextMarkImportContext(SvXMLImport &rImport, XMLTextImportHelper &rHlp, css::uno::Reference< css::uno::XInterface > &io_rxCrossRefHeadingBookmark)
static css::uno::Reference< css::text::XTextContent > CreateAndInsertMark(SvXMLImport &rImport, const OUString &sServiceName, const OUString &sMarkName, const css::uno::Reference< css::text::XTextRange > &rRange, const OUString &i_rXmlId=OUString(), bool const isFieldmarkSeparatorMissing=false)
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
endFastElement is called before a context will be destructed, but after an elements context has been ...
bool FindName(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
static bool convertBool(bool &rBool, std::u16string_view rString)
#define TOOLS_WARN_EXCEPTION(area, stream)
Reference< XSingleServiceFactory > xFactory
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
Handling of tokens in XML:
@ XML_FIELDMARK_SEPARATOR
@ XML_REFERENCE_MARK_START
constexpr OUStringLiteral ODF_FORMTEXT
constexpr OUStringLiteral ODF_CODE_PARAM
constexpr OUStringLiteral ODF_FORMCHECKBOX
constexpr OUStringLiteral ODF_UNHANDLED
constexpr OUStringLiteral ODF_FORMDROPDOWN
#define XMLOFF_WARN_UNKNOWN(area, rIter)
#define XML_ELEMENT(prefix, name)
constexpr sal_Int32 TOKEN_MASK