LibreOffice Module xmloff (master) 1
XMLTextMarkImportContext.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
21
22
23#include <rtl/ustring.hxx>
24#include <sal/log.hxx>
25#include <osl/diagnose.h>
27#include <xmloff/xmluconv.hxx>
28#include <xmloff/xmltoken.hxx>
29#include <xmloff/xmlimp.hxx>
32#include <xmloff/odffields.hxx>
33#include <xmloff/xmlement.hxx>
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>
43
44#include <com/sun/star/text/XFormField.hpp>
46
47#include <RDFaImportHelper.hxx>
48
49
50using namespace ::com::sun::star;
51using namespace ::com::sun::star::text;
52using namespace ::com::sun::star::uno;
53using namespace ::com::sun::star::beans;
54using namespace ::com::sun::star::lang;
55using namespace ::com::sun::star::container;
56using namespace ::com::sun::star::xml::sax;
57using namespace ::xmloff::token;
58
59
61 SvXMLImport& rImport,
62 XMLTextImportHelper& rHlp ) :
63 SvXMLImportContext(rImport),
64 rHelper(rHlp)
65{
66}
67
68
69void XMLFieldParamImportContext::startFastElement(sal_Int32 /*nElement*/, const css::uno::Reference< css::xml::sax::XFastAttributeList> & xAttrList)
70{
71 OUString sName;
72 OUString sValue;
73
74 for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
75 {
76 switch (aIter.getToken())
77 {
79 sName = aIter.toString();
80 break;
82 sValue = aIter.toString();
83 break;
84 default:
85 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
86 }
87 }
88 if (rHelper.hasCurrentFieldCtx() && !sName.isEmpty()) {
90 }
91}
92
93
95 SvXMLImport& rImport,
97 uno::Reference<uno::XInterface> & io_rxCrossRefHeadingBookmark )
98 : SvXMLImportContext(rImport)
99 , m_rHelper(rHlp)
100 , m_rxCrossRefHeadingBookmark(io_rxCrossRefHeadingBookmark)
101 , m_isHidden(false)
102 , m_bHaveAbout(false)
103{
104}
105
106namespace {
107
108enum lcl_MarkType { TypeReference, TypeReferenceStart, TypeReferenceEnd,
109 TypeBookmark, TypeBookmarkStart, TypeBookmarkEnd,
110 TypeFieldmark, TypeFieldmarkStart, TypeFieldmarkSeparator, TypeFieldmarkEnd
111 };
112
113}
114
116{
117 { XML_REFERENCE_MARK, TypeReference },
118 { XML_REFERENCE_MARK_START, TypeReferenceStart },
119 { XML_REFERENCE_MARK_END, TypeReferenceEnd },
121 { XML_BOOKMARK_START, TypeBookmarkStart },
122 { XML_BOOKMARK_END, TypeBookmarkEnd },
123 { XML_FIELDMARK, TypeFieldmark },
124 { XML_FIELDMARK_START, TypeFieldmarkStart },
125 { XML_FIELDMARK_SEPARATOR, TypeFieldmarkSeparator },
126 { XML_FIELDMARK_END, TypeFieldmarkEnd },
127 { XML_TOKEN_INVALID, lcl_MarkType(0) },
128};
129
130
131static OUString lcl_getFormFieldmarkName(std::u16string_view name)
132{
133 if (name == ODF_FORMCHECKBOX ||
134 name == u"msoffice.field.FORMCHECKBOX" ||
135 name == u"ecma.office-open-xml.field.FORMCHECKBOX")
136 return ODF_FORMCHECKBOX;
137 else if (name == ODF_FORMDROPDOWN ||
138 name == u"ecma.office-open-xml.field.FORMDROPDOWN")
139 return ODF_FORMDROPDOWN;
140 else
141 return OUString();
142}
143
144static OUString lcl_getFieldmarkName(OUString const& name)
145{
146 if (name == "msoffice.field.FORMTEXT" ||
147 name == "ecma.office-open-xml.field.FORMTEXT")
148 return ODF_FORMTEXT;
149 else
150 return name;
151}
152
153
155 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
156{
157 if (!FindName(xAttrList))
158 {
159 m_sBookmarkName.clear();
160 }
161
162 if ((nElement & TOKEN_MASK) == XML_FIELDMARK_START ||
163 (nElement & TOKEN_MASK) == XML_FIELDMARK)
164 {
165 if (m_sBookmarkName.isEmpty())
166 {
167 m_sBookmarkName = "Unknown";
168 }
170 }
171
172 if ((nElement & TOKEN_MASK) == XML_BOOKMARK_START)
173 {
175 }
176}
177
178static auto InsertFieldmark(SvXMLImport & rImport,
179 XMLTextImportHelper & rHelper, bool const isFieldmarkSeparatorMissing) -> void
180{
181 assert(rHelper.hasCurrentFieldCtx()); // was set up in StartElement()
182
183 // fdo#86795 check if it's actually a checkbox first
184 auto const [ name, type ] = rHelper.getCurrentFieldType();
185 OUString const fieldmarkTypeName = lcl_getFieldmarkName(type);
186 if (fieldmarkTypeName == ODF_FORMCHECKBOX ||
187 fieldmarkTypeName == ODF_FORMDROPDOWN)
188 { // sw can't handle checkbox with start+end
189 SAL_INFO("xmloff.text", "invalid fieldmark-start/fieldmark-end ignored");
190 return;
191 }
192
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)
198 {
199 SAL_WARN("xmloff.text", "invalid field mark positions");
200 assert(false);
201 }
202 xCursor->gotoRange(rHelper.GetCursorAsRange(), true);
203
204 Reference<XTextContent> const xContent = XMLTextMarkImportContext::CreateAndInsertMark(
205 rImport, "com.sun.star.text.Fieldmark", name, xCursor,
206 OUString(), isFieldmarkSeparatorMissing);
207
208 if (!xContent.is())
209 return;
210
211 // setup fieldmark...
212 Reference<text::XFormField> const xFormField(xContent, UNO_QUERY);
213 assert(xFormField.is());
214 try {
215 xFormField->setFieldType(fieldmarkTypeName);
216 } catch (uno::RuntimeException const&) {
217 // tdf#140437 somehow old documents had the field code in the type
218 // attribute instead of field:param
219 SAL_INFO("xmloff.text", "invalid fieldmark type, converting to param");
220 // add without checking: FieldParamImporter::Import() catches ElementExistException
221 rHelper.addFieldParam(ODF_CODE_PARAM, fieldmarkTypeName);
222 xFormField->setFieldType(ODF_UNHANDLED);
223 }
224 rHelper.setCurrentFieldParamsTo(xFormField);
225 // move cursor after setFieldType as that may delete/re-insert
226 rHelper.GetCursor()->gotoRange(xContent->getAnchor()->getEnd(), false);
227 rHelper.GetCursor()->goLeft(1, false); // move before CH_TXT_ATR_FIELDEND
228 // tdf#129520: AppendTextNode() ignores the content index!
229 // plan B: insert a spurious paragraph break now and join
230 // it in PopFieldmark()!
231 rHelper.GetText()->insertControlCharacter(rHelper.GetCursor(),
232 text::ControlCharacter::PARAGRAPH_BREAK, false);
233 rHelper.GetCursor()->goLeft(1, false); // back to previous paragraph
234}
235
236static auto PopFieldmark(XMLTextImportHelper & rHelper) -> void
237{
238 // can't verify name because it's not written as an attribute...
239 uno::Reference<text::XTextContent> const xField(rHelper.popFieldCtx(),
240 uno::UNO_QUERY);
241 if (!xField.is())
242 return;
243
244 if (rHelper.GetText() == xField->getAnchor()->getText())
245 {
246 try
247 { // skip CH_TXT_ATR_FIELDEND
248 rHelper.GetCursor()->goRight(1, true);
249 rHelper.GetCursor()->setString(OUString()); // undo AppendTextNode from InsertFieldmark
250 rHelper.GetCursor()->gotoRange(xField->getAnchor()->getEnd(), false);
251 }
252 catch (uno::Exception const&)
253 {
254 assert(false); // must succeed
255 }
256 }
257 else
258 {
259 SAL_INFO("xmloff.text", "fieldmark has invalid positions");
260 // could either dispose it or leave it to end at the end of the document?
261 xField->dispose();
262 }
263}
264
266{
267 static constexpr OUStringLiteral sAPI_bookmark = u"com.sun.star.text.Bookmark";
268
269 lcl_MarkType nTmp{};
270 if (!SvXMLUnitConverter::convertEnum(nTmp, SvXMLImport::getNameFromToken(nElement), lcl_aMarkTypeMap))
271 return;
272
273 if (m_sBookmarkName.isEmpty() && TypeFieldmarkEnd != nTmp && TypeFieldmarkSeparator != nTmp)
274 return;
275
276 switch (nTmp)
277 {
278 case TypeReference:
279 // export point reference mark
281 "com.sun.star.text.ReferenceMark",
283 m_rHelper.GetCursorAsRange()->getStart());
284 break;
285
286 case TypeBookmark:
287 {
288 // tdf#94804: detect duplicate heading cross reference bookmarks
289 if (m_sBookmarkName.startsWith("__RefHeading__"))
290 {
292 {
293 uno::Reference<container::XNamed> const xNamed(
294 m_rxCrossRefHeadingBookmark, uno::UNO_QUERY);
296 m_sBookmarkName, xNamed->getName());
297 break; // don't insert
298 }
299 }
300 }
301 [[fallthrough]];
302 case TypeFieldmark:
303 {
304 const OUString formFieldmarkName=lcl_getFormFieldmarkName(m_sFieldName);
305 bool bImportAsField = (nTmp==TypeFieldmark && !formFieldmarkName.isEmpty()); //@TODO handle abbreviation cases...
306 // export point bookmark
307 const Reference<XInterface> xContent(
309 (bImportAsField ? OUString("com.sun.star.text.FormFieldmark") : OUString(sAPI_bookmark)),
311 m_rHelper.GetCursorAsRange()->getStart(),
312 m_sXmlId) );
313 if (nTmp==TypeFieldmark) {
314 if (xContent.is() && bImportAsField) {
315 // setup fieldmark...
316 Reference< css::text::XFormField> xFormField(xContent, UNO_QUERY);
317 xFormField->setFieldType(formFieldmarkName);
318 if (xFormField.is() && m_rHelper.hasCurrentFieldCtx()) {
320 }
321 }
323 }
324 if (TypeBookmark == nTmp
325 && m_sBookmarkName.startsWith("__RefHeading__"))
326 {
327 assert(xContent.is());
329 }
330 }
331 break;
332
333 case TypeBookmarkStart:
334 // save XTextRange for later construction of bookmark
335 {
336 std::shared_ptr< ::xmloff::ParsedRDFaAttributes >
337 xRDFaAttributes;
338 if (m_bHaveAbout && TypeBookmarkStart == nTmp)
339 {
340 xRDFaAttributes =
341 GetImport().GetRDFaImportHelper().ParseRDFa(
344 }
347 m_rHelper.GetCursorAsRange()->getStart(),
348 m_sXmlId, xRDFaAttributes);
349 }
350 break;
351
352 case TypeBookmarkEnd:
353 {
354 // tdf#94804: detect duplicate heading cross reference bookmarks
355 if (m_sBookmarkName.startsWith("__RefHeading__"))
356 {
358 {
359 uno::Reference<container::XNamed> const xNamed(
360 m_rxCrossRefHeadingBookmark, uno::UNO_QUERY);
362 m_sBookmarkName, xNamed->getName());
363 break; // don't insert
364 }
365 }
366
367 // get old range, and construct
368 Reference<XTextRange> xStartRange;
369 std::shared_ptr< ::xmloff::ParsedRDFaAttributes >
370 xRDFaAttributes;
372 m_sBookmarkName, xStartRange,
373 m_sXmlId, xRDFaAttributes))
374 {
375 Reference<XTextRange> xEndRange(
376 m_rHelper.GetCursorAsRange()->getStart());
377
378 // check if beginning and end are in same XText
379 if (xStartRange.is() && xEndRange.is() && xStartRange->getText() == xEndRange->getText())
380 {
381 // create range for insertion
382 Reference<XTextCursor> xInsertionCursor =
383 m_rHelper.GetText()->createTextCursorByRange(
384 xEndRange);
385 try {
386 xInsertionCursor->gotoRange(xStartRange, true);
387 } catch (uno::Exception&) {
388 TOOLS_WARN_EXCEPTION("xmloff.text",
389 "cannot go to end position of bookmark");
390 }
391
392 //DBG_ASSERT(! xInsertionCursor->isCollapsed(),
393 // "we want no point mark");
394 // can't assert, because someone could
395 // create a file with subsequence
396 // start/end elements
397
398 Reference<XInterface> xContent;
399 // insert reference
400 xContent = CreateAndInsertMark(GetImport(),
401 sAPI_bookmark,
403 xInsertionCursor,
404 m_sXmlId);
405 if (xRDFaAttributes)
406 {
407 const Reference<rdf::XMetadatable>
408 xMeta(xContent, UNO_QUERY);
409 GetImport().GetRDFaImportHelper().AddRDFa(
410 xMeta, xRDFaAttributes);
411 }
412 const Reference<XPropertySet> xPropertySet(xContent, UNO_QUERY);
413 if (xPropertySet.is())
414 {
415 xPropertySet->setPropertyValue("BookmarkHidden", uno::Any(m_rHelper.getBookmarkHidden(m_sBookmarkName)));
416 xPropertySet->setPropertyValue("BookmarkCondition", uno::Any(m_rHelper.getBookmarkCondition(m_sBookmarkName)));
417 }
418 if (m_sBookmarkName.startsWith("__RefHeading__"))
419 {
420 assert(xContent.is());
422 }
423 }
424 // else: beginning/end in different XText -> ignore!
425 }
426 // else: no start found -> ignore!
427 break;
428 }
429 case TypeFieldmarkStart:
430 {
431 break;
432 }
433 case TypeFieldmarkSeparator:
434 {
436 break;
437 }
438 case TypeFieldmarkEnd:
439 {
441 { // backward compat for old files without separator
443 }
445 break;
446 }
447 case TypeReferenceStart:
448 case TypeReferenceEnd:
449 OSL_FAIL("reference start/end are handled in txtparai !");
450 break;
451
452 default:
453 OSL_FAIL("unknown mark type");
454 break;
455 }
456}
457
458css::uno::Reference< css::xml::sax::XFastContextHandler > XMLTextMarkImportContext::createFastChildContext(
459 sal_Int32 ,
460 const css::uno::Reference< css::xml::sax::XFastAttributeList >& )
461{
463}
464
465
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)
473{
474 // create mark
475 const Reference<XMultiServiceFactory> xFactory(rImport.GetModel(),
476 UNO_QUERY);
477 Reference<XInterface> xIfc;
478
479 if (xFactory.is())
480 {
481 xIfc = xFactory->createInstance(sServiceName);
482
483 if (!xIfc.is())
484 {
485 OSL_FAIL("CreateAndInsertMark: cannot create service?");
486 return nullptr;
487 }
488
489 // set name (unless there is no name (text:meta))
490 const Reference<XNamed> xNamed(xIfc, UNO_QUERY);
491 if (xNamed.is())
492 {
493 xNamed->setName(sMarkName);
494 }
495 else
496 {
497 if (!sMarkName.isEmpty())
498 {
499 OSL_FAIL("name given, but XNamed not supported?");
500 return nullptr;
501 }
502 }
503
504 if (isFieldmarkSeparatorMissing)
505 {
506 uno::Reference<beans::XPropertySet> const xProps(xIfc, uno::UNO_QUERY_THROW);
507 xProps->setPropertyValue("PrivateSeparatorAtStart", uno::Any(true));
508 }
509
510 // cast to XTextContent and attach to document
511 const Reference<XTextContent> xTextContent(xIfc, UNO_QUERY);
512 if (xTextContent.is())
513 {
514 try
515 {
516 // if inserting marks, bAbsorb==sal_False will cause
517 // collapsing of the given XTextRange.
518 rImport.GetTextImport()->GetText()->insertTextContent(rRange,
519 xTextContent, true);
520
521 // xml:id for RDF metadata -- after insertion!
522 rImport.SetXmlId(xIfc, i_rXmlId);
523
524 return xTextContent;
525 }
526 catch (css::lang::IllegalArgumentException &)
527 {
528 OSL_FAIL("CreateAndInsertMark: cannot insert?");
529 return nullptr;
530 }
531 }
532 }
533 return nullptr;
534}
535
537 const Reference<XFastAttributeList> & xAttrList)
538{
539 bool bNameOK = false;
540
541 // find name attribute first
542 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
543 {
544 OUString sValue = aIter.toString();
545 switch(aIter.getToken())
546 {
548 m_sBookmarkName = sValue;
549 bNameOK = true;
550 break;
551 case XML_ELEMENT(XML, XML_ID):
552 m_sXmlId = sValue;
553 break;
554 // RDFa
555 case XML_ELEMENT(XHTML, XML_ABOUT):
556 m_sAbout = sValue;
557 m_bHaveAbout = true;
558 break;
559 case XML_ELEMENT(XHTML, XML_PROPERTY):
560 m_sProperty = sValue;
561 break;
562 case XML_ELEMENT(XHTML, XML_CONTENT):
563 m_sContent = sValue;
564 break;
565 case XML_ELEMENT(XHTML, XML_DATATYPE):
566 m_sDatatype = sValue;
567 break;
569 m_sFieldName = sValue;
570 break;
571 case XML_ELEMENT(LO_EXT, XML_HIDDEN):
573 break;
574 case XML_ELEMENT(LO_EXT, XML_CONDITION):
575 m_sCondition = sValue;
576 break;
577 default:
578 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
579 }
580 }
581
582 return bNameOK;
583}
584
585/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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.
Definition: xmlictxt.hxx:48
SvXMLImport & GetImport()
Definition: xmlictxt.hxx:60
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...
Definition: xmluconv.hxx:145
XMLFieldParamImportContext(SvXMLImport &rImport, XMLTextImportHelper &rHlp)
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)
Definition: txtimp.cxx:2120
bool getBookmarkHidden(OUString const &bookmark) const
Definition: txtimp.cxx:2455
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
Definition: txtimp.cxx:2093
css::uno::Reference< css::text::XText > & GetText()
Definition: txtimp.cxx:211
void setCurrentFieldParamsTo(css::uno::Reference< css::text::XFormField > const &xFormField)
Definition: txtimp.cxx:2172
css::uno::Reference< css::text::XFormField > popFieldCtx()
Definition: txtimp.cxx:2127
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
Definition: txtimp.cxx:2082
void addFieldParam(const OUString &name, const OUString &value)
Definition: txtimp.cxx:2142
bool hasCurrentFieldCtx() const
Definition: txtimp.cxx:2167
bool hasCurrentFieldSeparator() const
Definition: txtimp.cxx:2161
void setBookmarkAttributes(OUString const &bookmark, bool hidden, OUString const &condition)
Definition: txtimp.cxx:2449
const OUString & getBookmarkCondition(OUString const &bookmark) const
Definition: txtimp.cxx:2460
void AddCrossRefHeadingMapping(OUString const &rFrom, OUString const &rTo)
Definition: txtimp.cxx:2393
css::uno::Reference< css::text::XTextRange > & GetCursorAsRange()
Definition: txtimp.cxx:221
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
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)
float u
Reference< XSingleServiceFactory > xFactory
OUString sName
const char * name
#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
Definition: xmltoken.hxx:3325
@ XML_REFERENCE_MARK_START
Definition: xmltoken.hxx:1604
@ XML_REFERENCE_MARK_END
Definition: xmltoken.hxx:1603
constexpr OUStringLiteral ODF_FORMTEXT
Definition: odffields.hxx:25
constexpr OUStringLiteral ODF_CODE_PARAM
Definition: odffields.hxx:56
constexpr OUStringLiteral ODF_FORMCHECKBOX
Definition: odffields.hxx:28
constexpr OUStringLiteral ODF_UNHANDLED
Definition: odffields.hxx:53
constexpr OUStringLiteral ODF_FORMDROPDOWN
Definition: odffields.hxx:32
TEXT
ResultType type
#define XMLOFF_WARN_UNKNOWN(area, rIter)
Definition: xmlictxt.hxx:114
#define XML_ELEMENT(prefix, name)
Definition: xmlimp.hxx:97
constexpr sal_Int32 TOKEN_MASK
Definition: xmlimp.hxx:94