1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
23 #include <string_view>
26 #include <rtl/ustring.hxx>
27 #include <rtl/ustrbuf.hxx>
28 #include <sal/log.hxx>
29 #include <tools/diagnose_ex.h>
30 #include <com/sun/star/frame/XModel.hpp>
31 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
32 #include <com/sun/star/text/XTextFrame.hpp>
33 #include <com/sun/star/text/XTextCursor.hpp>
34 #include <com/sun/star/beans/XPropertySet.hpp>
35 #include <com/sun/star/beans/XPropertySetInfo.hpp>
36 #include <com/sun/star/text/ControlCharacter.hpp>
37 #include <com/sun/star/container/XIndexReplace.hpp>
38 #include <com/sun/star/drawing/XShapes.hpp>
39 #include <com/sun/star/container/XEnumerationAccess.hpp>
40 #include <com/sun/star/rdf/XMetadatable.hpp>
42 #include <sax/tools/converter.hxx>
44 #include <xmloff/xmlictxt.hxx>
45 #include <xmloff/xmlimp.hxx>
46 #include <xmloff/xmltoken.hxx>
47 #include <xmloff/namespacemap.hxx>
48 #include <xmloff/xmlnamespace.hxx>
49 #include <xmloff/txtimp.hxx>
50 #include "txtparai.hxx"
51 #include <txtfldi.hxx>
52 #include "XMLFootnoteImportContext.hxx"
53 #include "XMLTextMarkImportContext.hxx"
54 #include "XMLTextFrameContext.hxx"
55 #include <xmloff/XMLCharContext.hxx>
56 #include "XMLTextFrameHyperlinkContext.hxx"
57 #include <xmloff/XMLEventsImportContext.hxx>
58 #include "XMLChangeImportContext.hxx"
59 #include <txtlists.hxx>
61 #include "txtparaimphint.hxx"
62 #include "xmllinebreakcontext.hxx"
63 #include "xmlcontentcontrolcontext.hxx"
65 using namespace ::com::sun::star
;
66 using namespace ::com::sun::star::uno
;
67 using namespace ::com::sun::star::text
;
68 using namespace ::com::sun::star::drawing
;
69 using namespace ::com::sun::star::beans
;
70 using namespace ::xmloff::token
;
71 using ::com::sun::star::container::XEnumerationAccess
;
72 using ::com::sun::star::container::XEnumeration
;
78 std::vector
<std::unique_ptr
<XMLHint_Impl
>> m_Hints
;
79 std::unordered_map
<OUString
, XMLIndexMarkHint_Impl
*> m_IndexHintsById
;
80 uno::Reference
<uno::XInterface
> m_xCrossRefHeadingBookmark
;
83 void push_back(std::unique_ptr
<XMLHint_Impl
> pHint
)
85 m_Hints
.push_back(std::move(pHint
));
88 void push_back(std::unique_ptr
<XMLIndexMarkHint_Impl
> pHint
)
90 m_IndexHintsById
.emplace(pHint
->GetID(), pHint
.get());
91 m_Hints
.push_back(std::move(pHint
));
94 std::vector
<std::unique_ptr
<XMLHint_Impl
>> const& GetHints() const
99 XMLIndexMarkHint_Impl
* GetIndexHintById(const OUString
& sID
)
101 auto it
= m_IndexHintsById
.find(sID
);
102 return it
== m_IndexHintsById
.end() ? nullptr : it
->second
;
105 uno::Reference
<uno::XInterface
> & GetCrossRefHeadingBookmark()
107 return m_xCrossRefHeadingBookmark
;
112 XMLCharContext::XMLCharContext(
113 SvXMLImport
& rImport
,
114 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
,
117 SvXMLImportContext( rImport
)
125 for (auto &aIter
: sax_fastparser::castToFastAttributeList( xAttrList
))
127 if( aIter
.getToken() == XML_ELEMENT(TEXT
, XML_C
) )
129 sal_Int32 nTmp
= aIter
.toInt32();
132 if( nTmp
> SAL_MAX_UINT16
)
133 m_nCount
= SAL_MAX_UINT16
;
135 m_nCount
= static_cast<sal_uInt16
>(nTmp
);
139 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
143 XMLCharContext::XMLCharContext(
145 sal_Int16 nControl
) :
146 SvXMLImportContext( rImp
)
147 ,m_nControl(nControl
)
153 XMLCharContext::~XMLCharContext()
156 void XMLCharContext::endFastElement(sal_Int32
)
159 InsertControlCharacter( m_nControl
);
164 OUString
sBuff( &m_c
, 1 );
169 OUStringBuffer
sBuff(static_cast<int>(m_nCount
));
171 sBuff
.append( &m_c
, 1 );
173 InsertString(sBuff
.makeStringAndClear() );
177 void XMLCharContext::InsertControlCharacter(sal_Int16 _nControl
)
179 GetImport().GetTextImport()->InsertControlCharacter( _nControl
);
181 void XMLCharContext::InsertString(const OUString
& _sString
)
183 GetImport().GetTextImport()->InsertString( _sString
);
188 /** import start of reference (<text:reference-start>) */
189 class XMLStartReferenceContext_Impl
: public SvXMLImportContext
193 // Do everything in constructor. Well ...
194 XMLStartReferenceContext_Impl (
195 SvXMLImport
& rImport
,
196 XMLHints_Impl
& rHints
,
197 const Reference
<xml::sax::XFastAttributeList
> & xAttrList
);
199 static bool FindName(
200 const Reference
<xml::sax::XFastAttributeList
> & xAttrList
,
206 XMLStartReferenceContext_Impl::XMLStartReferenceContext_Impl(
207 SvXMLImport
& rImport
,
208 XMLHints_Impl
& rHints
,
209 const Reference
<xml::sax::XFastAttributeList
> & xAttrList
) :
210 SvXMLImportContext(rImport
)
214 if (FindName(xAttrList
, sName
))
216 std::unique_ptr
<XMLHint_Impl
> pHint(new XMLReferenceHint_Impl(
217 sName
, rImport
.GetTextImport()->GetCursor()->getStart()));
219 // degenerates to point reference, if no end is found!
220 pHint
->SetEnd(rImport
.GetTextImport()->GetCursor()->getStart() );
222 rHints
.push_back(std::move(pHint
));
226 bool XMLStartReferenceContext_Impl::FindName(
227 const Reference
<xml::sax::XFastAttributeList
> & xAttrList
,
230 bool bNameOK( false );
232 // find name attribute first
233 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
235 if ( aIter
.getToken() == XML_ELEMENT(TEXT
, XML_NAME
) )
237 rName
= aIter
.toString();
248 /** import end of reference (<text:reference-end>) */
249 class XMLEndReferenceContext_Impl
: public SvXMLImportContext
253 // Do everything in constructor. Well ...
254 XMLEndReferenceContext_Impl(
255 SvXMLImport
& rImport
,
256 const XMLHints_Impl
& rHints
,
257 const Reference
<xml::sax::XFastAttributeList
> & xAttrList
);
262 XMLEndReferenceContext_Impl::XMLEndReferenceContext_Impl(
263 SvXMLImport
& rImport
,
264 const XMLHints_Impl
& rHints
,
265 const Reference
<xml::sax::XFastAttributeList
> & xAttrList
) :
266 SvXMLImportContext(rImport
)
270 // borrow from XMLStartReferenceContext_Impl
271 if (!XMLStartReferenceContext_Impl::FindName(xAttrList
, sName
))
274 // search for reference start
275 for (const auto& rHintPtr
: rHints
.GetHints())
277 XMLHint_Impl
*const pHint
= rHintPtr
.get();
278 if ( pHint
->IsReference() &&
279 sName
== static_cast<XMLReferenceHint_Impl
*>(pHint
)->GetRefName() )
281 // set end and stop searching
282 pHint
->SetEnd(GetImport().GetTextImport()->
283 GetCursor()->getStart() );
287 // else: no start (in this paragraph) -> ignore
292 class XMLImpHyperlinkContext_Impl
: public SvXMLImportContext
294 XMLHints_Impl
& m_rHints
;
295 XMLHyperlinkHint_Impl
*mpHint
;
297 bool& mrbIgnoreLeadingSpace
;
302 XMLImpHyperlinkContext_Impl(
303 SvXMLImport
& rImport
,
305 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
,
306 XMLHints_Impl
& rHints
,
307 bool& rIgnLeadSpace
);
309 virtual ~XMLImpHyperlinkContext_Impl() override
;
311 virtual css::uno::Reference
< css::xml::sax::XFastContextHandler
> SAL_CALL
createFastChildContext(
312 sal_Int32 nElement
, const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& AttrList
) override
;
314 virtual void SAL_CALL
characters( const OUString
& rChars
) override
;
319 XMLImpHyperlinkContext_Impl::XMLImpHyperlinkContext_Impl(
320 SvXMLImport
& rImport
,
321 sal_Int32
/*nElement*/,
322 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
,
323 XMLHints_Impl
& rHints
,
324 bool& rIgnLeadSpace
)
325 : SvXMLImportContext( rImport
)
327 , mpHint( new XMLHyperlinkHint_Impl( GetImport().GetTextImport()->GetCursorAsRange()->getStart() ) )
328 , mrbIgnoreLeadingSpace( rIgnLeadSpace
)
332 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
334 OUString sValue
= aIter
.toString();
335 switch (aIter
.getToken())
337 case XML_ELEMENT(XLINK
, XML_HREF
):
338 mpHint
->SetHRef( GetImport().GetAbsoluteReference( sValue
) );
340 case XML_ELEMENT(OFFICE
, XML_NAME
):
341 mpHint
->SetName( sValue
);
343 case XML_ELEMENT(OFFICE
, XML_TARGET_FRAME_NAME
):
344 mpHint
->SetTargetFrameName( sValue
);
346 case XML_ELEMENT(XLINK
, XML_SHOW
):
349 case XML_ELEMENT(TEXT
, XML_STYLE_NAME
):
350 mpHint
->SetStyleName( sValue
);
352 case XML_ELEMENT(TEXT
, XML_VISITED_STYLE_NAME
):
353 mpHint
->SetVisitedStyleName( sValue
);
356 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
360 if( !sShow
.isEmpty() && mpHint
->GetTargetFrameName().isEmpty() )
362 if( IsXMLToken( sShow
, XML_NEW
) )
363 mpHint
->SetTargetFrameName(
365 else if( IsXMLToken( sShow
, XML_REPLACE
) )
366 mpHint
->SetTargetFrameName(
370 if ( mpHint
->GetHRef().isEmpty() )
372 // hyperlink without a URL is not imported.
378 m_rHints
.push_back(std::unique_ptr
<XMLHyperlinkHint_Impl
>(mpHint
));
382 XMLImpHyperlinkContext_Impl::~XMLImpHyperlinkContext_Impl()
385 mpHint
->SetEnd( GetImport().GetTextImport()
386 ->GetCursorAsRange()->getStart() );
389 css::uno::Reference
< css::xml::sax::XFastContextHandler
> XMLImpHyperlinkContext_Impl::createFastChildContext(
391 const uno::Reference
< xml::sax::XFastAttributeList
>& xAttrList
)
393 if ( nElement
== XML_ELEMENT(OFFICE
, XML_EVENT_LISTENERS
) )
395 XMLEventsImportContext
* pCtxt
= new XMLEventsImportContext(GetImport());
397 mpHint
->SetEventsContext(pCtxt
);
402 return XMLImpSpanContext_Impl::CreateSpanContext(
403 GetImport(), nElement
, xAttrList
,
404 m_rHints
, mrbIgnoreLeadingSpace
);
408 void XMLImpHyperlinkContext_Impl::characters( const OUString
& rChars
)
410 GetImport().GetTextImport()->InsertString( rChars
, mrbIgnoreLeadingSpace
);
415 class XMLImpRubyBaseContext_Impl
: public SvXMLImportContext
417 XMLHints_Impl
& m_rHints
;
419 bool& rIgnoreLeadingSpace
;
424 XMLImpRubyBaseContext_Impl(
425 SvXMLImport
& rImport
,
427 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
,
428 XMLHints_Impl
& rHints
,
429 bool& rIgnLeadSpace
);
431 virtual css::uno::Reference
< css::xml::sax::XFastContextHandler
> SAL_CALL
createFastChildContext(
432 sal_Int32 nElement
, const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& AttrList
) override
;
434 virtual void SAL_CALL
characters( const OUString
& rChars
) override
;
439 XMLImpRubyBaseContext_Impl::XMLImpRubyBaseContext_Impl(
440 SvXMLImport
& rImport
,
441 sal_Int32
/*nElement*/,
442 const Reference
< xml::sax::XFastAttributeList
> &,
443 XMLHints_Impl
& rHints
,
444 bool& rIgnLeadSpace
)
445 : SvXMLImportContext( rImport
)
447 , rIgnoreLeadingSpace( rIgnLeadSpace
)
451 css::uno::Reference
< css::xml::sax::XFastContextHandler
> XMLImpRubyBaseContext_Impl::createFastChildContext(
453 const uno::Reference
< xml::sax::XFastAttributeList
>& xAttrList
)
455 return XMLImpSpanContext_Impl::CreateSpanContext( GetImport(), nElement
, xAttrList
,
456 m_rHints
, rIgnoreLeadingSpace
);
459 void XMLImpRubyBaseContext_Impl::characters( const OUString
& rChars
)
461 GetImport().GetTextImport()->InsertString( rChars
, rIgnoreLeadingSpace
);
466 class XMLImpRubyContext_Impl
: public SvXMLImportContext
468 XMLHints_Impl
& m_rHints
;
470 bool& rIgnoreLeadingSpace
;
472 Reference
< XTextRange
> m_xStart
;
473 OUString m_sStyleName
;
474 OUString m_sTextStyleName
;
480 XMLImpRubyContext_Impl(
481 SvXMLImport
& rImport
,
483 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
,
484 XMLHints_Impl
& rHints
,
485 bool& rIgnLeadSpace
);
487 virtual void SAL_CALL
endFastElement(sal_Int32 nElement
) override
;
489 virtual css::uno::Reference
< css::xml::sax::XFastContextHandler
> SAL_CALL
createFastChildContext(
490 sal_Int32 nElement
, const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& AttrList
) override
;
492 void SetTextStyleName( const OUString
& s
) { m_sTextStyleName
= s
; }
493 void AppendText( std::u16string_view s
) { m_sText
+= s
; }
496 class XMLImpRubyTextContext_Impl
: public SvXMLImportContext
498 XMLImpRubyContext_Impl
& m_rRubyContext
;
503 XMLImpRubyTextContext_Impl(
504 SvXMLImport
& rImport
,
506 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
,
507 XMLImpRubyContext_Impl
& rParent
);
509 virtual void SAL_CALL
characters( const OUString
& rChars
) override
;
514 XMLImpRubyTextContext_Impl::XMLImpRubyTextContext_Impl(
515 SvXMLImport
& rImport
,
516 sal_Int32
/*nElement*/,
517 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
,
518 XMLImpRubyContext_Impl
& rParent
)
519 : SvXMLImportContext( rImport
)
520 , m_rRubyContext( rParent
)
522 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
524 if( aIter
.getToken() == XML_ELEMENT(TEXT
, XML_STYLE_NAME
) )
526 m_rRubyContext
.SetTextStyleName( aIter
.toString() );
532 void XMLImpRubyTextContext_Impl::characters( const OUString
& rChars
)
534 m_rRubyContext
.AppendText( rChars
);
538 XMLImpRubyContext_Impl::XMLImpRubyContext_Impl(
539 SvXMLImport
& rImport
,
540 sal_Int32
/*nElement*/,
541 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
,
542 XMLHints_Impl
& rHints
,
543 bool& rIgnLeadSpace
)
544 : SvXMLImportContext( rImport
)
546 , rIgnoreLeadingSpace( rIgnLeadSpace
)
547 , m_xStart( GetImport().GetTextImport()->GetCursorAsRange()->getStart() )
549 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
551 if( aIter
.getToken() == XML_ELEMENT(TEXT
, XML_STYLE_NAME
) )
553 m_sStyleName
= aIter
.toString();
559 void XMLImpRubyContext_Impl::endFastElement(sal_Int32
)
561 const rtl::Reference
< XMLTextImportHelper
> xTextImport(
562 GetImport().GetTextImport());
563 const Reference
< XTextCursor
> xAttrCursor(
564 xTextImport
->GetText()->createTextCursorByRange( m_xStart
));
565 if (!xAttrCursor
.is())
567 SAL_WARN("xmloff.text", "cannot insert ruby");
570 xAttrCursor
->gotoRange(xTextImport
->GetCursorAsRange()->getStart(),
572 xTextImport
->SetRuby( GetImport(), xAttrCursor
,
573 m_sStyleName
, m_sTextStyleName
, m_sText
);
576 css::uno::Reference
< css::xml::sax::XFastContextHandler
> XMLImpRubyContext_Impl::createFastChildContext(
578 const uno::Reference
< xml::sax::XFastAttributeList
>& xAttrList
)
580 if( nElement
== XML_ELEMENT(TEXT
, XML_RUBY_BASE
) )
581 return new XMLImpRubyBaseContext_Impl( GetImport(), nElement
,
584 rIgnoreLeadingSpace
);
585 else if( nElement
== XML_ELEMENT(TEXT
, XML_RUBY_TEXT
) )
586 return new XMLImpRubyTextContext_Impl( GetImport(), nElement
,
590 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement
);
597 /** for text:meta and text:meta-field
599 class XMLMetaImportContextBase
: public SvXMLImportContext
601 XMLHints_Impl
& m_rHints
;
603 bool& m_rIgnoreLeadingSpace
;
606 Reference
<XTextRange
> m_xStart
;
613 XMLMetaImportContextBase(
614 SvXMLImport
& i_rImport
,
615 const sal_Int32 nElement
,
616 XMLHints_Impl
& i_rHints
,
617 bool & i_rIgnoreLeadingSpace
);
619 virtual void SAL_CALL
startFastElement(
621 const Reference
<xml::sax::XFastAttributeList
> & i_xAttrList
) override
;
623 virtual void SAL_CALL
endFastElement(sal_Int32 nElement
) override
;
625 virtual css::uno::Reference
< css::xml::sax::XFastContextHandler
> SAL_CALL
createFastChildContext(
626 sal_Int32 nElement
, const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& AttrList
) override
;
628 virtual void SAL_CALL
characters( const OUString
& i_rChars
) override
;
630 virtual void ProcessAttribute(const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
);
632 virtual void InsertMeta(const Reference
<XTextRange
> & i_xInsertionRange
)
638 XMLMetaImportContextBase::XMLMetaImportContextBase(
639 SvXMLImport
& i_rImport
,
640 const sal_Int32
/*i_nElement*/,
641 XMLHints_Impl
& i_rHints
,
642 bool & i_rIgnoreLeadingSpace
)
643 : SvXMLImportContext( i_rImport
)
644 , m_rHints( i_rHints
)
645 , m_rIgnoreLeadingSpace( i_rIgnoreLeadingSpace
)
646 , m_xStart( GetImport().GetTextImport()->GetCursorAsRange()->getStart() )
650 void XMLMetaImportContextBase::startFastElement(
651 sal_Int32
/*nElement*/,
652 const Reference
<xml::sax::XFastAttributeList
> & xAttrList
)
654 for (auto &aIter
: sax_fastparser::castToFastAttributeList( xAttrList
))
655 ProcessAttribute(aIter
);
658 void XMLMetaImportContextBase::endFastElement(sal_Int32
)
660 SAL_WARN_IF(!m_xStart
.is(), "xmloff.text", "no mxStart?");
661 if (!m_xStart
.is()) return;
663 const Reference
<XTextRange
> xEndRange(
664 GetImport().GetTextImport()->GetCursorAsRange()->getStart() );
666 // create range for insertion
667 const Reference
<XTextCursor
> xInsertionCursor(
668 GetImport().GetTextImport()->GetText()->createTextCursorByRange(
670 xInsertionCursor
->gotoRange(m_xStart
, true);
672 InsertMeta(xInsertionCursor
);
675 css::uno::Reference
< css::xml::sax::XFastContextHandler
> XMLMetaImportContextBase::createFastChildContext(
677 const uno::Reference
< xml::sax::XFastAttributeList
>& xAttrList
)
679 return XMLImpSpanContext_Impl::CreateSpanContext( GetImport(), nElement
,
680 xAttrList
, m_rHints
, m_rIgnoreLeadingSpace
);
683 void XMLMetaImportContextBase::characters( const OUString
& i_rChars
)
685 GetImport().GetTextImport()->InsertString(i_rChars
, m_rIgnoreLeadingSpace
);
688 void XMLMetaImportContextBase::ProcessAttribute(const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
)
690 if ( aIter
.getToken() == XML_ELEMENT(XML
, XML_ID
) )
691 m_XmlId
= aIter
.toString();
693 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
699 class XMLMetaImportContext
: public XMLMetaImportContextBase
704 OUString m_sProperty
;
706 OUString m_sDatatype
;
710 XMLMetaImportContext(
711 SvXMLImport
& i_rImport
,
713 XMLHints_Impl
& i_rHints
,
714 bool & i_rIgnoreLeadingSpace
);
716 virtual void ProcessAttribute(const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
) override
;
718 virtual void InsertMeta(const Reference
<XTextRange
> & i_xInsertionRange
) override
;
723 XMLMetaImportContext::XMLMetaImportContext(
724 SvXMLImport
& i_rImport
,
726 XMLHints_Impl
& i_rHints
,
727 bool & i_rIgnoreLeadingSpace
)
728 : XMLMetaImportContextBase( i_rImport
, nElement
,
729 i_rHints
, i_rIgnoreLeadingSpace
)
730 , m_bHaveAbout(false)
734 void XMLMetaImportContext::ProcessAttribute(const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
)
736 switch (aIter
.getToken())
739 case XML_ELEMENT(XHTML
, XML_ABOUT
):
740 m_sAbout
= aIter
.toString();
743 case XML_ELEMENT(XHTML
, XML_PROPERTY
):
744 m_sProperty
= aIter
.toString();
746 case XML_ELEMENT(XHTML
, XML_CONTENT
):
747 m_sContent
= aIter
.toString();
749 case XML_ELEMENT(XHTML
, XML_DATATYPE
):
750 m_sDatatype
= aIter
.toString();
753 XMLMetaImportContextBase::ProcessAttribute(aIter
);
757 void XMLMetaImportContext::InsertMeta(
758 const Reference
<XTextRange
> & i_xInsertionRange
)
760 SAL_WARN_IF(m_bHaveAbout
== m_sProperty
.isEmpty(), "xmloff.text", "XMLMetaImportContext::InsertMeta: invalid RDFa?");
761 if (!m_XmlId
.isEmpty() || (m_bHaveAbout
&& !m_sProperty
.isEmpty()))
764 const uno::Reference
<rdf::XMetadatable
> xMeta(
765 XMLTextMarkImportContext::CreateAndInsertMark(
767 "com.sun.star.text.InContentMetadata",
769 i_xInsertionRange
, m_XmlId
),
771 SAL_WARN_IF(!xMeta
.is(), "xmloff.text", "cannot insert Meta?");
773 if (xMeta
.is() && m_bHaveAbout
)
775 GetImport().AddRDFa(xMeta
,
776 m_sAbout
, m_sProperty
, m_sContent
, m_sDatatype
);
781 SAL_INFO("xmloff.text", "invalid <text:meta>: no xml:id, no valid RDFa");
787 /** text:meta-field */
788 class XMLMetaFieldImportContext
: public XMLMetaImportContextBase
790 OUString m_DataStyleName
;
794 XMLMetaFieldImportContext(
795 SvXMLImport
& i_rImport
,
797 XMLHints_Impl
& i_rHints
,
798 bool & i_rIgnoreLeadingSpace
);
800 virtual void ProcessAttribute(const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
) override
;
802 virtual void InsertMeta(const Reference
<XTextRange
> & i_xInsertionRange
) override
;
807 XMLMetaFieldImportContext::XMLMetaFieldImportContext(
808 SvXMLImport
& i_rImport
,
810 XMLHints_Impl
& i_rHints
,
811 bool & i_rIgnoreLeadingSpace
)
812 : XMLMetaImportContextBase( i_rImport
, nElement
,
813 i_rHints
, i_rIgnoreLeadingSpace
)
817 void XMLMetaFieldImportContext::ProcessAttribute(const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
)
819 switch (aIter
.getToken())
821 case XML_ELEMENT(STYLE
, XML_DATA_STYLE_NAME
):
822 m_DataStyleName
= aIter
.toString();
825 XMLMetaImportContextBase::ProcessAttribute(aIter
);
829 void XMLMetaFieldImportContext::InsertMeta(
830 const Reference
<XTextRange
> & i_xInsertionRange
)
832 if (!m_XmlId
.isEmpty()) // valid?
835 const Reference
<XPropertySet
> xPropertySet(
836 XMLTextMarkImportContext::CreateAndInsertMark(
838 "com.sun.star.text.textfield.MetadataField",
840 i_xInsertionRange
, m_XmlId
),
842 SAL_WARN_IF(!xPropertySet
.is(), "xmloff.text", "cannot insert MetaField?");
843 if (!xPropertySet
.is()) return;
845 if (!m_DataStyleName
.isEmpty())
847 bool isDefaultLanguage(true);
849 const sal_Int32
nKey( GetImport().GetTextImport()->GetDataStyleKey(
850 m_DataStyleName
, & isDefaultLanguage
) );
854 OUString
sPropertyIsFixedLanguage("IsFixedLanguage");
855 xPropertySet
->setPropertyValue("NumberFormat", Any(nKey
));
856 if ( xPropertySet
->getPropertySetInfo()->
857 hasPropertyByName( sPropertyIsFixedLanguage
) )
859 xPropertySet
->setPropertyValue( sPropertyIsFixedLanguage
,
860 Any(!isDefaultLanguage
) );
867 SAL_INFO("xmloff.text", "invalid <text:meta-field>: no xml:id");
874 * Process index marks.
876 * All *-mark-end index marks should instantiate *this* class (because
877 * it doesn't process attributes other than ID), while the *-mark and
878 * *-mark-start classes should instantiate the appropriate subclasses.
880 class XMLIndexMarkImportContext_Impl
: public SvXMLImportContext
882 XMLHints_Impl
& m_rHints
;
887 XMLIndexMarkImportContext_Impl(
888 SvXMLImport
& rImport
,
889 XMLHints_Impl
& rHints
);
891 void SAL_CALL
startFastElement(sal_Int32 nElement
, const Reference
<xml::sax::XFastAttributeList
> & xAttrList
) override
;
895 /// process all attributes
896 void ProcessAttributes(sal_Int32 nElement
, const Reference
<xml::sax::XFastAttributeList
> & xAttrList
,
897 Reference
<beans::XPropertySet
>& rPropSet
);
900 * All marks can be created immediately. Since we don't care about
901 * the element content, ProcessAttribute should set the properties
904 * This method tolerates an empty PropertySet; subclasses however
905 * are not expected to.
907 virtual void ProcessAttribute(sal_Int32 nElement
,
908 const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
,
909 Reference
<beans::XPropertySet
>& rPropSet
);
911 static void GetServiceName(OUString
& sServiceName
,
914 bool CreateMark(Reference
<beans::XPropertySet
>& rPropSet
,
915 const OUString
& rServiceName
);
920 XMLIndexMarkImportContext_Impl::XMLIndexMarkImportContext_Impl(
921 SvXMLImport
& rImport
,
922 XMLHints_Impl
& rHints
)
923 : SvXMLImportContext(rImport
)
928 void XMLIndexMarkImportContext_Impl::startFastElement(
930 const Reference
<xml::sax::XFastAttributeList
> & xAttrList
)
932 // get Cursor position (needed for all cases)
933 Reference
<XTextRange
> xPos(
934 GetImport().GetTextImport()->GetCursor()->getStart());
935 Reference
<beans::XPropertySet
> xMark
;
939 case XML_ELEMENT(TEXT
, XML_TOC_MARK
):
940 case XML_ELEMENT(TEXT
, XML_USER_INDEX_MARK
):
941 case XML_ELEMENT(TEXT
, XML_ALPHABETICAL_INDEX_MARK
):
943 // single mark: create mark and insert
945 GetServiceName(sService
, nElement
);
946 if (CreateMark(xMark
, sService
))
948 ProcessAttributes(nElement
, xAttrList
, xMark
);
950 std::make_unique
<XMLIndexMarkHint_Impl
>(xMark
, xPos
));
952 // else: can't create mark -> ignore
956 case XML_ELEMENT(TEXT
, XML_TOC_MARK_START
):
957 case XML_ELEMENT(TEXT
, XML_USER_INDEX_MARK_START
):
958 case XML_ELEMENT(TEXT
, XML_ALPHABETICAL_INDEX_MARK_START
):
960 // start: create mark and insert (if ID is found)
962 GetServiceName(sService
, nElement
);
963 if (CreateMark(xMark
, sService
))
965 ProcessAttributes(nElement
, xAttrList
, xMark
);
968 // process only if we find an ID
970 std::make_unique
<XMLIndexMarkHint_Impl
>(xMark
, xPos
, sID
));
972 // else: no ID -> we'll never find the end -> ignore
974 // else: can't create mark -> ignore
978 case XML_ELEMENT(TEXT
, XML_TOC_MARK_END
):
979 case XML_ELEMENT(TEXT
, XML_USER_INDEX_MARK_END
):
980 case XML_ELEMENT(TEXT
, XML_ALPHABETICAL_INDEX_MARK_END
):
982 // end: search for ID and set end of mark
984 // call process attributes with empty XPropertySet:
985 ProcessAttributes(nElement
, xAttrList
, xMark
);
988 // if we have an ID, find the hint and set the end position
989 XMLIndexMarkHint_Impl
*const pHint
= m_rHints
.GetIndexHintById(sID
);
991 // set end and stop searching
994 // else: no ID -> ignore
999 SAL_WARN("xmloff.text", "unknown index mark type!");
1004 void XMLIndexMarkImportContext_Impl::ProcessAttributes(
1006 const Reference
<xml::sax::XFastAttributeList
> & xAttrList
,
1007 Reference
<beans::XPropertySet
>& rPropSet
)
1009 // process attributes
1010 for (auto &aIter
: sax_fastparser::castToFastAttributeList( xAttrList
))
1012 ProcessAttribute(nElement
, aIter
, rPropSet
);
1016 void XMLIndexMarkImportContext_Impl::ProcessAttribute(
1018 const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
,
1019 Reference
<beans::XPropertySet
>& rPropSet
)
1021 // we only know ID + string-value attribute;
1022 // (former: marks, latter: -start + -end-marks)
1023 // the remainder is handled in sub-classes
1026 case XML_ELEMENT(TEXT
, XML_TOC_MARK
):
1027 case XML_ELEMENT(TEXT
, XML_USER_INDEX_MARK
):
1028 case XML_ELEMENT(TEXT
, XML_ALPHABETICAL_INDEX_MARK
):
1029 if ( aIter
.getToken() == XML_ELEMENT(TEXT
, XML_STRING_VALUE
) )
1031 rPropSet
->setPropertyValue("AlternativeText", uno::makeAny(aIter
.toString()));
1036 case XML_ELEMENT(TEXT
, XML_TOC_MARK_START
):
1037 case XML_ELEMENT(TEXT
, XML_USER_INDEX_MARK_START
):
1038 case XML_ELEMENT(TEXT
, XML_ALPHABETICAL_INDEX_MARK_START
):
1039 case XML_ELEMENT(TEXT
, XML_TOC_MARK_END
):
1040 case XML_ELEMENT(TEXT
, XML_USER_INDEX_MARK_END
):
1041 case XML_ELEMENT(TEXT
, XML_ALPHABETICAL_INDEX_MARK_END
):
1042 if ( aIter
.getToken() == XML_ELEMENT(TEXT
, XML_ID
) )
1044 sID
= aIter
.toString();
1050 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
1056 void XMLIndexMarkImportContext_Impl::GetServiceName(
1057 OUString
& sServiceName
,
1062 case XML_ELEMENT(TEXT
, XML_TOC_MARK
):
1063 case XML_ELEMENT(TEXT
, XML_TOC_MARK_START
):
1064 case XML_ELEMENT(TEXT
, XML_TOC_MARK_END
):
1066 sServiceName
= "com.sun.star.text.ContentIndexMark";
1070 case XML_ELEMENT(TEXT
, XML_USER_INDEX_MARK
):
1071 case XML_ELEMENT(TEXT
, XML_USER_INDEX_MARK_START
):
1072 case XML_ELEMENT(TEXT
, XML_USER_INDEX_MARK_END
):
1074 sServiceName
= "com.sun.star.text.UserIndexMark";
1078 case XML_ELEMENT(TEXT
, XML_ALPHABETICAL_INDEX_MARK
):
1079 case XML_ELEMENT(TEXT
, XML_ALPHABETICAL_INDEX_MARK_START
):
1080 case XML_ELEMENT(TEXT
, XML_ALPHABETICAL_INDEX_MARK_END
):
1082 sServiceName
= "com.sun.star.text.DocumentIndexMark";
1088 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement
);
1089 sServiceName
.clear();
1095 bool XMLIndexMarkImportContext_Impl::CreateMark(
1096 Reference
<beans::XPropertySet
>& rPropSet
,
1097 const OUString
& rServiceName
)
1099 Reference
<lang::XMultiServiceFactory
>
1100 xFactory(GetImport().GetModel(), UNO_QUERY
);
1104 Reference
<beans::XPropertySet
> xPropSet( xFactory
->createInstance(rServiceName
), UNO_QUERY
);
1106 rPropSet
= xPropSet
;
1115 class XMLTOCMarkImportContext_Impl
: public XMLIndexMarkImportContext_Impl
1119 XMLTOCMarkImportContext_Impl(
1120 SvXMLImport
& rImport
,
1121 XMLHints_Impl
& rHints
);
1125 /** process outline level */
1126 virtual void ProcessAttribute(sal_Int32 nElement
,
1127 const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
,
1128 Reference
<beans::XPropertySet
>& rPropSet
) override
;
1133 XMLTOCMarkImportContext_Impl::XMLTOCMarkImportContext_Impl(
1134 SvXMLImport
& rImport
, XMLHints_Impl
& rHints
) :
1135 XMLIndexMarkImportContext_Impl(rImport
, rHints
)
1139 void XMLTOCMarkImportContext_Impl::ProcessAttribute(
1141 const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
,
1142 Reference
<beans::XPropertySet
>& rPropSet
)
1144 SAL_WARN_IF(!rPropSet
.is(), "xmloff.text", "need PropertySet");
1146 switch (aIter
.getToken())
1148 case XML_ELEMENT(TEXT
, XML_OUTLINE_LEVEL
):
1150 // ouline level: set Level property
1152 if (::sax::Converter::convertNumber( nTmp
, aIter
.toView() )
1154 && nTmp
< GetImport().GetTextImport()->
1155 GetChapterNumbering()->getCount() )
1157 rPropSet
->setPropertyValue("Level", uno::makeAny(static_cast<sal_Int16
>(nTmp
- 1)));
1159 // else: value out of range -> ignore
1163 // else: delegate to superclass
1164 XMLIndexMarkImportContext_Impl::ProcessAttribute(
1165 nElement
, aIter
, rPropSet
);
1171 class XMLUserIndexMarkImportContext_Impl
: public XMLIndexMarkImportContext_Impl
1175 XMLUserIndexMarkImportContext_Impl(
1176 SvXMLImport
& rImport
,
1177 XMLHints_Impl
& rHints
);
1181 /** process index name */
1182 virtual void ProcessAttribute(sal_Int32 nElement
,
1183 const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
,
1184 Reference
<beans::XPropertySet
>& rPropSet
) override
;
1189 XMLUserIndexMarkImportContext_Impl::XMLUserIndexMarkImportContext_Impl(
1190 SvXMLImport
& rImport
, XMLHints_Impl
& rHints
) :
1191 XMLIndexMarkImportContext_Impl(rImport
, rHints
)
1195 void XMLUserIndexMarkImportContext_Impl::ProcessAttribute(
1197 const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
,
1198 Reference
<beans::XPropertySet
>& rPropSet
)
1200 switch (aIter
.getToken())
1202 case XML_ELEMENT(TEXT
, XML_INDEX_NAME
):
1203 rPropSet
->setPropertyValue("UserIndexName", uno::makeAny(aIter
.toString()));
1205 case XML_ELEMENT(TEXT
, XML_OUTLINE_LEVEL
):
1207 // ouline level: set Level property
1209 if (::sax::Converter::convertNumber(
1210 nTmp
, aIter
.toView(), 0,
1211 GetImport().GetTextImport()->GetChapterNumbering()->getCount()))
1213 rPropSet
->setPropertyValue("Level", uno::makeAny(static_cast<sal_Int16
>(nTmp
- 1)));
1215 // else: value out of range -> ignore
1219 // else: unknown text property: delegate to super class
1220 XMLIndexMarkImportContext_Impl::ProcessAttribute(
1221 nElement
, aIter
, rPropSet
);
1227 class XMLAlphaIndexMarkImportContext_Impl
: public XMLIndexMarkImportContext_Impl
1231 XMLAlphaIndexMarkImportContext_Impl(
1232 SvXMLImport
& rImport
,
1233 XMLHints_Impl
& rHints
);
1237 /** process primary + secondary keys */
1238 virtual void ProcessAttribute(sal_Int32 nElement
,
1239 const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
,
1240 Reference
<beans::XPropertySet
>& rPropSet
) override
;
1245 XMLAlphaIndexMarkImportContext_Impl::XMLAlphaIndexMarkImportContext_Impl(
1246 SvXMLImport
& rImport
, XMLHints_Impl
& rHints
) :
1247 XMLIndexMarkImportContext_Impl(rImport
, rHints
)
1251 void XMLAlphaIndexMarkImportContext_Impl::ProcessAttribute(
1253 const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
,
1254 Reference
<beans::XPropertySet
>& rPropSet
)
1256 switch (aIter
.getToken())
1258 case XML_ELEMENT(TEXT
, XML_KEY1
):
1259 rPropSet
->setPropertyValue("PrimaryKey", uno::makeAny(aIter
.toString()));
1261 case XML_ELEMENT(TEXT
, XML_KEY2
):
1262 rPropSet
->setPropertyValue("SecondaryKey", uno::makeAny(aIter
.toString()));
1264 case XML_ELEMENT(TEXT
, XML_KEY1_PHONETIC
):
1265 rPropSet
->setPropertyValue("PrimaryKeyReading", uno::makeAny(aIter
.toString()));
1267 case XML_ELEMENT(TEXT
, XML_KEY2_PHONETIC
):
1268 rPropSet
->setPropertyValue("SecondaryKeyReading", uno::makeAny(aIter
.toString()));
1270 case XML_ELEMENT(TEXT
, XML_STRING_VALUE_PHONETIC
):
1271 rPropSet
->setPropertyValue("TextReading", uno::makeAny(aIter
.toString()));
1273 case XML_ELEMENT(TEXT
, XML_MAIN_ENTRY
):
1275 bool bMainEntry
= false;
1278 if (::sax::Converter::convertBool(bTmp
, aIter
.toView()))
1281 rPropSet
->setPropertyValue("IsMainEntry", uno::makeAny(bMainEntry
));
1285 XMLIndexMarkImportContext_Impl::ProcessAttribute(
1286 nElement
, aIter
, rPropSet
);
1291 XMLImpSpanContext_Impl::XMLImpSpanContext_Impl(
1292 SvXMLImport
& rImport
,
1293 sal_Int32
/*nElement*/,
1294 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
,
1295 XMLHints_Impl
& rHints
,
1296 bool& rIgnLeadSpace
,
1297 sal_uInt8 nSFConvFlags
)
1298 : SvXMLImportContext( rImport
)
1299 , m_rHints( rHints
)
1301 , rIgnoreLeadingSpace( rIgnLeadSpace
)
1302 , nStarFontsConvFlags( nSFConvFlags
& (CONV_FROM_STAR_BATS
|CONV_FROM_STAR_MATH
) )
1304 OUString aStyleName
;
1306 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
1308 if( aIter
.getToken() == XML_ELEMENT(TEXT
, XML_STYLE_NAME
) )
1310 aStyleName
= aIter
.toString();
1315 if( !aStyleName
.isEmpty() )
1317 pHint
= new XMLStyleHint_Impl( aStyleName
,
1318 GetImport().GetTextImport()->GetCursorAsRange()->getStart() );
1319 m_rHints
.push_back(std::unique_ptr
<XMLStyleHint_Impl
>(pHint
));
1323 void XMLImpSpanContext_Impl::endFastElement(sal_Int32
)
1328 Reference
<XTextRange
> xCrsrRange(GetImport().GetTextImport()->GetCursorAsRange());
1329 if (!xCrsrRange
.is())
1330 return; // Robust (defective file)
1332 pHint
->SetEnd(xCrsrRange
->getStart());
1335 css::uno::Reference
< css::xml::sax::XFastContextHandler
> XMLImpSpanContext_Impl::CreateSpanContext(
1336 SvXMLImport
& rImport
,
1338 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
,
1339 XMLHints_Impl
& rHints
,
1340 bool& rIgnoreLeadingSpace
,
1341 sal_uInt8 nStarFontsConvFlags
1344 SvXMLImportContext
*pContext
= nullptr;
1348 case XML_ELEMENT(TEXT
, XML_SPAN
):
1349 pContext
= new XMLImpSpanContext_Impl( rImport
, nElement
,
1353 ,nStarFontsConvFlags
1357 case XML_ELEMENT(TEXT
, XML_TAB
):
1358 pContext
= new XMLCharContext( rImport
, xAttrList
,
1360 rIgnoreLeadingSpace
= false;
1363 case XML_ELEMENT(TEXT
, XML_LINE_BREAK
):
1364 if (xAttrList
->hasAttribute(XML_ELEMENT(LO_EXT
, XML_CLEAR
)))
1366 pContext
= new SvXMLLineBreakContext(rImport
, *rImport
.GetTextImport());
1370 pContext
= new XMLCharContext(rImport
, ControlCharacter::LINE_BREAK
);
1372 rIgnoreLeadingSpace
= false;
1375 case XML_ELEMENT(TEXT
, XML_S
):
1376 pContext
= new XMLCharContext( rImport
, xAttrList
, 0x0020, true );
1377 rIgnoreLeadingSpace
= false;
1380 case XML_ELEMENT(TEXT
, XML_A
):
1382 // test for HyperLinkURL property. If present, insert link as
1383 // text property (StarWriter), else try to insert as text
1384 // field (StarCalc, StarDraw, ...)
1385 Reference
< beans::XPropertySet
> xPropSet( rImport
.GetTextImport()->GetCursor(), UNO_QUERY
);
1387 if ( xPropSet
->getPropertySetInfo()->hasPropertyByName( "HyperLinkURL" ) )
1389 pContext
= new XMLImpHyperlinkContext_Impl(
1394 rIgnoreLeadingSpace
);
1398 pContext
= new XMLUrlFieldImportContext(rImport
, *rImport
.GetTextImport());
1399 //whitespace handling like other fields
1400 rIgnoreLeadingSpace
= false;
1406 case XML_ELEMENT(TEXT
, XML_RUBY
):
1407 pContext
= new XMLImpRubyContext_Impl( rImport
, nElement
,
1410 rIgnoreLeadingSpace
);
1413 case XML_ELEMENT(TEXT
, XML_NOTE
):
1414 if (rImport
.GetTextImport()->IsInFrame())
1416 // we must not insert footnotes into text frames
1417 pContext
= new SvXMLImportContext( rImport
);
1421 pContext
= new XMLFootnoteImportContext(rImport
, *rImport
.GetTextImport());
1423 rIgnoreLeadingSpace
= false;
1426 case XML_ELEMENT(TEXT
, XML_REFERENCE_MARK
):
1427 case XML_ELEMENT(TEXT
, XML_BOOKMARK
):
1428 case XML_ELEMENT(TEXT
, XML_BOOKMARK_START
):
1429 case XML_ELEMENT(TEXT
, XML_BOOKMARK_END
):
1430 pContext
= new XMLTextMarkImportContext(rImport
, *rImport
.GetTextImport(),
1431 rHints
.GetCrossRefHeadingBookmark());
1434 case XML_ELEMENT(FIELD
, XML_FIELDMARK
):
1435 case XML_ELEMENT(FIELD
, XML_FIELDMARK_START
):
1436 case XML_ELEMENT(FIELD
, XML_FIELDMARK_END
):
1437 pContext
= new XMLTextMarkImportContext(rImport
, *rImport
.GetTextImport(),
1438 rHints
.GetCrossRefHeadingBookmark());
1441 case XML_ELEMENT(TEXT
, XML_REFERENCE_MARK_START
):
1442 pContext
= new XMLStartReferenceContext_Impl( rImport
,
1443 rHints
, xAttrList
);
1446 case XML_ELEMENT(TEXT
, XML_REFERENCE_MARK_END
):
1447 pContext
= new XMLEndReferenceContext_Impl( rImport
,
1448 rHints
, xAttrList
);
1451 case XML_ELEMENT(DRAW
, XML_FRAME
):
1453 Reference
< XTextRange
> xAnchorPos
=
1454 rImport
.GetTextImport()->GetCursor()->getStart();
1455 XMLTextFrameContext
*pTextFrameContext
=
1456 new XMLTextFrameContext(rImport
,
1458 TextContentAnchorType_AS_CHARACTER
);
1459 // Remove check for text content. (#i33242#)
1460 // Check for text content is done on the processing of the hint
1461 if( TextContentAnchorType_AT_CHARACTER
==
1462 pTextFrameContext
->GetAnchorType() )
1464 rHints
.push_back(std::make_unique
<XMLTextFrameHint_Impl
>(
1465 pTextFrameContext
, xAnchorPos
));
1467 pContext
= pTextFrameContext
;
1468 rIgnoreLeadingSpace
= false;
1471 case XML_ELEMENT(DRAW
, XML_A
):
1473 Reference
< XTextRange
> xAnchorPos(rImport
.GetTextImport()->GetCursor()->getStart());
1475 new XMLTextFrameHyperlinkContext( rImport
, nElement
,
1477 TextContentAnchorType_AS_CHARACTER
);
1479 std::make_unique
<XMLTextFrameHint_Impl
>(pContext
, xAnchorPos
));
1483 case XML_ELEMENT(TEXT
, XML_TOC_MARK
):
1484 case XML_ELEMENT(TEXT
, XML_TOC_MARK_START
):
1485 pContext
= new XMLTOCMarkImportContext_Impl(
1489 case XML_ELEMENT(TEXT
, XML_USER_INDEX_MARK
):
1490 case XML_ELEMENT(TEXT
, XML_USER_INDEX_MARK_START
):
1491 pContext
= new XMLUserIndexMarkImportContext_Impl(
1495 case XML_ELEMENT(TEXT
, XML_ALPHABETICAL_INDEX_MARK
):
1496 case XML_ELEMENT(TEXT
, XML_ALPHABETICAL_INDEX_MARK_START
):
1497 pContext
= new XMLAlphaIndexMarkImportContext_Impl(
1501 case XML_ELEMENT(TEXT
, XML_TOC_MARK_END
):
1502 case XML_ELEMENT(TEXT
, XML_USER_INDEX_MARK_END
):
1503 case XML_ELEMENT(TEXT
, XML_ALPHABETICAL_INDEX_MARK_END
):
1504 pContext
= new XMLIndexMarkImportContext_Impl(
1508 case XML_ELEMENT(TEXT
, XML_CHANGE_START
):
1509 case XML_ELEMENT(TEXT
, XML_CHANGE_END
):
1510 case XML_ELEMENT(TEXT
, XML_CHANGE
):
1511 pContext
= new XMLChangeImportContext(
1513 ((nElement
== XML_ELEMENT(TEXT
, XML_CHANGE_END
))
1514 ? XMLChangeImportContext::Element::END
1515 : (nElement
== XML_ELEMENT(TEXT
, XML_CHANGE_START
))
1516 ? XMLChangeImportContext::Element::START
1517 : XMLChangeImportContext::Element::POINT
),
1521 case XML_ELEMENT(TEXT
, XML_META
):
1522 pContext
= new XMLMetaImportContext(rImport
, nElement
,
1523 rHints
, rIgnoreLeadingSpace
);
1526 case XML_ELEMENT(TEXT
, XML_META_FIELD
):
1527 pContext
= new XMLMetaFieldImportContext(rImport
, nElement
,
1528 rHints
, rIgnoreLeadingSpace
);
1531 case XML_ELEMENT(LO_EXT
, XML_CONTENT_CONTROL
):
1532 pContext
= new XMLContentControlContext(rImport
, nElement
, rHints
, rIgnoreLeadingSpace
);
1536 // none of the above? then it's probably a text field!
1537 pContext
= XMLTextFieldImportContext::CreateTextFieldImportContext(
1538 rImport
, *rImport
.GetTextImport(), nElement
);
1539 // #108784# import draw elements (except control shapes in headers)
1540 if( pContext
== nullptr &&
1541 !( rImport
.GetTextImport()->IsInHeaderFooter() &&
1542 nElement
== XML_ELEMENT(DRAW
, XML_CONTROL
) ) )
1544 Reference
< XShapes
> xShapes
;
1545 SvXMLShapeContext
* pShapeContext
= XMLShapeImportHelper::CreateGroupChildContext(
1546 rImport
, nElement
, xAttrList
, xShapes
);
1547 pContext
= pShapeContext
;
1548 // OD 2004-04-20 #i26791# - keep shape in a text frame hint to
1549 // adjust its anchor position, if its at-character anchored
1550 Reference
< XTextRange
> xAnchorPos
=
1551 rImport
.GetTextImport()->GetCursor()->getStart();
1553 std::make_unique
<XMLDrawHint_Impl
>(pShapeContext
, xAnchorPos
));
1555 // Behind fields, shapes and any unknown content blanks aren't ignored
1556 rIgnoreLeadingSpace
= false;
1560 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement
);
1564 css::uno::Reference
< css::xml::sax::XFastContextHandler
> XMLImpSpanContext_Impl::createFastChildContext(
1566 const uno::Reference
< xml::sax::XFastAttributeList
>& xAttrList
)
1568 return CreateSpanContext( GetImport(), nElement
, xAttrList
,
1569 m_rHints
, rIgnoreLeadingSpace
1570 ,nStarFontsConvFlags
1574 void XMLImpSpanContext_Impl::characters( const OUString
& rChars
)
1576 OUString sStyleName
;
1578 sStyleName
= pHint
->GetStyleName();
1580 GetImport().GetTextImport()->ConvertStarFonts( rChars
, sStyleName
,
1581 nStarFontsConvFlags
,
1582 false, GetImport() );
1583 GetImport().GetTextImport()->InsertString( sChars
, rIgnoreLeadingSpace
);
1587 XMLParaContext::XMLParaContext(
1588 SvXMLImport
& rImport
,
1590 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
) :
1591 SvXMLImportContext( rImport
),
1592 xStart( rImport
.GetTextImport()->GetCursorAsRange()->getStart() ),
1593 m_bHaveAbout(false),
1594 nOutlineLevel( (nElement
& TOKEN_MASK
) == XML_H
? 1 : -1 ),
1595 // Lost outline numbering in master document (#i73509#)
1596 mbOutlineLevelAttrFound( false ),
1597 mbOutlineContentVisible(true),
1598 bIgnoreLeadingSpace( true ),
1599 bHeading( (nElement
& TOKEN_MASK
) == XML_H
),
1600 bIsListHeader( false ),
1603 nStarFontsConvFlags( 0 )
1605 bool bHaveXmlId( false );
1606 OUString aCondStyleName
;
1608 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
1610 switch( aIter
.getToken() )
1612 case XML_ELEMENT(XML
, XML_ID
):
1613 m_sXmlId
= aIter
.toString();
1616 case XML_ELEMENT(XHTML
, XML_ABOUT
):
1617 m_sAbout
= aIter
.toString();
1618 m_bHaveAbout
= true;
1620 case XML_ELEMENT(XHTML
, XML_PROPERTY
):
1621 m_sProperty
= aIter
.toString();
1623 case XML_ELEMENT(XHTML
, XML_CONTENT
):
1624 m_sContent
= aIter
.toString();
1626 case XML_ELEMENT(XHTML
, XML_DATATYPE
):
1627 m_sDatatype
= aIter
.toString();
1629 case XML_ELEMENT(TEXT
, XML_ID
):
1630 if (!bHaveXmlId
) { m_sXmlId
= aIter
.toString(); }
1632 case XML_ELEMENT(TEXT
, XML_STYLE_NAME
):
1633 sStyleName
= aIter
.toString();
1635 case XML_ELEMENT(TEXT
, XML_COND_STYLE_NAME
):
1636 aCondStyleName
= aIter
.toString();
1638 case XML_ELEMENT(TEXT
, XML_OUTLINE_LEVEL
):
1640 sal_Int32 nTmp
= aIter
.toInt32();
1645 nOutlineLevel
= static_cast<sal_Int8
>(nTmp
);
1647 // Lost outline numbering in master document (#i73509#)
1648 mbOutlineLevelAttrFound
= true;
1651 case XML_ELEMENT(LO_EXT
, XML_OUTLINE_CONTENT_VISIBLE
):
1654 if (::sax::Converter::convertBool(bBool
, aIter
.toView()))
1655 mbOutlineContentVisible
= bBool
;
1658 case XML_ELEMENT(TEXT
, XML_IS_LIST_HEADER
):
1661 if (::sax::Converter::convertBool(bBool
, aIter
.toView()))
1662 bIsListHeader
= bBool
;
1665 case XML_ELEMENT(TEXT
, XML_RESTART_NUMBERING
):
1668 if (::sax::Converter::convertBool(bBool
, aIter
.toView()))
1672 case XML_ELEMENT(TEXT
, XML_START_VALUE
):
1674 nStartValue
= sal::static_int_cast
< sal_Int16
>(aIter
.toInt32());
1678 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
1682 if( !aCondStyleName
.isEmpty() )
1683 sStyleName
= aCondStyleName
;
1686 void XMLParaContext::endFastElement(sal_Int32
)
1688 rtl::Reference
< XMLTextImportHelper
> xTxtImport(
1689 GetImport().GetTextImport());
1690 Reference
< XTextRange
> xCrsrRange( xTxtImport
->GetCursorAsRange() );
1691 if( !xCrsrRange
.is() )
1692 return; // Robust (defective file)
1693 Reference
< XTextRange
> xEnd(xCrsrRange
->getStart());
1695 // if we have an id set for this paragraph, get a cursor for this
1696 // paragraph and register it with the given identifier
1697 // FIXME: this is just temporary, and should be removed when
1698 // EditEngine paragraphs implement XMetadatable!
1699 if (!m_sXmlId
.isEmpty())
1701 Reference
< XTextCursor
> xIdCursor( xTxtImport
->GetText()->createTextCursorByRange( xStart
) );
1702 if( xIdCursor
.is() )
1704 xIdCursor
->gotoRange( xEnd
, true );
1705 GetImport().getInterfaceToIdentifierMapper().registerReference(
1706 m_sXmlId
, Reference
<XInterface
>( xIdCursor
, UNO_QUERY
));
1710 // insert a paragraph break
1711 xTxtImport
->InsertControlCharacter( ControlCharacter::APPEND_PARAGRAPH
);
1713 // create a cursor that select the whole last paragraph
1714 Reference
< XTextCursor
> xAttrCursor
;
1716 xAttrCursor
= xTxtImport
->GetText()->createTextCursorByRange( xStart
);
1717 if( !xAttrCursor
.is() )
1718 return; // Robust (defective file)
1719 } catch (const uno::Exception
&) {
1720 // createTextCursorByRange() likes to throw runtime exception, even
1721 // though it just means 'we were unable to create the cursor'
1724 xAttrCursor
->gotoRange( xEnd
, true );
1726 // xml:id for RDF metadata
1727 if (!m_sXmlId
.isEmpty() || m_bHaveAbout
|| !m_sProperty
.isEmpty())
1730 const uno::Reference
<container::XEnumerationAccess
> xEA
1731 (xAttrCursor
, uno::UNO_QUERY_THROW
);
1732 const uno::Reference
<container::XEnumeration
> xEnum(
1733 xEA
->createEnumeration(), uno::UNO_SET_THROW
);
1734 SAL_WARN_IF(!xEnum
->hasMoreElements(), "xmloff.text", "xml:id: no paragraph?");
1735 if (xEnum
->hasMoreElements()) {
1736 uno::Reference
<rdf::XMetadatable
> xMeta
;
1737 xEnum
->nextElement() >>= xMeta
;
1738 SAL_WARN_IF(!xMeta
.is(), "xmloff.text", "xml:id: not XMetadatable");
1739 GetImport().SetXmlId(xMeta
, m_sXmlId
);
1742 GetImport().AddRDFa(xMeta
,
1743 m_sAbout
, m_sProperty
, m_sContent
, m_sDatatype
);
1745 SAL_WARN_IF(xEnum
->hasMoreElements(), "xmloff.text", "xml:id: > 1 paragraph?");
1747 } catch (const uno::Exception
&) {
1748 SAL_INFO("xmloff.text", "XMLParaContext::~XMLParaContext: exception");
1752 OUString
const sCellParaStyleName(xTxtImport
->GetCellParaStyleDefault());
1753 if( !sCellParaStyleName
.isEmpty() )
1755 /* Suppress handling of outline and list attributes,
1756 because of side effects of method <SetStyleAndAttrs(..)> (#i80724#)
1758 xTxtImport
->SetStyleAndAttrs( GetImport(), xAttrCursor
,
1761 false, -1, // suppress outline handling
1762 false ); // suppress list attributes handling
1765 // #103445# for headings without style name, find the proper style
1766 if( bHeading
&& sStyleName
.isEmpty() )
1767 xTxtImport
->FindOutlineStyleName( sStyleName
, nOutlineLevel
);
1769 // set style and hard attributes at the previous paragraph
1770 // Add parameter <mbOutlineLevelAttrFound> (#i73509#)
1771 sStyleName
= xTxtImport
->SetStyleAndAttrs( GetImport(), xAttrCursor
,
1774 mbOutlineLevelAttrFound
,
1775 bHeading
? nOutlineLevel
: -1,
1777 mbOutlineContentVisible
);
1779 // handle list style header
1780 if (bHeading
&& (bIsListHeader
|| bIsRestart
))
1782 Reference
<XPropertySet
> xPropSet( xAttrCursor
, UNO_QUERY
);
1788 OUString sNumberingIsNumber
1789 ("NumberingIsNumber");
1790 if(xPropSet
->getPropertySetInfo()->
1791 hasPropertyByName(sNumberingIsNumber
))
1793 xPropSet
->setPropertyValue
1794 (sNumberingIsNumber
, makeAny( false ) );
1799 OUString sParaIsNumberingRestart
1800 ("ParaIsNumberingRestart");
1801 OUString sNumberingStartValue
1802 ("NumberingStartValue");
1803 if (xPropSet
->getPropertySetInfo()->
1804 hasPropertyByName(sParaIsNumberingRestart
))
1806 xPropSet
->setPropertyValue
1807 (sParaIsNumberingRestart
, makeAny(true));
1810 if (xPropSet
->getPropertySetInfo()->
1811 hasPropertyByName(sNumberingStartValue
))
1813 xPropSet
->setPropertyValue
1814 (sNumberingStartValue
, makeAny(nStartValue
));
1823 for (const auto & i
: m_xHints
->GetHints())
1825 XMLHint_Impl
*const pHint
= i
.get();
1826 xAttrCursor
->gotoRange( pHint
->GetStart(), false );
1827 xAttrCursor
->gotoRange( pHint
->GetEnd(), true );
1828 switch( pHint
->GetType() )
1830 case XML_HINT_STYLE
:
1832 const OUString
& rStyleName
=
1833 static_cast<XMLStyleHint_Impl
*>(pHint
)->GetStyleName();
1834 if( !rStyleName
.isEmpty() )
1835 xTxtImport
->SetStyleAndAttrs( GetImport(),
1836 xAttrCursor
, rStyleName
,
1840 case XML_HINT_REFERENCE
:
1842 const OUString
& rRefName
=
1843 static_cast<XMLReferenceHint_Impl
*>(pHint
)->GetRefName();
1844 if( !rRefName
.isEmpty() )
1846 if( !pHint
->GetEnd().is() )
1847 pHint
->SetEnd(xEnd
);
1849 // reference name uses rStyleName member
1850 // borrow from XMLTextMarkImportContext
1851 XMLTextMarkImportContext::CreateAndInsertMark(
1853 "com.sun.star.text.ReferenceMark",
1859 case XML_HINT_HYPERLINK
:
1861 const XMLHyperlinkHint_Impl
*pHHint
=
1862 static_cast<const XMLHyperlinkHint_Impl
*>(pHint
);
1863 xTxtImport
->SetHyperlink( GetImport(),
1867 pHHint
->GetTargetFrameName(),
1868 pHHint
->GetStyleName(),
1869 pHHint
->GetVisitedStyleName(),
1870 pHHint
->GetEventsContext() );
1873 case XML_HINT_INDEX_MARK
:
1875 Reference
<beans::XPropertySet
> xMark(
1876 static_cast<const XMLIndexMarkHint_Impl
*>(pHint
)->GetMark());
1877 Reference
<XTextContent
> xContent(xMark
, UNO_QUERY
);
1880 xTxtImport
->GetText()->insertTextContent(
1881 xAttrCursor
, xContent
, true );
1883 catch (uno::RuntimeException
const&)
1885 TOOLS_INFO_EXCEPTION("xmloff.text", "could not insert index mark, presumably in editengine text");
1889 case XML_HINT_TEXT_FRAME
:
1891 const XMLTextFrameHint_Impl
*pFHint
=
1892 static_cast<const XMLTextFrameHint_Impl
*>(pHint
);
1893 // Check for text content (#i33242#)
1894 Reference
< XTextContent
> xTextContent
=
1895 pFHint
->GetTextContent();
1896 if ( xTextContent
.is() )
1898 /* Core impl. of the unification of drawing objects and
1899 Writer fly frames (#i26791#)
1901 if ( pFHint
->IsBoundAtChar() )
1903 xTextContent
->attach( xAttrCursor
);
1906 /* Consider, that hint can also contain a shape -
1907 e.g. drawing object of type 'Text'. (#i33242#)
1911 Reference
< XShape
> xShape
= pFHint
->GetShape();
1914 // determine anchor type
1915 Reference
< XPropertySet
> xPropSet( xShape
, UNO_QUERY
);
1916 TextContentAnchorType eAnchorType
=
1917 TextContentAnchorType_AT_PARAGRAPH
;
1919 Any aAny
= xPropSet
->getPropertyValue( "AnchorType" );
1920 aAny
>>= eAnchorType
;
1922 if ( TextContentAnchorType_AT_CHARACTER
== eAnchorType
)
1924 // set anchor position for at-character anchored objects
1925 xPropSet
->setPropertyValue("TextRange", Any(xAttrCursor
));
1931 /* Core impl. of the unification of drawing objects and
1932 Writer fly frames (#i26791#)
1936 const XMLDrawHint_Impl
*pDHint
=
1937 static_cast<const XMLDrawHint_Impl
*>(pHint
);
1938 // Improvement: hint directly provides the shape. (#i33242#)
1939 const Reference
< XShape
>& xShape
= pDHint
->GetShape();
1942 // determine anchor type
1943 Reference
< XPropertySet
> xPropSet( xShape
, UNO_QUERY
);
1944 TextContentAnchorType eAnchorType
= TextContentAnchorType_AT_PARAGRAPH
;
1946 Any aAny
= xPropSet
->getPropertyValue( "AnchorType" );
1947 aAny
>>= eAnchorType
;
1949 if ( TextContentAnchorType_AT_CHARACTER
== eAnchorType
)
1951 // set anchor position for at-character anchored objects
1952 xPropSet
->setPropertyValue("TextRange", Any(xAttrCursor
));
1958 SAL_WARN( "xmloff.text", "What's this" );
1966 css::uno::Reference
< css::xml::sax::XFastContextHandler
> XMLParaContext::createFastChildContext(
1968 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
1971 m_xHints
.reset(new XMLHints_Impl
);
1972 return XMLImpSpanContext_Impl::CreateSpanContext(
1973 GetImport(), nElement
, xAttrList
,
1974 *m_xHints
, bIgnoreLeadingSpace
,
1975 nStarFontsConvFlags
);
1978 void XMLParaContext::characters( const OUString
& rChars
)
1981 GetImport().GetTextImport()->ConvertStarFonts( rChars
, sStyleName
,
1982 nStarFontsConvFlags
,
1983 true, GetImport() );
1984 GetImport().GetTextImport()->InsertString( sChars
, bIgnoreLeadingSpace
);
1988 XMLNumberedParaContext::XMLNumberedParaContext(
1989 SvXMLImport
& i_rImport
,
1990 sal_Int32
/*nElement*/,
1991 const Reference
< xml::sax::XFastAttributeList
> & xAttrList
) :
1992 SvXMLImportContext( i_rImport
),
1998 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
2000 switch( aIter
.getToken() )
2002 case XML_ELEMENT(XML
, XML_ID
):
2003 //FIXME: there is no UNO API for lists
2005 case XML_ELEMENT(TEXT
, XML_LIST_ID
):
2006 m_ListId
= aIter
.toString();
2008 case XML_ELEMENT(TEXT
, XML_LEVEL
):
2010 sal_Int32 nTmp
= aIter
.toInt32();
2011 if ( nTmp
>= 1 && nTmp
<= SHRT_MAX
) {
2012 m_Level
= static_cast<sal_uInt16
>(nTmp
) - 1;
2016 case XML_ELEMENT(TEXT
, XML_STYLE_NAME
):
2017 StyleName
= aIter
.toString();
2019 case XML_ELEMENT(TEXT
, XML_CONTINUE_NUMBERING
):
2020 // this attribute is deprecated
2021 // ContinueNumbering = IsXMLToken(sValue, XML_TRUE);
2023 case XML_ELEMENT(TEXT
, XML_START_VALUE
):
2025 sal_Int32 nTmp
= aIter
.toInt32();
2026 if ( nTmp
>= 0 && nTmp
<= SHRT_MAX
) {
2027 m_StartValue
= static_cast<sal_Int16
>(nTmp
);
2032 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
2036 XMLTextListsHelper
& rTextListsHelper(
2037 i_rImport
.GetTextImport()->GetTextListHelper() );
2038 if (m_ListId
.isEmpty())
2040 SAL_WARN_IF(0 <= i_rImport
.GetODFVersion().compareTo(u
"1.2"), "xmloff.text", "invalid numbered-paragraph: no list-id (1.2)");
2041 m_ListId
= rTextListsHelper
.GetNumberedParagraphListId(m_Level
,
2043 SAL_WARN_IF(m_ListId
.isEmpty(), "xmloff.text", "numbered-paragraph: no ListId");
2044 if (m_ListId
.isEmpty()) {
2048 m_xNumRules
= rTextListsHelper
.EnsureNumberedParagraph( i_rImport
,
2049 m_ListId
, m_Level
, StyleName
);
2051 SAL_WARN_IF(!m_xNumRules
.is(), "xmloff.text", "numbered-paragraph: no NumRules");
2053 i_rImport
.GetTextImport()->GetTextListHelper().PushListContext( this );
2056 void XMLNumberedParaContext::endFastElement(sal_Int32
)
2058 if (!m_ListId
.isEmpty()) {
2059 GetImport().GetTextImport()->PopListContext();
2063 css::uno::Reference
< css::xml::sax::XFastContextHandler
> XMLNumberedParaContext::createFastChildContext(
2064 sal_Int32 nElement
, const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
2068 case XML_ELEMENT(TEXT
, XML_H
):
2069 case XML_ELEMENT(LO_EXT
, XML_H
):
2070 case XML_ELEMENT(TEXT
, XML_P
):
2071 case XML_ELEMENT(LO_EXT
, XML_P
):
2072 return new XMLParaContext( GetImport(), nElement
, xAttrList
);
2074 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement
);
2080 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */